Sei sulla pagina 1di 2

FUNCTION_BLOCK FB305

TITLE = 'CSPID'
//Block comment:Compact PID called by script function
NAME : C_PID
FAMILY : Process
AUTHOR : IPS
VERSION : '1.0'
VAR_INPUT
// INPUT Variables
SP : REAL;
PV : DWORD;
BPV : DWORD;
PVTime : TIME;
BPVTime : TIME;
GAIN : REAL;
TI : TIME;
TD : TIME;
TM_Lag : TIME;
EndOfScale : REAL := 100.0;
MinDDP :REAL:= 0.1;
RESET : BOOL;
END_VAR
VAR_OUTPUT
// OUTPUT Vaiables

END_VAR

VAR_TEMP
// Temporary Variables
DeltaT : DINT;
END_VAR
VAR
// Static Variables
rPV :REAL;
DP:REAL;
BDP:REAL;
rDPTime:REAL;
rBDPTime:REAL;
DDP : REAL;
BDDP :REAL;
ProportionalFactorVal : REAL;
IntegralFactorVal : REAL;
DerivativeFactorVal : REAL;
IDP : REAL;
BIDP : REAL;
rIntgralParVal :REAL;
rDerivativeParVal :REAL;
rProportionalParVal :REAL;
rCycle :REAL;
ControlValueOut : REAL;
CVariableValue : REAL;
END_VAR

// Statement Section
BEGIN
IF RESET
THEN
IDP := 0.0;
END_IF;
rPV := DINT_TO_REAL(DWORD_TO_DINT(PV));
rDPTime := DINT_TO_REAL(TIME_TO_DINT(PVTime))/1000.0;
rBDPTime := DINT_TO_REAL(TIME_TO_DINT(BPVTime))/1000.0;
DP := SP - rPV;
rIntgralParVal := DINT_TO_REAL(TIME_TO_DINT(TI))/1000.0;
rDerivativeParVal := DINT_TO_REAL(TIME_TO_DINT(TD))/1000.0;
rProportionalParVal := GAIN;
//rCycle:= (rDPTime - RBDPTime);
//rCycle := DINT_TO_REAL(TIME_TO_DINT(PVTIME -BPVTime))/ 1000.0;
DeltaT := TIME_TO_DINT(PVTIME -BPVTime);
rCycle := DINT_TO_REAL( DeltaT) /1000.0;
IF (rCycle > 0.2 ) OR (rCycle <0.0)
THEN
rCycle := 0.2;
END_IF;
// Integral Action
IDP:= rCycle* DP/2.0 + BIDP;
IntegralFactorVal:= IDP * rProportionalParVal / rIntgralParVal;
BIDP := IDP;
// Derivative Action
DDP := DP /rCycle;
DerivativeFactorVal:= rProportionalParVal * rDerivativeParVal * DDP;
IF (MinDDP < ABS(DDP - BDDP))//when the error difference is less thab MinDDP
then we reset the integral factor
THEN // Reset before integral part
BIDP := 0.0;
END_IF;
BDDP := DDP;
BDP := DP;
// Proportiona Action
ProportionalFactorVal:= rProportionalParVal * DP;
// Raw PID Out
ControlValueOut:= ProportionalFactorVal + IntegralFactorVal +
DerivativeFactorVal ;
CVariableValue := CVariableValue + ControlValueOut;
IF CVariableValue > EndOfScale
THEN
CVariableValue := EndOfScale;
ELSIF CVariableValue< 0.0
THEN
CVariableValue := 0.0;
END_IF;

END_FUNCTION_BLOCK

Potrebbero piacerti anche