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