46 lines
1.1 KiB
Plaintext
46 lines
1.1 KiB
Plaintext
|
|
FUNCTION_BLOCK FB_MovingAverage
|
||
|
|
VAR_INPUT
|
||
|
|
xEnable : BOOL;
|
||
|
|
rInput : REAL; // Raw analog value
|
||
|
|
iWindowSize : INT := 10; // Number of samples (1..100)
|
||
|
|
END_VAR
|
||
|
|
VAR_OUTPUT
|
||
|
|
rOutput : REAL; // Filtered output
|
||
|
|
xReady : BOOL; // TRUE when buffer is full
|
||
|
|
END_VAR
|
||
|
|
VAR
|
||
|
|
arBuffer : ARRAY[0..99] OF REAL; // Circular buffer
|
||
|
|
iIndex : INT := 0;
|
||
|
|
iCount : INT := 0;
|
||
|
|
rSum : REAL := 0.0;
|
||
|
|
iWin : INT;
|
||
|
|
END_VAR
|
||
|
|
|
||
|
|
IF NOT xEnable THEN
|
||
|
|
rOutput := rInput;
|
||
|
|
iIndex := 0;
|
||
|
|
iCount := 0;
|
||
|
|
rSum := 0.0;
|
||
|
|
RETURN;
|
||
|
|
END_IF;
|
||
|
|
|
||
|
|
// Clamp window size
|
||
|
|
iWin := MIN(MAX(iWindowSize, 1), 100);
|
||
|
|
|
||
|
|
// Subtract the oldest value from sum before overwrite
|
||
|
|
rSum := rSum - arBuffer[iIndex];
|
||
|
|
|
||
|
|
// Store new value
|
||
|
|
arBuffer[iIndex] := rInput;
|
||
|
|
rSum := rSum + rInput;
|
||
|
|
|
||
|
|
// Advance circular index
|
||
|
|
iIndex := (iIndex + 1) MOD iWin;
|
||
|
|
|
||
|
|
// Track how many samples collected
|
||
|
|
IF iCount < iWin THEN
|
||
|
|
iCount := iCount + 1;
|
||
|
|
END_IF;
|
||
|
|
|
||
|
|
xReady := (iCount >= iWin);
|
||
|
|
rOutput := rSum / INT_TO_REAL(iCount); // Valid even before buffer full
|