Вы находитесь на странице: 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

Вам также может понравиться