0% found this document useful (0 votes)
223 views6 pages

FB19

This document contains the source code of a PID control algorithm. It defines input and output variables, constants, and the logic to calculate the proportional, integral, and derivative terms to control an industrial process. The algorithm handles modes like manual vs automatic control, disturbance compensation, anti-windup protection, and output limiting. It uses common PID tuning parameters like proportional gain, integral and derivative times.

Uploaded by

Bassel Almouie
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
223 views6 pages

FB19

This document contains the source code of a PID control algorithm. It defines input and output variables, constants, and the logic to calculate the proportional, integral, and derivative terms to control an industrial process. The algorithm handles modes like manual vs automatic control, disturbance compensation, anti-windup protection, and output limiting. It uses common PID tuning parameters like proportional gain, integral and derivative times.

Uploaded by

Bassel Almouie
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 6

FUNCTION_BLOCK PID

TITLE = 'output PID-algorithm'


AUTHOR : AUT_1
FAMILY : MODCONT
NAME : PID
VERSION : '1.4'
//KNOW_HOW_PROTECT

VAR_INPUT
ER : REAL ; //error-signal
PV : REAL ; //process variable
GAIN : REAL := 2.000000e+000; //proportional gain
TI : TIME := T#20S; //reset time
I_ITLVAL : REAL ; //initialization value of the integral action
TD : TIME := T#10S; //derivative time
TM_LAG : TIME := T#2S; //time lag of the derivative action
DISV : REAL ; //disturbance variable
P_SEL : BOOL := TRUE; //proportional action selected
PFDB_SEL : BOOL ; //proportional action in feedback path selected
DFDB_SEL : BOOL ; //derivative action in feedback path on
I_SEL : BOOL := TRUE; //integral action selected
INT_HPOS : BOOL ; //integral action hold in positive direction
INT_HNEG : BOOL ; //integral action hold in negative direction
I_ITL_ON : BOOL ; //initialization of the integral action on
D_SEL : BOOL ; //derivative action selected
DISV_SEL : BOOL := TRUE; //disturbance variable on
SMOO_CHG : BOOL := TRUE; //smooth changeover from the manual mode to the
automatic mode
COM_RST : BOOL ; //complete restart
CYCLE : TIME := T#1S; //sample time
LMNG_PID : STRUCT
LMN : REAL ;
LMN_HLM : REAL ;
LMN_LLM : REAL ;
R_MTR_TM : REAL ;
ARWHL_ON : BOOL ;
ARWLL_ON : BOOL ;
MAN_ON : BOOL ;
LMNGS_ON : BOOL ;
LMNR_ON : BOOL ;
END_STRUCT ;
END_VAR
VAR_OUTPUT
LMN_P : REAL ; //proportionality component
LMN_I : REAL ; //integral component
LMN_D : REAL ; //derivative component
PID_LMNG : STRUCT
OUTV : REAL ;
HVAR1 : REAL ;
HVAR2 : REAL ;
HVAR3 : REAL ;
HBIT1 : BOOL ;
HBIT2 : BOOL ;
HBIT3 : BOOL ;
END_STRUCT ;
END_VAR
VAR
sInvAlt : REAL ;
sIanteilAlt : REAL ;
sRestInt : REAL ;
sRestDif : REAL ;
sRueck : REAL ;
sSpOld : REAL ;
END_VAR
VAR_TEMP
Hvar : REAL ; //Hilfsvariable
ErKp : REAL ; //Variable ER*GAIN
rTi : REAL ; //Integrationszeit in real
rTd : REAL ; //Differentiationszeit in real
rTmLag : REAL ; //Verzögerungszeit in real
rCycle : REAL ; //Abtastzeit in real
Panteil : REAL ; //P-Anteil
Ianteil : REAL ; //I-Anteil
Diff : REAL ; //Änderungswert
Danteil : REAL ; //D-Anteil
Verstaerk : REAL ; //Verstärkung
RueckDiff : REAL ; //Differenz des Rückkopplungswertes
RueckAlt : REAL ; //Alter Rückkopplungswert
dDisv : REAL ; //disturbance variable
dLmn : REAL ; //Stellwert
PidOutv : REAL ; //PID-Ausgangswert
Hvar1 : REAL ; //PID-Ausgangswert Hilfsvariable 1
Hvar2 : REAL ; //PID-Ausgangswert Hilfsvariable 2
rLmnHlm : REAL ; //Obere Begrenzung
rLmnLlm : REAL ; //Untere Begrenzung
rMtrTm : REAL ; //Motorstellzeit
rSp : REAL ; //Sollwert
RegD_PRueck : REAL ; //Regeldifferenz und P-Anteil in Rückführung
lmn_i_hlm : REAL ; //provisorische Begrenzung I-Anteil
lmn_i_llm : REAL ; //provisorische Begrenzung I-Anteil
iKorrektur : REAL ; //Korrektur des I-Anteils
iKorrektur2 : REAL ; //Korrektur des I-Anteils
bPantKorr : BOOL ; //P-Anteil zur Anzeige korrigieren
bIantKorr : BOOL ; //I-Anteil zur Anzeige korrigieren
bHvar : BOOL ; //Hilfsvariable
bArwhlOn : BOOL ; //anti reset wind-up in high limit on
bArwllOn : BOOL ; //anti reset wind-up in low limit on
bManOn : BOOL ; //manual mode on
bLmngsOn : BOOL ; //PID-algorithm for step controller
bLmnrOn : BOOL ; //step controller with repeated manipulated value
bHBit1 : BOOL ; //Hilfsbit 1
bHBit2 : BOOL ; //Hilfsbit 2
bHBit3 : BOOL ; //Hilfsbit 3
END_VAR
BEGIN
bHBit1:=FALSE;
bHBit2:=FALSE;
bHBit3:=FALSE;
IF COM_RST THEN
sRestInt:=0.0;
sRueck:=0.0;
sRestDif:=0.0;
sInvAlt:=0.0;
sIanteilAlt:=0.0;
sSpOld:=0.0;
ErKp:=0.0;
Panteil:=0.0;
Ianteil:=0.0;
Danteil:=0.0;
PidOutv:=0.0;
Hvar1:=0.0;
Hvar2:=0.0;
ELSE
bManOn:=LMNG_PID.MAN_ON;
bLmngsOn:=LMNG_PID.LMNGS_ON;
bLmnrOn:=LMNG_PID.LMNR_ON;
dLmn:=LMNG_PID.LMN;
rLmnHlm:=LMNG_PID.LMN_HLM;
rLmnLlm:=LMNG_PID.LMN_LLM;
rMtrTm:=LMNG_PID.R_MTR_TM;
bArwhlOn:=LMNG_PID.ARWHL_ON;
bArwllOn:=LMNG_PID.ARWLL_ON;
ErKp:=ER*GAIN;
rSp:=ER+PV;
rTi:=DINT_TO_REAL(TIME_TO_DINT(TI))/1000.0;
rTd:=DINT_TO_REAL(TIME_TO_DINT(TD))/1000.0;
rTmLag:=DINT_TO_REAL(TIME_TO_DINT(TM_LAG))/1000.0;
rCycle:=DINT_TO_REAL(TIME_TO_DINT(CYCLE))/1000.0;
IF rTi<(rCycle*0.5) THEN
rTi:=rCycle*0.5;
END_IF;
IF rTd<rCycle THEN
rTd:=rCycle;
END_IF;
IF rTmLag<(rCycle*0.5) THEN
rTmLag:=rCycle*0.5;
END_IF;
IF DISV_SEL THEN
dDisv:=DISV;
ELSE
dDisv:=0.0;
END_IF;
bPantKorr:=FALSE;
bIantKorr:=FALSE;
RegD_PRueck:=(-PV)*GAIN;
Panteil:=0.0;
IF P_SEL THEN
IF PFDB_SEL THEN
IF (NOT I_SEL) OR I_ITL_ON THEN
Panteil:=RegD_PRueck;
ELSE
Panteil:=ErKp;
bPantKorr:=TRUE;
END_IF;
ELSE
Panteil:=ErKp;
END_IF;
END_IF;
IF bLmngsOn THEN
Hvar:=rTi-ABS(0.01*ErKp*rMtrTm);
IF Hvar<(0.1*rTi) THEN
rTi:=0.1*rTi;
ELSE
rTi:=Hvar;
END_IF;
END_IF;
IF I_SEL THEN
IF I_ITL_ON THEN
Ianteil:=I_ITLVAL;
sRestInt:=0.0;
ELSE
IF (NOT bLmngsOn) OR (bLmngsOn AND bLmnrOn) THEN
IF bManOn THEN
Ianteil:=dLmn-dDisv;
IF ((NOT bLmngsOn) AND SMOO_CHG) OR PFDB_SEL THEN
Ianteil:=Ianteil-Panteil;
END_IF;
sRestInt:=0.0;
ELSE
Diff:=(rCycle/rTi)*(ErKp+sInvAlt)*0.5+sRestInt;
IF Diff>=0.0 THEN
bHvar:=INT_HPOS OR bArwhlOn;
ELSE
bHvar:=INT_HNEG OR bArwllOn;
END_IF;
IF bHvar THEN
Diff:=0.0;
END_IF;
Ianteil:=sIanteilAlt+Diff;
sRestInt:=sIanteilAlt-Ianteil+Diff;
IF PFDB_SEL AND P_SEL THEN
Ianteil:=Ianteil-(rSp-sSpOld)*GAIN;
END_IF;
END_IF;
bIantKorr:=TRUE;
ELSE
Ianteil:=0.0;
sRestInt:=0.0;
END_IF;
END_IF;
ELSE
Ianteil:=0.0;
sRestInt:=0.0;
END_IF;
IF DFDB_SEL THEN
Diff:=(-PV)*GAIN;
ELSE
Diff:=ErKp;
END_IF;
IF (NOT bManOn) AND D_SEL THEN
Verstaerk:=rTd/((rCycle*0.5)+rTmLag);
Danteil:=(Diff-sRueck)*Verstaerk;
RueckAlt:=sRueck;
RueckDiff:=(rCycle/rTd)*Danteil+sRestDif;
sRueck:=RueckDiff+RueckAlt;
sRestDif:=RueckAlt-sRueck+RueckDiff;
ELSE
Danteil:=0.0;
sRestDif:=0.0;
IF SMOO_CHG OR DFDB_SEL OR bLmngsOn THEN
sRueck:=Diff;
ELSE
sRueck:=0.0;
END_IF;
END_IF;
PidOutv:=Panteil+Ianteil+Danteil+dDisv;
bHVar:=((NOT I_ITL_ON) AND I_SEL) AND (NOT bManOn);
IF ((NOT bLmngsOn) AND bHVar) OR (bLmngsOn AND bLmnrOn AND bHVar) THEN
lmn_i_hlm:=rLmnHlm-dDisv;
lmn_i_llm:=rLmnLlm-dDisv;
IF (Ianteil>lmn_i_hlm) AND (PidOutv>rLmnHlm) AND ((PidOutv-
Danteil)>rLmnHlm) THEN
iKorrektur:=Ianteil-lmn_i_hlm;
iKorrektur2:=PidOutv-rLmnHlm;
IF iKorrektur2<iKorrektur THEN
iKorrektur:=iKorrektur2;
END_IF;
Ianteil:=Ianteil-iKorrektur;
ELSE
IF (Ianteil<lmn_i_llm) AND (PidOutv<rLmnLlm) AND ((PidOutv-
Danteil)<rLmnLlm) THEN
iKorrektur:=Ianteil-lmn_i_llm;
iKorrektur2:=PidOutv-rLmnLlm;
IF iKorrektur2>iKorrektur THEN
iKorrektur:=iKorrektur2;
END_IF;
Ianteil:=Ianteil-iKorrektur;
ELSE
;
END_IF;
END_IF;
IF INT_HPOS OR bArwhlOn THEN
IF PidOutv<rLmnHlm THEN
iKorrektur:=(rCycle/rTi)*Panteil;
IF (iKorrektur+PidOutv)>=rLmnHlm THEN
PidOutv:=rLmnHlm;
Ianteil:=Ianteil+iKorrektur;
END_IF;
END_IF;
ELSIF INT_HNEG OR bArwllOn THEN
IF PidOutv>rLmnLlm THEN
iKorrektur:=(rCycle/rTi)*Panteil;
IF (iKorrektur+PidOutv)<=rLmnLlm THEN
PidOutv:=rLmnLlm;
Ianteil:=Ianteil+iKorrektur;
END_IF;
END_IF;
ELSE
;
END_IF;
END_IF;
sInvAlt:=ErKp;
sIanteilAlt:=Ianteil;
sSpOld:=rSp;
IF bPantKorr AND bIantKorr THEN
Ianteil:=Ianteil-(RegD_PRueck-Panteil);
END_IF;
IF bPantKorr THEN
Panteil:=RegD_PRueck;
END_IF;
IF bLmngsOn THEN
IF NOT bLmnrOn THEN
Hvar1:=ErKp/rTi;
Hvar2:=dDisv+Ianteil;
ELSE
Hvar1:=Ianteil;
Hvar2:=dDisv;
END_IF;
bHBit1:=P_SEL AND I_SEL AND (NOT I_ITL_ON) AND (NOT PFDB_SEL) AND (NOT
DFDB_SEL);
bHBit2:=(NOT I_ITL_ON) AND I_SEL;
bHBit3:=rSp<>sSpOld;
ELSE
HVar1:=PidOutv-Danteil;
HVar2:=0.0;
END_IF;
sSpOld:=rSp;
END_IF;
LMN_P:=Panteil;
LMN_I:=Ianteil;
LMN_D:=Danteil;
PID_LMNG.OUTV:=PidOutv;
PID_LMNG.HVAR1:=Hvar1;
PID_LMNG.HVAR2:=Hvar2;
PID_LMNG.HVAR3:=ErKp;
PID_LMNG.HBIT1:=bHBit1;
PID_LMNG.HBIT2:=bHBit2;
PID_LMNG.HBIT3:=bHBit3;
END_FUNCTION_BLOCK

You might also like