added new files for filtering
This commit is contained in:
parent
be5720e84e
commit
88e893e4ad
27
Exponential-Moving-Average.txt
Normal file
27
Exponential-Moving-Average.txt
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#Faster response than SMA, no large buffer needed. The alpha parameter (0.0–1.0) controls smoothing — lower = more smoothing.
|
||||
|
||||
FUNCTION_BLOCK FB_EMA
|
||||
VAR_INPUT
|
||||
xEnable : BOOL;
|
||||
rInput : REAL;
|
||||
rAlpha : REAL := 0.1; // Smoothing factor: 0 = max smooth, 1 = no filter
|
||||
END_VAR
|
||||
VAR_OUTPUT
|
||||
rOutput : REAL;
|
||||
END_VAR
|
||||
VAR
|
||||
xFirst : BOOL := TRUE;
|
||||
END_VAR
|
||||
|
||||
IF NOT xEnable THEN
|
||||
xFirst := TRUE;
|
||||
rOutput := rInput;
|
||||
RETURN;
|
||||
END_IF;
|
||||
|
||||
IF xFirst THEN
|
||||
rOutput := rInput;
|
||||
xFirst := FALSE;
|
||||
ELSE
|
||||
rOutput := rAlpha * rInput + (1.0 - rAlpha) * rOutput;
|
||||
END_IF;
|
||||
49
Weighted Moving Average (WMA).txt
Normal file
49
Weighted Moving Average (WMA).txt
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
#More recent samples have higher weight. Better step response than SMA.
|
||||
|
||||
FUNCTION_BLOCK FB_WMA
|
||||
VAR_INPUT
|
||||
xEnable : BOOL;
|
||||
rInput : REAL;
|
||||
iWindowSize : INT := 8; // Max 16
|
||||
END_VAR
|
||||
VAR_OUTPUT
|
||||
rOutput : REAL;
|
||||
END_VAR
|
||||
VAR
|
||||
arBuffer : ARRAY[0..15] OF REAL;
|
||||
iIndex : INT := 0;
|
||||
iCount : INT := 0;
|
||||
iWin : INT;
|
||||
rWeightSum : REAL;
|
||||
rValSum : REAL;
|
||||
i : INT;
|
||||
iPos : INT;
|
||||
rWeight : REAL;
|
||||
END_VAR
|
||||
|
||||
IF NOT xEnable THEN
|
||||
iIndex := 0; iCount := 0; rOutput := rInput;
|
||||
RETURN;
|
||||
END_IF;
|
||||
|
||||
iWin := MIN(MAX(iWindowSize, 1), 16);
|
||||
|
||||
// Store newest sample
|
||||
arBuffer[iIndex] := rInput;
|
||||
iIndex := (iIndex + 1) MOD iWin;
|
||||
IF iCount < iWin THEN iCount := iCount + 1; END_IF;
|
||||
|
||||
// Calculate weighted sum (weight = position, newest = highest)
|
||||
rWeightSum := 0.0;
|
||||
rValSum := 0.0;
|
||||
FOR i := 0 TO iCount - 1 DO
|
||||
// Most recent sample is at (iIndex - 1), going back
|
||||
iPos := (iIndex - 1 - i + iWin * 2) MOD iWin;
|
||||
rWeight := INT_TO_REAL(iCount - i); // Newest gets weight=iCount, oldest=1
|
||||
rValSum := rValSum + arBuffer[iPos] * rWeight;
|
||||
rWeightSum := rWeightSum + rWeight;
|
||||
END_FOR;
|
||||
|
||||
IF rWeightSum > 0.0 THEN
|
||||
rOutput := rValSum / rWeightSum;
|
||||
END_IF;
|
||||
Loading…
Reference in a new issue