138 lines
2.9 KiB
Plaintext
138 lines
2.9 KiB
Plaintext
|
|
(* @PATH := '\/Functions_Collection' *)
|
|
(* @SYMFILEFLAGS := '4096' *)
|
|
FUNCTION_BLOCK FB41_PIDController
|
|
VAR_INPUT
|
|
in_SP : REAL; (* SP *)
|
|
in_PV : REAL; (* PV *)
|
|
MAN : REAL;
|
|
GAIN : REAL;
|
|
TI : REAL;
|
|
TD : REAL;
|
|
DEADB_W : REAL ;
|
|
LMN_HLM : REAL;
|
|
LMN_LLM : REAL;
|
|
LMN_FAC : REAL;
|
|
LMN_OFF : REAL;
|
|
CYCLE : REAL ;
|
|
I_ITLVAL : REAL;
|
|
DISV : REAL;
|
|
MAN_ON : BOOL;
|
|
I_SEL : BOOL;
|
|
P_SEL : BOOL;
|
|
D_SEL : BOOL;
|
|
INT_HOLD : BOOL;
|
|
I_ITL_ON : BOOL;
|
|
END_VAR
|
|
VAR_OUTPUT
|
|
LMN : REAL;
|
|
LMN_P : REAL;
|
|
LMN_I : REAL;
|
|
LMN_D : REAL;
|
|
High_Limit : BOOL;
|
|
Low_Limit : BOOL;
|
|
END_VAR
|
|
VAR
|
|
mIntegral : Integral ; (* FB Integral Instance *)
|
|
mIntegralOut : REAL; (* Integral Value *)
|
|
mOld_error : REAL ;
|
|
Error : REAL ;
|
|
mProportional : REAL ;
|
|
mDerivative : REAL ;
|
|
Gain_error : REAL; (*Error Value * Gain*)
|
|
Total_result : REAL; (*Total result of PID Block*)
|
|
INT_Block : BOOL;
|
|
LMN_alarm : BOOL ; (*Limit output alarm *)
|
|
mAuxONS : R_TRIG ;
|
|
mManEn : BOOL ;
|
|
mManONS : F_TRIG ;
|
|
END_VAR
|
|
|
|
(* @END_DECLARATION := '0' *)
|
|
(* SP - PV *)
|
|
Error := in_SP - in_PV ;
|
|
|
|
(* Multiply GAIN *)
|
|
IF ABS(Error) >= DEADB_W THEN (* Dead Band Implementation *)
|
|
Gain_error := Error * GAIN ;
|
|
ELSE
|
|
Gain_error := 0.0 ;
|
|
END_IF
|
|
|
|
(* Freeze Integral Calculation *)
|
|
INT_Block := INT_HOLD OR MAN_ON OR LMN_alarm ;
|
|
|
|
(* Integral calculation *)
|
|
IF I_SEL AND TI>0 THEN
|
|
IF I_ITL_ON THEN
|
|
mIntegralOut := I_ITLVAL;
|
|
ELSE
|
|
IF NOT INT_Block THEN
|
|
IF (( Gain_error>=0 ) AND NOT High_Limit) OR (( Gain_error<=0 ) AND NOT Low_Limit) THEN
|
|
(*mIntegral := mIntegral + Gain_error * CYCLE / TI;*)
|
|
mIntegral.i_NewValue := Gain_error / TI ;
|
|
mIntegral.i_IntCycle := CYCLE ;
|
|
mIntegral(Out_Integral:=mIntegralOut) ;
|
|
END_IF
|
|
END_IF
|
|
END_IF
|
|
ELSE
|
|
mIntegralOut := 0.0 ;
|
|
END_IF
|
|
LMN_I := mIntegralOut ;
|
|
|
|
(* Derivative calculation *)
|
|
IF ( D_SEL AND TD >0 ) THEN
|
|
mDerivative := ( Gain_error - mOld_error ) * TD / 10 ;
|
|
ELSE
|
|
mDerivative := 0.0 ;
|
|
END_IF
|
|
mOld_error := Gain_error ;
|
|
LMN_D := mDerivative ;
|
|
|
|
(* Proportional contribute *)
|
|
IF P_SEL THEN
|
|
mProportional := Gain_error ;
|
|
ELSE
|
|
mProportional := 0 ;
|
|
END_IF
|
|
LMN_P := mProportional ;
|
|
|
|
(* Total result P + I + D + DISV *)
|
|
Total_result := mProportional + mIntegralOut + mDerivative + DISV ;
|
|
|
|
mManONS(CLK:=MAN_ON) ;
|
|
|
|
(* Manual control *)
|
|
IF MAN_ON THEN
|
|
Total_result := MAN ;
|
|
IF NOT I_ITL_ON AND mManONS.Q THEN
|
|
mIntegralOut := LMN - LMN_P - DISV ; (* - Bumpless - Inizilize the Integral Component when the PID is setted in auto again *)
|
|
mIntegral(Out_Integral:=mIntegralOut) ;
|
|
mDerivative := 0.0 ;
|
|
END_IF
|
|
END_IF
|
|
|
|
(* High Low limit for total result *)
|
|
High_Limit := FALSE ;
|
|
Low_Limit := FALSE ;
|
|
|
|
IF Total_result > LMN_HLM THEN
|
|
High_Limit := TRUE ;
|
|
Total_result := LMN_HLM;
|
|
END_IF
|
|
|
|
IF Total_result < LMN_LLM THEN
|
|
Low_Limit := TRUE ;
|
|
Total_result := LMN_LLM;
|
|
END_IF
|
|
|
|
LMN := ( Total_result * LMN_FAC ) + LMN_OFF;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
END_FUNCTION_BLOCK
|