Add rate-limmiter-md
This commit is contained in:
parent
a43610406f
commit
7bab96799f
73
rate-limmiter-md
Normal file
73
rate-limmiter-md
Normal file
|
|
@ -0,0 +1,73 @@
|
||||||
|
FUNCTION "FC_RateLimiter" : Void
|
||||||
|
{ S7_Optimized_Access := 'TRUE' }
|
||||||
|
VERSION : 0.1
|
||||||
|
VAR_INPUT
|
||||||
|
analog_input : Real; // Raw input signal (setpoint or feedback)
|
||||||
|
pos_slew_rate : Real := 10.0; // Max allowed increase per PLC scan (engineering units)
|
||||||
|
neg_slew_rate : Real := 10.0; // Max allowed decrease per PLC scan (engineering units)
|
||||||
|
enable : Bool := TRUE; // Enable rate limiting
|
||||||
|
reset : Bool := FALSE; // Reset: output snaps to input immediately
|
||||||
|
END_VAR
|
||||||
|
|
||||||
|
VAR_OUTPUT
|
||||||
|
rate_limited_output : Real; // Slew-rate limited output
|
||||||
|
END_VAR
|
||||||
|
|
||||||
|
VAR
|
||||||
|
prev_output : Real; // Previous output value (retains between scans)
|
||||||
|
initialized : Bool := FALSE; // First-run initialization flag
|
||||||
|
END_VAR
|
||||||
|
|
||||||
|
VAR_TEMP
|
||||||
|
delta : Real; // Calculated change from previous output
|
||||||
|
max_rise : Real; // Clamped positive limit for this cycle
|
||||||
|
max_fall : Real; // Clamped negative limit for this cycle
|
||||||
|
END_VAR
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
// Handle reset: snap output to input immediately
|
||||||
|
IF #reset THEN
|
||||||
|
#rate_limited_output := #analog_input;
|
||||||
|
#prev_output := #analog_input;
|
||||||
|
#initialized := TRUE;
|
||||||
|
RETURN;
|
||||||
|
END_IF;
|
||||||
|
|
||||||
|
// Bypass if disabled: pass-through mode
|
||||||
|
IF NOT #enable THEN
|
||||||
|
#rate_limited_output := #analog_input;
|
||||||
|
#prev_output := #analog_input;
|
||||||
|
RETURN;
|
||||||
|
END_IF;
|
||||||
|
|
||||||
|
// Initialize on first run to avoid startup transient
|
||||||
|
IF NOT #initialized THEN
|
||||||
|
#rate_limited_output := #analog_input;
|
||||||
|
#prev_output := #analog_input;
|
||||||
|
#initialized := TRUE;
|
||||||
|
RETURN;
|
||||||
|
END_IF;
|
||||||
|
|
||||||
|
// Ensure slew rates are non-negative
|
||||||
|
#max_rise := ABS(#pos_slew_rate);
|
||||||
|
#max_fall := ABS(#neg_slew_rate);
|
||||||
|
|
||||||
|
// Calculate desired change
|
||||||
|
#delta := #analog_input - #prev_output;
|
||||||
|
|
||||||
|
// Apply asymmetric slew limiting
|
||||||
|
IF #delta > #max_rise THEN
|
||||||
|
// Rising too fast: limit to max rise
|
||||||
|
#rate_limited_output := #prev_output + #max_rise;
|
||||||
|
ELSIF #delta < -#max_fall THEN
|
||||||
|
// Falling too fast: limit to max fall
|
||||||
|
#rate_limited_output := #prev_output - #max_fall;
|
||||||
|
ELSE
|
||||||
|
// Within allowed slew range: pass through
|
||||||
|
#rate_limited_output := #analog_input;
|
||||||
|
END_IF;
|
||||||
|
|
||||||
|
// Store for next scan
|
||||||
|
#prev_output := #rate_limited_output;
|
||||||
|
|
||||||
|
END_FUNCTION
|
||||||
Loading…
Reference in a new issue