Modular PID Control ? 3.

: 2009-03-23

: komatic

: ModPID



MODPID


1.SP_GEN -.
2.A_DEAD_B .
3.INTEG .
4.DIF .
5.LAG2ND 2 .
6.LAG1ST 1 .

download , .

-.

FUNCTION_BLOCK FB125
TITLE =" setpoint generator"
AUTHOR : AUT_1
FAMILY : MODCONT
NAME : SP_GEN
VERSION : " 1.0"
// reverse by komatic
(*
SP_GEN OUTVUP
OUTVDN
OUTV H_LM L_LM.
OUTV :
3 OUTVUP OUTVDN:
d OUTV / d t = (H_LM L_LM) / (100 )
, 3 :
d OUTV / d t = (H_LM L_LM) / (10 ).

: H_LM . OUTV . L_LM.

H_LM L_LM,
QH_LM QL_LM.
DFOUT_ON = TRUE (), OUTV = DF_OUTV.
*)
VAR_INPUT
DF_OUTV : REAL ; //
H_LM : REAL := 1.000000e+002; //
L_LM : REAL ; //
OUTVUP : BOOL ; //
OUTVDN : BOOL ; //
DFOUT_ON : BOOL ; //
COM_RST : BOOL ; //
CYCLE : TIME := T#100MS; //
END_VAR
VAR_OUTPUT
OUTV : REAL ; //
QH_LM : BOOL ; //
QL_LM : BOOL ; //
END_VAR
VAR
stUpSp : TIME ;
stDownSp : TIME ;
rCycle : REAL ;
Sollwert : REAL ;
END_VAR
BEGIN
IF COM_RST
THEN
Sollwert:=0.0;
stUpSp:=T#0MS;
stDownSp:=T#0MS;
ELSE
rCycle:=DINT_TO_REAL(TIME_TO_DINT(CYCLE))/1000.0;
IF (NOT (OUTVUP OR QL_LM)) AND OUTVDN
THEN
stUpSp:=T#0MS;
stDownSp:=stDownSp+CYCLE;
IF stDownSp > T#3S
THEN
Sollwert:=Sollwert-((H_LM-L_LM)*rCycle/10.0);
ELSE
Sollwert:=Sollwert-((H_LM-L_LM)*rCycle/100.0);
END_IF;
ELSIF (NOT (OUTVDN OR QH_LM)) AND OUTVUP
THEN
stDownSp:=T#0MS;
stUpSp:=stUpSp+CYCLE;
IF stUpSp > T#3S
THEN
Sollwert:=Sollwert+((H_LM-L_LM)*rCycle/10.0);
ELSE
Sollwert:=Sollwert+((H_LM-L_LM)*rCycle/100.0);
END_IF;
ELSE
stUpSp:=T#0MS;
stDownSp:=T#0MS;
END_IF;
END_IF;
IF DFOUT_ON
THEN
Sollwert:=DF_OUTV;
stUpSp:=T#0MS;
stDownSp:=T#0MS;
END_IF;
IF Sollwert >= H_LM
THEN
QH_LM:=1;
QL_LM:=0;
Sollwert:=H_LM;
ELSE
QH_LM:=0;
IF Sollwert <= L_LM
THEN
QL_LM:=1;
Sollwert:=L_LM;
ELSE
QL_LM:=0;
END_IF;
END_IF;
OUTV:=Sollwert;
END_FUNCTION_BLOCK

.

