You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
146 lines
5.4 KiB
XML
146 lines
5.4 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<TcPlcObject Version="1.1.0.1" ProductVersion="3.1.4024.12">
|
|
<POU Name="fbPID" Id="{ba0371f9-f611-44ea-97d3-8d6e71d4762a}" SpecialFunc="None">
|
|
<Declaration><![CDATA[FUNCTION_BLOCK fbPID
|
|
VAR_INPUT
|
|
Setpoint: REAL; (* Desired setpoint *)
|
|
ProcessValue: REAL; (* Current process value *)
|
|
Enable: BOOL; (* Enable/disable PID control *)
|
|
END_VAR
|
|
VAR_OUTPUT
|
|
ControlOutput: REAL; (* Output of PID controller *)
|
|
END_VAR
|
|
VAR
|
|
// -- PID parameters
|
|
Kp: REAL := 0.0; (* Proportional gain *)
|
|
Ki: REAL := 0.0; (* Integral gain *)
|
|
Kd: REAL := 0.0; (* Derivative gain *)
|
|
|
|
// -- Internal variables
|
|
LastError: REAL := 0.0; (* Error at previous sample *)
|
|
Integral: REAL := 0.0; (* Integral of error over time *)
|
|
SampleTime: TIME := T#1S; (* Sampling time *)
|
|
|
|
// -- Auto-tuning parameters
|
|
AutoTuneStep: REAL := 0.1; (* Step size for auto-tuning *)
|
|
SettlingTime: TIME := T#5S;(* Desired settling time for auto-tuning *)
|
|
LastStepTime: TIME := T#0S;(* Time of last auto-tune step *)
|
|
AutoTuning: BOOL := FALSE; (* Auto-tuning flag *)
|
|
InitStep: BOOL := TRUE; (* Flag for initial step in auto-tuning *)
|
|
END_VAR
|
|
]]></Declaration>
|
|
<Implementation>
|
|
<ST><![CDATA[(* Function to perform auto-tuning *)
|
|
FUNCTION AutoTunePID : BOOL
|
|
VAR
|
|
CurrentTime: TIME;
|
|
Error: REAL;
|
|
DeltaTime: TIME;
|
|
BEGIN
|
|
CurrentTime := TcSysTime(); (* Get current system time *)
|
|
Error := ABS(ProcessValue - Setpoint);
|
|
|
|
IF Error < 0.05 * Setpoint THEN (* Acceptable error threshold *)
|
|
IF NOT InitStep THEN
|
|
DeltaTime := CurrentTime - LastStepTime; (* Calculate time difference *)
|
|
SampleTime := TIME_TO_REAL(DeltaTime) / 2; (* Calculate sample time *)
|
|
Kp := 0.6 / (ProcessValue * AutoTuneStep); (* Calculate proportional gain *)
|
|
Ki := 2 * Kp / (0.3 * TIME_TO_REAL(SettlingTime)); (* Calculate integral gain *)
|
|
Kd := Kp * 0.125 * TIME_TO_REAL(SettlingTime); (* Calculate derivative gain *)
|
|
AutoTuning := FALSE;
|
|
AutoTunePID := TRUE;
|
|
EXIT;
|
|
END_IF;
|
|
ELSE
|
|
InitStep := FALSE;
|
|
LastStepTime := CurrentTime;
|
|
IF ProcessValue > Setpoint THEN
|
|
ProcessValue := ProcessValue - AutoTuneStep * Setpoint; (* Decrease process value *)
|
|
ELSE
|
|
ProcessValue := ProcessValue + AutoTuneStep * Setpoint; (* Increase process value *)
|
|
END_IF;
|
|
END_IF;
|
|
|
|
AutoTunePID := FALSE;
|
|
END_FUNCTION;
|
|
|
|
(* Function to perform PID control *)
|
|
FUNCTION PIDControl : VOID
|
|
VAR
|
|
Error: REAL;
|
|
Proportional: REAL;
|
|
IntegralTerm: REAL;
|
|
DerivativeTerm: REAL;
|
|
BEGIN
|
|
IF Enable THEN
|
|
Error := Setpoint - ProcessValue;
|
|
|
|
IF AutoTuning THEN
|
|
IF AutoTunePID() THEN
|
|
RETURN;
|
|
END_IF;
|
|
END_IF;
|
|
|
|
Integral := Integral + (Error * SampleTime); (* Integral term calculation *)
|
|
Integral := MAX(MIN(Integral, 1000), -1000); (* Anti-windup limit *)
|
|
|
|
Proportional := Kp * Error; (* Proportional term *)
|
|
IntegralTerm := Ki * Integral; (* Integral term *)
|
|
DerivativeTerm := Kd * (Error - LastError) / SampleTime; (* Derivative term *)
|
|
|
|
ControlOutput := Proportional + IntegralTerm + DerivativeTerm;
|
|
|
|
LastError := Error; (* Update last error *)
|
|
ELSE
|
|
ControlOutput := 0.0; (* Disable control if not enabled *)
|
|
Integral := 0.0; (* Reset integral term *)
|
|
LastError := 0.0; (* Reset last error *)
|
|
END_IF;
|
|
END_FUNCTION;]]></ST>
|
|
</Implementation>
|
|
<Method Name="AutoTunePID" Id="{a72ed6ef-5938-4dfc-b7ba-21356dc9bded}">
|
|
<Declaration><![CDATA[METHOD AutoTunePID : BOOL
|
|
VAR_INPUT
|
|
CurrentTime: TIME;
|
|
Error: REAL;
|
|
DeltaTime: TIME;
|
|
END_VAR
|
|
]]></Declaration>
|
|
<Implementation>
|
|
<ST><![CDATA[ CurrentTime := TcSysTime(); (* Get current system time *)
|
|
Error := ABS(ProcessValue - Setpoint);
|
|
|
|
IF Error < 0.05 * Setpoint THEN (* Acceptable error threshold *)
|
|
IF NOT InitStep THEN
|
|
DeltaTime := CurrentTime - LastStepTime; (* Calculate time difference *)
|
|
SampleTime := TIME_TO_REAL(DeltaTime) / 2; (* Calculate sample time *)
|
|
Kp := 0.6 / (ProcessValue * AutoTuneStep); (* Calculate proportional gain *)
|
|
Ki := 2 * Kp / (0.3 * TIME_TO_REAL(SettlingTime)); (* Calculate integral gain *)
|
|
Kd := Kp * 0.125 * TIME_TO_REAL(SettlingTime); (* Calculate derivative gain *)
|
|
AutoTuning := FALSE;
|
|
AutoTunePID := TRUE;
|
|
EXIT;
|
|
END_IF;
|
|
ELSE
|
|
InitStep := FALSE;
|
|
LastStepTime := CurrentTime;
|
|
IF ProcessValue > Setpoint THEN
|
|
ProcessValue := ProcessValue - AutoTuneStep * Setpoint; (* Decrease process value *)
|
|
ELSE
|
|
ProcessValue := ProcessValue + AutoTuneStep * Setpoint; (* Increase process value *)
|
|
END_IF;
|
|
END_IF;
|
|
|
|
AutoTunePID := FALSE;]]></ST>
|
|
</Implementation>
|
|
</Method>
|
|
<LineIds Name="fbPID">
|
|
<LineId Id="30" Count="65" />
|
|
<LineId Id="9" Count="0" />
|
|
</LineIds>
|
|
<LineIds Name="fbPID.AutoTunePID">
|
|
<LineId Id="9" Count="23" />
|
|
<LineId Id="5" Count="0" />
|
|
</LineIds>
|
|
</POU>
|
|
</TcPlcObject> |