s7-SCL-scripts/moving-average.txt

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