FUNCTION_BLOCK FB101
TITLE =" adaptive dead band"
AUTHOR : AUT_1
FAMILY : MODCONT
NAME : A_DEAD_B
VERSION : " 1.0"
// reverse by komatic
(*
.
.
*)
VAR_INPUT
INV : REAL ; //
DB_WH_LM : REAL := 5.000000e+000; //
DB_WL_LM : REAL := 1.000000e+000; //
CRIT_FRQ : REAL := 1.000000e-001; //
RET_FAC : INT := 1; //
ADAPT_ON : BOOL ; //
COM_RST : BOOL ; //
CYCLE : TIME := T#1S; //
END_VAR
VAR_OUTPUT
OUTV : REAL ; //
DB_WIDTH : REAL ; //
END_VAR
VAR
sbPos : BOOL ;
sbNeg : BOOL ;
stP1 : TIME ;
stP2 : TIME ;
siZaehl : INT ;
END_VAR
VAR_TEMP
drOutv : REAL ; //Zwischenspeicher OUTV
drDbWidth : REAL ; //Zwischenspeicher DB_WIDTH
dbUp : BOOL ; //Kennung "Totzonenbreite vergrern"
dbDown : BOOL ; //Kennung "Totzonenbreite verkleinern"
END_VAR
BEGIN
IF COM_RST
THEN
sbPos:=0;
sbNeg:=0;
dbUp:=0;
dbDown:=0;
stP1:=T#0MS;
stP2:=T#0MS;
siZaehl:=0;
OUTV:=0.0;
DB_WIDTH:=DB_WL_LM;
ELSE
IF ADAPT_ON
THEN //
//----------
dbDown:=0;
IF stP1 >= CYCLE
THEN
stP1:=stP1 - CYCLE;
IF siZaehl >=1
THEN
dbUp:=1;
ELSE
dbUp:=0;
END_IF;
ELSE
siZaehl:=0;
dbUp:=0;
END_IF;
//----------
IF INV < -DB_WIDTH
THEN
sbNeg:=1;
IF sbPos
THEN
stP1:=DINT_TO_TIME(REAL_TO_DINT(1000.0 / CRIT_FRQ));
siZaehl:=siZaehl+1;
sbPos:=0;
ELSE
dbUp:=0;
END_IF;
drOutv:=INV + DB_WIDTH;
stP2:=T#0MS;
ELSE
//----------
IF INV > DB_WIDTH
THEN
sbPos:=1;
IF sbNeg
THEN
stP1:=DINT_TO_TIME(REAL_TO_DINT(1000.0 / CRIT_FRQ));
siZaehl:=siZaehl+1;
sbNeg:=0;
ELSE
dbUp:=0;
END_IF;
drOutv:=INV - DB_WIDTH;
stP2:=T#0MS;
ELSE
dbUp:=0;
IF stP2 >= CYCLE
THEN
stP2:=stP2 - CYCLE;
IF stP2 < CYCLE
THEN
dbDown:=1;
END_IF;
ELSE
stP2:=DINT_TO_TIME(REAL_TO_DINT(RET_FAC*1000.0/CRIT_FRQ));
END_IF;
drOutv:=0.0;
END_IF;
//----------
IF dbUp
THEN
drDbWidth:=DB_WIDTH+0.1;
IF drDbWidth > DB_WH_LM THEN drDbWidth:=DB_WH_LM; END_IF;
ELSE
IF dbDown
THEN
drDbWidth:=DB_WIDTH-0.1;
IF drDbWidth < DB_WL_LM THEN drDbWidth:=DB_WL_LM; END_IF;
ELSE
drDbWidth:=DB_WIDTH;
END_IF;
OUTV:=drOutv;
DB_WIDTH:=drDbWidth;
END_IF;
END_IF;
ELSE //
IF INV < -DB_WIDTH
THEN
OUTV:=INV+DB_WIDTH;
ELSE
IF INV > DB_WIDTH
THEN
OUTV:=INV-DB_WIDTH;
ELSE
OUTV:=0.0;
END_IF;
END_IF;
END_IF;
END_IF;
END_FUNCTION_BLOCK

.

FUNCTION_BLOCK FB108
TITLE =" integrator"
AUTHOR : AUT_1
FAMILY : MODCONT
NAME : INTEG
VERSION : " 1.0"
// reverse by komatic
(*
.
.
*)
VAR_INPUT
INV : REAL ; //
H_LM : REAL := 1.000000e+002; //
L_LM : REAL ; //
TI : TIME := T#25S; //
DF_OUTV : REAL ; //
HOLD : BOOL ; //
DFOUT_ON : BOOL ; //
COM_RST : BOOL ; //
CYCLE : TIME := T#1S; //
END_VAR
VAR_OUTPUT
OUTV : REAL ; //
QH_LM : BOOL ; //
QL_LM : BOOL ; //
END_VAR
VAR
sRest : REAL ;
END_VAR
VAR_TEMP
rTi : REAL ; // real
rCycle : REAL ; // real
OutvNew : REAL ; //Neue Ausgangsgre
OutvDiff : REAL ; //nderungswert
END_VAR
BEGIN
IF COM_RST
THEN //
sRest:=0.0;
IF DFOUT_ON
THEN
OutvNew:=DF_OUTV;
ELSE
OutvNew:=0.0;
END_IF;
ELSE
IF DFOUT_ON
THEN
OutvNew:=DF_OUTV;
ELSE
IF HOLD
THEN
OutvNew:=OUTV;
sRest:=0.0;
ELSE //
rCycle:=DINT_TO_REAL(TIME_TO_DINT(CYCLE));
rTi:=DINT_TO_REAL(TIME_TO_DINT(TI));
IF rTi < rCycle THEN rTi:=rCycle; END_IF;
OutvDiff:=rCycle / rTi * INV + sRest;
OutvNew:=OutvDiff + OUTV;
sRest:=OUTV - OutvNew + OutvDiff;
END_IF;
END_IF;
END_IF;
IF OutvNew >= H_LM
THEN
QL_LM:=0;
QH_LM:=1;
OutvNew:=H_LM;
ELSE
QH_LM:=0;
IF OutvNew <= L_LM
THEN
QL_LM:=1;
OutvNew:=L_LM;
ELSE
QL_LM:=0;
END_IF;
END_IF;
OUTV:=OutvNew;
END_FUNCTION_BLOCK

