#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;