``` 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 ```