.

FUNCTION_BLOCK FB106
TITLE =" differentiator"
AUTHOR : AUT_1
FAMILY : MODCONT
NAME : DIF
VERSION : " 1.0"
// reverse by komatic
(*
.
.
*)
VAR_INPUT
INV : REAL ; //
TD : TIME := T#25S; //
TM_LAG : TIME := T#5S; // ..
COM_RST : BOOL ; //
CYCLE : TIME := T#1S; //
END_VAR
VAR_OUTPUT
OUTV : REAL ; //
END_VAR
VAR
sRueck : REAL ;
sRest : REAL ;
END_VAR
VAR_TEMP
rTd : REAL ; // real
rTmLag : REAL ; // .. real
rCycle : REAL ; // real
OutvNew : REAL ; //Neue Ausgangsgre
Verstaerk : REAL ; //Verstrkung
RueckDiff : REAL ; //Differenz des Rckkopplungswertes
RueckAlt : REAL ; //Alter Rckkopplungswert
END_VAR
BEGIN
IF COM_RST
THEN
sRest:=0.0;
OUTV:=0;
sRueck:=INV;
ELSE
rCycle:=DINT_TO_REAL(TIME_TO_DINT(CYCLE));
rTd:=DINT_TO_REAL(TIME_TO_DINT(TD));
rTmLag:=DINT_TO_REAL(TIME_TO_DINT(TM_LAG));
IF rTd < rCycle THEN rTd:=rCycle; END_IF;
IF rTmLag < rCycle * 0.5 THEN rTmLag:=rCycle * 0.5; END_IF;
Verstaerk:= rTd / (rCycle * 0.5 + rTmLag);
OutvNew:= (INV - sRueck) * Verstaerk;
RueckAlt:=sRueck;
RueckDiff:= rCycle / rTd * OutvNew + sRest;
sRueck:=RueckDiff + RueckAlt;
sRest:=RueckAlt - sRueck + RueckDiff;
OUTV:=OutvNew;
END_IF;
END_FUNCTION_BLOCK

2 .

FUNCTION_BLOCK FB110
TITLE =" second-order lag element"
AUTHOR : AUT_1
FAMILY : MODCONT
NAME : LAG2ND
VERSION : " 1.0"
// reverse by komatic
(*
2 . .
*)
VAR_INPUT
INV : REAL ; //
TM_CONST : TIME := T#10S; //
DAM_COEF : REAL := 1.000000e+000; //damping coefficient
TRANCOEF : REAL := 1.000000e+000; //transfer coefficient
DF_OUTV : REAL ; //
DFOUT_ON : BOOL ; //
TRACK : BOOL ; // OUTV=INV
COM_RST : BOOL ; //
CYCLE : TIME := T#1S; //
END_VAR
VAR_OUTPUT
OUTV : REAL ; //
END_VAR
VAR
sRest1 : REAL ;
sRest2 : REAL ;
sRueck : REAL ;
sInt : REAL ;
END_VAR
VAR_TEMP
drTmCon : REAL ; //Verzgerungszeit in real
drCycle : REAL ; //Abtastzeit in real
Hvar : REAL ; //Hilfsvariable
RueckDiff : REAL ; //Rckkopplungsdifferenz
IntDiff : REAL ; //Inkrement beim Integrieren
RueckAlt : REAL ; //alter Rckkopplungswert
IntAlt : REAL ; //alter Integrierwert
END_VAR
BEGIN
IF COM_RST
THEN
OUTV:=0.0;
sRest1:=0.0;
sRest2:=0.0;
sRueck:=0.0;
sInt:=0.0;
ELSE
IF TRACK
THEN
OUTV:=INV;
sRest1:=0.0;
sRest2:=0.0;
sRueck:=INV * TRANCOEF;
sInt:=INV*2.0*DAM_COEF;
ELSE
drCycle:=DINT_TO_REAL(TIME_TO_DINT(CYCLE));
drTmCon:=DINT_TO_REAL(TIME_TO_DINT(TM_CONST));
IF drTmCon < drCycle / 2.0 THEN drTmCon:=drCycle / 2.0; END_IF;
IntAlt:=sInt;
IntDiff:=(INV - (sRueck / TRANCOEF)) * drCycle / drTmCon + sRest1;
sInt:=IntDiff + sInt;
sRest1:=IntAlt - sInt + IntDiff;
RueckAlt:=sRueck;
Hvar:= drCycle / (drTmCon / DAM_COEF);
Hvar:=((sInt * TRANCOEF / (2*DAM_COEF) - RueckAlt) * Hvar) / (1 + Hvar);
OUTV:=Hvar+RueckAlt;
RueckDiff:=2.0 * Hvar + sRest2;
sRueck:=RueckDiff + RueckAlt;
sRest2:=RueckAlt-sRueck+RueckDiff;
END_IF;
END_IF;
IF DFOUT_ON
THEN
OUTV:=DF_OUTV;
sRest1:=0.0;
sRest2:=0.0;
sRueck:=INV*TRANCOEF;
sInt:=INV*2.0*DAM_COEF;
END_IF;
END_FUNCTION_BLOCK

1 .

FUNCTION_BLOCK FB109
TITLE =" first-order lag element"
AUTHOR : AUT_1
FAMILY : MODCONT
NAME : LAG1ST
VERSION : " 1.0"
// reverse by komatic
(*
1 . .
*)
VAR_INPUT
INV : REAL ; //
TM_LAG : TIME := T#25S; //
DF_OUTV : REAL ; //
TRACK : BOOL ; // OUTV = INV
DFOUT_ON : BOOL ; //
COM_RST : BOOL ; //
CYCLE : TIME := T#1S; //
END_VAR
VAR_OUTPUT
OUTV : REAL ; //
END_VAR
VAR
sRueck : REAL ;
sRest : REAL ;
END_VAR
VAR_TEMP
rTmLag : REAL ; // real
rCycle : REAL ; // real
OutvNew : REAL ; //
RueckAlt : REAL ; //Alter Rckkopplungswert
Hvar : REAL ; //
RueckDiff : REAL ; //Rckkopplungsdifferenz
END_VAR
BEGIN
IF COM_RST
THEN //
sRest:=0.0;
IF DFOUT_ON
THEN //
OutvNew:=DF_OUTV;
sRueck:=DF_OUTV;
ELSE //
OutvNew:=0.0;
sRueck:=0.0;
END_IF;
ELSE
IF DFOUT_ON
THEN //
OutvNew:=DF_OUTV;
sRueck:=DF_OUTV;
ELSE
IF TRACK
THEN //
OutvNew:=INV;
sRueck:=INV;
sRest:=0.0;
ELSE //
rCycle:=DINT_TO_REAL(TIME_TO_DINT(CYCLE));
// real
rTmLag:=DINT_TO_REAL(TIME_TO_DINT(TM_LAG));
// real
//
IF rTmLag < rCycle * 0.5 THEN rTmLag:=rCycle * 0.5; END_IF;
RueckAlt:=sRueck;
Hvar:=rCycle /( 2.0 * rTmLag);
Hvar:= (INV - RueckAlt) * Hvar / (1.0 + Hvar);
OutvNew:=Hvar+RueckAlt;
RueckDiff:=2.0 * Hvar + sRest;
sRueck:=RueckDiff + RueckAlt;
sRest:=RueckAlt - sRueck + RueckDiff;
END_IF;
END_IF;
END_IF;
OUTV:=OutvNew;
END_FUNCTION_BLOCK

,





: 5493

.

:

(4000 max):

: