Âåðñèÿ äëÿ ïå÷àòè

Modular PID Control ÷òî âíóòðè? ×àñòü 4.

Äàòà: 2009-04-02

Äîáàâëåíî: komatic

Òåìà: ModPID



MODPID

Ñîäåðæàíèå
1.PID ÏÈÄ ðåãóëÿòîð.
2.LMNGEN_C ÏÈÄ-ðåãóëÿòîð íåïðåðûâíîãî äåéñòâèÿ (àíàëîãîâûé).
3.LMNGEN_S Áëîê èñïîëüçóåòñÿ â ñòðóêòóðàõ ÏÈÄ-ðåãóëÿòîðîâ ïîøàãîâîãîóïðàâëåíèÿ.

×òîáû íå ïîâòîðÿòü ïîäðîáíîå îïèñàíèå ýòèõ ôóíêöèé â ðàçäåëå download âû ìîæåòå çàãóðçèòü îôèöèàëüíóþ äîêóìåíòàöèþ íà ðóññêîì è àíãëèéñêîì ÿçûêå, ïåðåéòè.

ÏÈÄ ðåãóëÿòîð.

FUNCTION_BLOCK FB119
TITLE =" output PID-algorithm"
AUTHOR : AUT_1
FAMILY : MODCONT
NAME : PID
VERSION : " 1.2"
// reverse by komatic
(*
Áëîê PID ñîäåðæèò ÏÈÄ-àëãîðèòìû è èñïîëüçóåòñÿ äëÿ ñîçäàíèÿ
ðåãóëÿòîðîâ ñëåäóþùèõ òèïîâ:
ÏÈÄ-ðåãóëÿòîð íåïðåðûâíîãî óïðàâëåíèÿ:
Áëîêè: PID + LMNGEN_C
Èìïóëüñíûé ÏÈÄ-ðåãóëÿòîð äëÿ ïðîïîðöèîíàëüíûõ ïðèâîäîâ:
Áëîêè: PID + LMNGEN_C + PULSEGEN
ÏÈÄ-ðåãóëÿòîð ïîøàãîâîãî óïðàâëåíèÿ äëÿ ïðîïîðöèîíàëüíûõ
ïðèâîäîâ:
Áëîêè: PID + LMNGEN_S
Áëîê îñóùåñòâëÿåò PID àëãîðèòì îáðàáîòêè âõîäíîãî ñèãíàëà.
Áëîê êîíñòðóêòèâíî è ôóíêöèîíàëüíî ïðåäñòàâëÿåò ñîáîé
ïàðàëëåëüíóþ ñòðóêòóðó è ôóíêöèîíèðóåò èñêëþ÷èòåëüíî êàê
àëãîðèòì ïîçèöèîíèðîâàíèÿ. Êîìïîíåíòû Ï-, È- è Ä-,
ïðåäíàçíà÷åííûå äëÿ îáðàáîòêè âõîäíîãî ñèãíàëà, ìîãóò áûòü
àêòèâèçèðîâàíû èëè âûêëþ÷åíû â èíäèâèäóàëüíîì ïîðÿäêå. Ýòî
ïîçâîëÿåò êîíôèãóðèðîâàòü Ï-, ÏÈ-, ÏÄ- è ÏÈÄ- ðåãóëÿòîðû íà
îñíîâå ïðîãðàììíîãî ïðîäóêòà Modular Control (Ìîäóëüíîå
óïðàâëåíèå).
Êîìïîíåíòû Ï- è Ä- ìîãóò áûòü òàêæå ââåäåíû â öåïü îáðàòíîé
ñâÿçè. Ïîìåùàÿ êîìïîíåíòû Ï- è Ä- â öåïè îáðàòíîé ñâÿçè
ðåãóëÿòîðà, ìîæíî ïðåäîòâðàòèòü ñêà÷êîîáðàçíûå èçìåíåíèÿ
ñèãíàëà. Ïðè ýòîì îáû÷íî íåò íåîáõîäèìîñòè èñïîëüçîâàòü
èíòåãðàòîð â öåïè óñòàâêè (setpoint), ÷òîáû èçáåæàòü ñòóïåí÷àòûõ
èçìåíåíèé óðîâíÿ ñèãíàëà.
 òî âðåìÿ êàê áëîê PID âûçûâàåòñÿ â ïðèîðèòåòíîì êëàññå
öèêëè÷åñêèõ ïðåðûâàíèé, ïåðèîä êîòîðîãî ïðèâÿçàí ê
äîìèíèðóþùåé ïîñòîÿííîé âðåìåíè ñèñòåìû, áëîêè îáðàáîòêè
ñèãíàëîâ äëÿ ïðèâîäà (LMNGEN_C è LMNGEN_S) ìîãóò
âûçûâàòüñÿ â ïðèîðèòåòíîì êëàññå öèêëè÷åñêèõ ïðåðûâàíèé ñ
ìåíüøèì ïåðèîäîì.
*)
VAR_INPUT
  ER            : REAL ;                    //ñèãíàë îøèáêè
  PV            : REAL ;                    //âõîäíàÿ ïåðåìåííàÿ
  GAIN          : REAL  := 1.000000e+000;   //êôò ïðîïîðöèîíàëüíîñòè
  TI            : TIME  := T#20S;           //âðèìÿ èíòåãðèðîâàíèÿ
  I_ITLVAL      : REAL ;                    //çíà÷åíèå èíèöèàëèçàöèè äëÿ èíòåãðàëüíîé ñîñòàâëÿþùåé
  TD            : TIME  := T#10S;           //âðåìÿ äèôåðåíöèðîâàíèÿ
  TM_LAG        : TIME  := T#2S;            //âðåìÿ çàäåðæêè äèôåðåíöèàëüíîé ñîñòàâëÿþùåé
  DISV          : REAL ;                    //ñèãíàë ðàññîãëàñîâàíèÿ
  P_SEL         : BOOL  := TRUE;            //âûáîð ïðîïîðöèîíàëüíîé ñîñòàâëÿþùåé
  PFDB_SEL      : BOOL ;                    //proportional action in feedback path selected
  DFDB_SEL      : BOOL ;                    //derivative action in feedback path on
  I_SEL         : BOOL  := TRUE;            //âûáîð èíòåãðàëüíîé ñîñòàâëÿþùåé
  INT_HOLD      : BOOL ;                    //óäåðæèâàíèå èíòåãðàëüíîé ñîñòàâëÿþùåé
  I_ITL_ON      : BOOL ;                    //èíèöèàëèçèðîâàòü èíòåãðàëüíóþ ñîñòàâëÿþùóþ
  D_SEL         : BOOL ;                    //âûáîð äèôåðåíöèàëüíîé ñîñòàâëÿþùåé
  DISV_SEL      : BOOL  := TRUE;            //âûáîð ïåðåìåííîé ðàññîãëàñîâàíèÿ
  COM_RST       : BOOL ;                    //ïîëíûé ðåñòàðò
  CYCLE         : TIME  := T#1S;            //âðåìÿ âûïîëíåíèÿ
  LMNG_PID : STRUCT    
   LMN          : REAL ;                    //âûõîäíîå çíà÷åíèå
   LMN_HLM      : REAL ;                    //âåðõíÿÿ ãðàíèöà äëÿ âûõîäà
   LMN_LLM      : REAL ;                    //íèæíÿÿ ãðàíèöà äëÿ âûõîäà
   R_MTR_TM     : REAL ;                    //motor manipulated value
   ARWHL_ON     : BOOL ;                    //anti reset wind-up in high limit on
   ARWLL_ON     : BOOL ;                    //anti reset wind-up in low limit on
   MAN_ON       : BOOL ;                    //manual mode on
   LMNGS_ON     : BOOL ;                    //PID-algorithm for step controller on
   LMNR_ON      : BOOL ;                    //repeated manipulated value on
  END_STRUCT ;   
END_VAR
VAR_OUTPUT
  LMN_P         : REAL ;                    //ïðîïîðöèîíàëüíàÿ ñîñòàâëÿþùàÿ
  LMN_I         : REAL ;                    //èíòåãðàëüíàÿ ñîñòàâëÿþùàÿ
  LMN_D         : REAL ;                    //äèôåðåíöèàëüíàÿ ñîñòàâëÿþùàÿ
  PID_LMNG : STRUCT    
   PID_OUTV     : REAL ;                    //PID output variable
   PID_SCTR     : REAL ;                    //PID output variable for step controller
  END_STRUCT ;   
END_VAR
VAR
  sInvAlt       : REAL ;   
  sIanteilAlt   : REAL ;   
  sRestInt      : REAL ;   
  sRestDif      : REAL ;   
  sRueck        : REAL ;   
  sbILimOn      : BOOL  := TRUE;   
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
  PidSctr       : REAL ;                    //PID-Ausgangswert für Schrittregler
  rLmnHlm       : REAL ;                    //Obere Begrenzung
  rLmnLlm       : REAL ;                    //Untere Begrenzung
  rMtrTm        : REAL ;                    //Motorstellzeit
  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
END_VAR
BEGIN
IF COM_RST
THEN
    ErKp:=0.0;
    Panteil:=0.0;
    Ianteil:=0.0;
    sRestInt:=0.0;
    Danteil:=0.0;
    sRueck:=0.0;
    sRestDif:=0.0;
    sInvAlt:=0.0;
    sIanteilAlt:=0.0;
    sRestInt:=0.0;
    sRestDif:=0.0;
    PidOutv:=0.0;
    PidSctr:=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;
    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;
    IF P_SEL
    THEN
        IF PFDB_SEL
        THEN
            Panteil:=(-PV)*GAIN;
        ELSE
            Panteil:=ErKp;
        END_IF;
    ELSE
        Panteil:=0.0;
    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 ((NOT bLmngsOn) AND I_SEL) OR (I_SEL AND bLmngsOn AND bLmnrOn)
    THEN
        IF I_ITL_ON
        THEN
            Ianteil:=I_ITLVAL;
            sRestInt:=0.0;
        ELSE
            IF bManOn
            THEN
                IF bLmngsOn
                THEN
                    Ianteil:=dLmn;
                ELSE
                    Ianteil:=dLmn-Panteil-dDisv;
                END_IF;
                sRestInt:=0.0;
            ELSE
                Diff:=rCycle/rTi*(ErKp+sInvAlt)*0.5+sRestInt;
                IF  (Diff > 0.0 AND bArwhlOn OR INT_HOLD) OR (Diff < 0.0 AND bArwllOn)
                THEN
                    Diff:=0.0;
                END_IF;
                Ianteil:=sIanteilAlt+Diff;
                sRestInt:=sIanteilAlt-Ianteil+Diff;
            END_IF;
        END_IF;
    ELSE    
        Ianteil:=0.0;
        sRestInt:=0.0;
    END_IF;
    IF (NOT bLmnrOn) AND bLmngsOn
    THEN
        PidSctr:=ErKp/rTi;
    ELSE
        PidSctr:=Ianteil;
    END_IF;
    IF DFDB_SEL
    THEN
        Diff:=(-PV)*GAIN;
    ELSE
        Diff:=ErKp;
    END_IF;
    IF (NOT LMNG_PID.MAN_ON) 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;
        sRueck:=Diff;
    END_IF;
    PidOutv:=Panteil+Ianteil+Danteil+dDisv;
END_IF
    LMN_P:=Panteil;
    LMN_I:=Ianteil;
    LMN_D:=Danteil;
    sInvAlt:=ErKp;
    sIanteilAlt:=Ianteil;
    PID_LMNG.PID_OUTV:=PidOutv;
    PID_LMNG.PID_SCTR:=PidSctr;
END_FUNCTION_BLOCK

ÏÈÄ-ðåãóëÿòîð íåïðåðûâíîãî äåéñòâèÿ (àíàëîãîâûé).

FUNCTION_BLOCK FB113
TITLE =" output continuous PID controller"
AUTHOR : AUT_1
FAMILY : MODCONT
NAME : LMNGEN_C
VERSION : " 1.1"
// reverse by dda
(*
Áëîê èñïîëüçóåòñÿ â ñòðóêòóðàõ ÏÈÄ-ðåãóëÿòîðîâ íåïðåðûâíîãî
óïðàâëåíèÿ. Îí ñîäåðæèò ñõåìó ôîðìèðîâàíèÿ óïðàâëÿþùåé
ïåðåìåííîé ðåãóëÿòîðà.
Áëîê ñîäåðæèò ïåðåêëþ÷àòåëü ðåæèìîâ ðàáîòû ("Ðó÷íîé"/
"Àâòîìàòè÷åñêèé").  ðó÷íîì ðåæèìå Âû ìîæåòå îïðåäåëÿòü
àáñîëþòíîå çíà÷åíèå, óìåíüøàòü èëè óâåëè÷èâàòü çíà÷åíèå
óïðàâëÿþùåãî ñèãíàëà ñ ïîìîùüþ êëþ÷åé.
Óïðàâëÿþùèé ñèãíàë, à òàêæå ñêîðîñòü åãî èçìåíåíèÿ ìîãóò áûòü
îãðàíè÷åíû ãðàíè÷íûìè âåëè÷èíàìè, çàäàííûìè ïîëüçîâàòåëåì.
Äàííûé áëîê âñåãäà èñïîëüçóåòñÿ âìåñòå ñ áëîêîì ÏÈÄ-àëãîðèòìà
ðåãóëÿòîðà.
*)
VAR_INPUT
  MAN           : REAL ;                    //manual value
  LMN_HLM       : REAL  := 1.000000e+002;   //manipulated value high limit
  LMN_LLM       : REAL ;                    //manipulated value low limit
  LMN_URLM      : REAL  := 1.000000e+001;   //manipulated value up rate limit
  LMN_DRLM      : REAL  := 1.000000e+001;   //manipulated down rate limit
  DF_OUTV       : REAL ;                    //default output variable
  MAN_ON        : BOOL  := TRUE;            //manual value on
  MANGN_ON      : BOOL ;                    //manual value generating on
  MANUP         : BOOL ;                    //manual value up
  MANDN         : BOOL ;                    //manual value down
  LMNRC_ON      : BOOL ;                    //manipulated value rate of change on
  DFOUT_ON      : BOOL ;                    //default output variable on
  COM_RST       : BOOL ;                    //complete restart
  CYCLE         : TIME  := T#1S;            //sample time
  PID_LMNG  : STRUCT   
   PID_OUTV     : REAL ;                    //PID output variable
   PID_SCTR     : REAL ;                    //PID output variable for step controller
  END_STRUCT ;   
END_VAR
VAR_OUTPUT
  LMN           : REAL ;                    //manipulated value
  QLMN_HLM      : BOOL ;                    //high limit of manipulated value reached
  QLMN_LLM      : BOOL ;                    //low limit of manipulated value reached
  LMNG_PID  : STRUCT    
   LMN          : REAL ;                    //manipulated value
   LMN_HLM      : REAL ;                    //manipulated value high limit
   LMN_LLM      : REAL ;                    //manipulated value low limit
   R_MTR_TM     : REAL ;                    //motor manipulated value
   ARWHL_ON     : BOOL ;                    //anti reset wind-up in high limit on
   ARWLL_ON     : BOOL ;                    //anti reset wind-up in low limit on
   MAN_ON       : BOOL ;                    //manual mode on
   LMNGS_ON     : BOOL ;                    //PID-algorithm for step controller on
   LMNR_ON      : BOOL ;                    //repeated manipulated value on
  END_STRUCT ;   
END_VAR
VAR
  MP1           : REAL ;                    //MP1: manipulated value
  LMN_OP        : REAL ;                    //manipulated value operation
  LMNOP_ON      : BOOL ;                    //manipulated value operation on
  stUpMan       : TIME ;   
  stDownMan     : TIME ;   
END_VAR
VAR_TEMP
  Hvar          : REAL ;                    //Hilfsvariable
  rCycle        : REAL ;                    //Abtastzeit in real
  Pid_Outv      : REAL ;                    //PID output variable
  dLmn          : REAL ;                    //Stellwert
  bArwhlOn      : BOOL ;                    //Anti Reset Wind-up high limit Bit für Struktur PID_LMNG
  bArwllOn      : BOOL ;                    //Anti Reset Wind-up low limit Bit für Struktur PID_LMNG
END_VAR
BEGIN
bArwhlOn:=0;
bArwllOn:=0;
rCycle:=DINT_TO_REAL(TIME_TO_DINT(CYCLE))/1000.0;
IF COM_RST OR DFOUT_ON
THEN
    dLmn:=DF_OUTV;
    MP1:=0.0;
    stUpMan:=T#0MS;
    stDownMan:=T#0MS;
    IF COM_RST
    THEN
        LMN:=DF_OUTV;
    END_IF
ELSE
    Pid_Outv:=PID_LMNG.PID_OUTV;
    IF MAN_ON
    THEN
        IF MANGN_ON
        THEN 
            IF NOT (MANUP OR QLMN_LLM) AND MANDN
            THEN
                stUpMan:=T#0MS;
                stDownMan:=stDownMan+CYCLE;
                IF stDownMan > T#3S
                THEN
                    dLmn:=LMN-((LMN_HLM-LMN_LLM)*rCycle/10.0);
                ELSE
                    dLmn:=LMN-((LMN_HLM-LMN_LLM)*rCycle/100.0);
                END_IF;
            ELSE
                IF NOT (MANDN OR QLMN_HLM) AND MANUP
                THEN
                    stDownMan:=T#0MS;
                    stUpMan:=stUpMan+CYCLE;
                    IF stUpMan > T#3S
                    THEN
                        dLmn:=LMN+((LMN_HLM-LMN_LLM)*rCycle/10.0);
                    ELSE
                        dLmn:=LMN+((LMN_HLM-LMN_LLM)*rCycle/100.0);
                    END_IF;
                ELSE
                    stUpMan:=T#0S;
                    stDownMan:=T#0S;
                    dLmn:=LMN;                   
                END_IF
            END_IF;
            IF dLmn > LMN_HLM
            THEN
                dLmn:=LMN_HLM;
            ELSE
                IF dLmn < LMN_LLM
                THEN
                    dLmn:=LMN_LLM;
                END_IF;
            END_IF;
        ELSE
            dLmn:=MAN;
            stUpMan:=T#0MS;
            stDownMan:=T#0MS;
        END_IF;
    ELSE
        dLmn:=Pid_Outv;
        stUpMan:=T#0MS;
        stDownMan:=T#0MS;
    END_IF;
MP1:= dLmn;
IF LMNOP_ON THEN dLmn:=LMN_OP; END_IF;              
END_IF;
//-----------------------------------
IF LMNRC_ON
THEN
    IF LMN < 0.0
    THEN
        IF LMN > dLmn
        THEN
            Hvar:=LMN - (LMN_URLM*rCycle);
            IF dLmn < Hvar
            THEN
                dLmn:=Hvar;
                bArwllOn:=1;
            END_IF;
        ELSE     
            IF LMN_DRLM=0.0
            THEN
                dLmn:=LMN;
                bArwhlOn:=1;
            ELSE
                IF dLmn<=0.0
                THEN
                    Hvar:=LMN_DRLM*rCycle + LMN;
                    IF dLmn > Hvar
                    THEN
                        dLmn:=Hvar;
                        bArwhlOn:=1;
                    END_IF;
                ELSE
                    Hvar:=(-LMN)/LMN_DRLM;
                    IF Hvar <= rCycle
                    THEN
                        Hvar:=(rCycle-Hvar)*LMN_URLM;
                        IF dLmn > Hvar
                        THEN
                            dLmn:=Hvar;
                            bArwhlOn:=1;
                        END_IF;
                    ELSE
                        dLmn:= rCycle*LMN_DRLM+LMN;
                        bArwhlOn:=1;
                    END_IF;
                END_IF;   
            END_IF;
        END_IF;
      ELSE   
//-------------------
            IF LMN<dLmn
            THEN
                Hvar:= LMN_URLM*rCycle + LMN;
                IF dLmn>Hvar
                THEN
                    dLmn:=Hvar;
                    bArwhlOn:=1;
                END_IF;
            ELSE
                IF LMN_DRLM=0.0
                THEN
                    dLmn:=LMN;
                    bArwllOn:=1;
                ELSE     
                    IF dLmn>=0.0
                    THEN
                        Hvar:=LMN-(LMN_DRLM*rCycle );
                        IF dLmn<Hvar
                        THEN
                            dLmn:=Hvar;
                            bArwllOn:=1;
                        END_IF;
                    ELSE
                        Hvar:=LMN/LMN_DRLM;
                        IF Hvar<=rCycle
                        THEN
                            Hvar:=(-(rCycle-Hvar))*LMN_URLM;
                            IF dLmn<Hvar
                            THEN
                                dLmn:=Hvar;
                                bArwllOn:=1;
                            END_IF;
                        ELSE
                            dLmn:=LMN-(rCycle*LMN_DRLM);
                            bArwllOn:=1;
                        END_IF;
                    END_IF;
               END_IF
          END_IF;
    END_IF;
END_IF;
//-------------------------------
IF dLmn>=LMN_HLM
THEN
    QLMN_HLM:=1;
    QLMN_LLM:=0;
    dLmn:=LMN_HLM;
    bArwhlOn:=1;
ELSE
    QLMN_HLM:=0;
    IF dLmn<=LMN_LLM
    THEN
        QLMN_LLM:=1;
        dLmn:=LMN_LLM;
        bArwllOn:=1;
    ELSE
        QLMN_LLM:=0;
    END_IF;
END_IF;
LMN:=dLmn;
LMNG_PID.LMN_HLM:=LMN_HLM;
LMNG_PID.LMN_LLM:=LMN_LLM;
LMNG_PID.LMN:=dLmn;
LMNG_PID.ARWHL_ON:=bArwhlOn;
LMNG_PID.ARWLL_ON:=bArwllOn;
LMNG_PID.MAN_ON:=MAN_ON OR LMNOP_ON;
LMNG_PID.LMNGS_ON:=0;
LMNG_PID.LMNR_ON:=0;
END_FUNCTION_BLOCK

Øàãîâûé ÏÈÄ-ðåãóëÿòîð. Ñîäåðæèò êîìïîíåíòû äëÿ ïîñòðîåíèÿ øàãîâîãî ðåãóëÿòîðà. Îí äîëæåí èñïîëüçîâàòüñÿ ñîâìåñòíî ñ ôóíêöèîíàëüíûì áëîêîì ÏÈÄ àëãîðèòìà.

FUNCTION_BLOCK FB114
TITLE =" output PID step controller"
AUTHOR : AUT_1
FAMILY : MODCONT
NAME : LMNGEN_S
VERSION : " 1.2"
// reverse by dda
(*
Áëîê èñïîëüçóåòñÿ â ñòðóêòóðàõ ÏÈÄ-ðåãóëÿòîðîâ ïîøàãîâîãî
óïðàâëåíèÿ ñ ïðèâîäàìè, èìåþùèìè èíòåãðèðóþùèé êîìïîíåíò
(íàïðèìåð, âåíòèëü, óïðàâëÿåìûé ýëåêòðîäâèãàòåëåì). Áëîê
ñîäåðæèò ñõåìó ôîðìèðîâàíèÿ óïðàâëÿþùåé ïåðåìåííîé
ðåãóëÿòîðà. Ðåãóëÿòîð ïîøàãîâîãî óïðàâëåíèÿ ìîæåò ðàáîòàòü êàê
ñ ñèãíàëîì ïîçèöèîííîé îáðàòíîé ñâÿçè, òàê è áåç íåãî.
*)
VAR_INPUT
  MAN           : REAL ;                    //manual value
  LMN_HLM       : REAL  := 1.000000e+002;   //manipulated value high limit
  LMN_LLM       : REAL ;                    //manipulated value low limit
  LMNR_IN       : REAL ;                    //repeated manipulated value
  MTR_TM        : TIME  := T#30S;           //motor manipulated value
  PULSE_TM      : TIME  := T#3S;            //minimum pulse time
  BREAK_TM      : TIME  := T#3S;            //minimum break time
  MAN_ON        : BOOL ;                    //manual value on
  MANGN_ON      : BOOL ;                    //manual value generating on
  MANUP         : BOOL ;                    //manual value up
  MANDN         : BOOL ;                    //manual value down
  LMNR_ON       : BOOL ;                    //repeated manipulated value on
  LMNR_HS       : BOOL ;                    //high limit signal of repeated manipulated value
  LMNR_LS       : BOOL ;                    //low limit signal of repeated manipulated value
  LMNS_ON       : BOOL  := TRUE;            //manipulated signals on
  LMNUP         : BOOL ;                    //manipulated signals up
  LMNDN         : BOOL ;                    //manipulated signals down
  COM_RST       : BOOL ;                    //complete restart
  CYCLE         : TIME  := T#1S;            //sample time
  PID_LMNG  : STRUCT    
   PID_OUTV     : REAL ;                    //PID output variable
   PID_SCTR     : REAL ;                    //PID output variable for step controller
  END_STRUCT ;   
END_VAR
VAR_OUTPUT
  LMN           : REAL ;                    //manipulated value
  QLMNUP        : BOOL ;                    //manipulated signal up
  QLMNDN        : BOOL ;                    //manipulated signal down
  QLMN_HLM      : BOOL ;                    //high limit of manipulated value reached
  QLMN_LLM      : BOOL ;                    //low limit of manipulated value reached
  LMNG_PID  : STRUCT    
   LMN          : REAL ;                    //manipulated value
   LMN_HLM      : REAL ;                    //manipulated value high limit
   LMN_LLM      : REAL ;                    //manipulated value low limit
   R_MTR_TM     : REAL ;                    //motor manipulated value
   ARWHL_ON     : BOOL ;                    //anti reset wind-up in high limit on
   ARWLL_ON     : BOOL ;                    //anti reset wind-up in low limit on
   MAN_ON       : BOOL ;                    //manual mode on
   LMNGS_ON     : BOOL ;                    //PID-algorithm for step controller on
   LMNR_ON      : BOOL ;                    //repeated manipulated value on
  END_STRUCT ;   
END_VAR
VAR
  LMNSOPON      : BOOL ;                    //manipulated signal operation on
  LMNUP_OP      : BOOL ;                    //manipulated signal up operation
  LMNDN_OP      : BOOL ;                    //manipulated signal down operation
  LMNOP_ON      : BOOL ;                    //manipulated value operation on
  LMNRS_ON      : BOOL ;                    //simulation of the repeated manipulated value on
  MP1           : REAL ;                    //MP1: manipulated value
  LMN_OP        : REAL ;                    //manipulated value operation
  LMNRSVAL      : REAL ;                    //repeated manipulated start value in simulation
  LMNR_SIM      : REAL ;                    //repeated manipulated value simulated
  stUpMan       : TIME ;   
  stDownMan     : TIME ;   
  siImpAus      : INT ;   
  stImpDauer    : TIME ;   
  stPausDauer   : TIME ;   
  sInt          : REAL ;   
  sThrOn        : REAL ;   
END_VAR
VAR_TEMP
  rPidOutv      : REAL ;                    //PID output variable
  rPidSctr      : REAL ;                    //PID output variable for step controller
  dLmn          : REAL ;                    //Stellwert
  LmnHlm        : REAL ;                    //Stellwert obere Begrenzung
  LmnLlm        : REAL ;                    //Stellwert untere Begrenzung
  Diff          : REAL ;                    //Änderungswert bei der Handwertbedienung
  rCycle        : REAL ;                    //Abtastzeit in real
  AdapIn1       : REAL ;                    //Eingang 1 der Adaption der Ansprechschwelle
  AdapIn2       : REAL ;                    //Eingang 2 der Adaption der Ansprechschwelle
  ThreeStepIn   : REAL ;                    //Eingang des Dreipunktgliedes
  iImpEin       : INT ;                     //Eingang des Impulsformers
  rMtrTm        : REAL ;                    //Motorstellzeit in real
  rMinThrOn     : REAL ;                    //Hilfsvariable
  rThrOff       : REAL ;                    //Abschaltschwelle
  IntIn         : REAL ;                    //Eingang des Integrierers in der Rückführung
  LmnrSim       : REAL ;                    //simulierte Stellungsrückmeldung
  bArwHLmOn     : BOOL ;                    //Anti Reset Wind-up Bit obere Grenze für Struktur PID_LMNG
  bArwLLmOn     : BOOL ;                    //Anti Reset Wind-up Bit untere Grenze für Struktur PID_LMNG
END_VAR
BEGIN
bArwHLmOn:=LMNR_HS;
bArwLLmOn:=LMNR_LS;
rMtrTm:=DINT_TO_REAL(TIME_TO_DINT(MTR_TM))/1000.0;
IF COM_RST
THEN
    LMN:=0.0;
    QLMNUP:=0;
    QLMNDN:=0;
    QLMN_HLM:=0;
    QLMN_LLM:=0;
    LMNR_SIM:=LMNRSVAL;
    LMNRS_ON:=0;
    MP1:=0.0;
    stUpMan:=T#0MS;
    stDownMan:=T#0MS;
    siImpAus:=0;
    stImpDauer:=T#0MS;
    stPausDauer:=T#0MS;
    sInt:=0.0;
    sThrOn:=0.0;
ELSE
    rPidOutv:=PID_LMNG.PID_OUTV;
    rPidSctr:=PID_LMNG.PID_SCTR;
    rCycle:=DINT_TO_REAL(TIME_TO_DINT(CYCLE))/1000.0;
    IF LMNR_ON
    THEN
        IF MAN_ON
        THEN
            IF MANGN_ON
            THEN
                IF NOT (MANUP OR QLMN_LLM) AND MANDN
                THEN
                    stUpMan:=T#0MS;
                    stDownMan:=stDownMan+CYCLE;
                    IF stDownMan > T#3S
                    THEN
                        dLmn:=LMN-((LMN_HLM-LMN_LLM)*rCycle/10.0);
                    ELSE
                        dLmn:=LMN-((LMN_HLM-LMN_LLM)*rCycle/100.0);
                    END_IF;
                ELSE
                    IF NOT (MANDN OR QLMN_HLM) AND MANUP
                    THEN
                        stDownMan:=T#0MS;
                        stUpMan:=stUpMan+CYCLE;
                        IF stUpMan>T#3S
                        THEN
                            dLmn:=LMN+((LMN_HLM-LMN_LLM)*rCycle/10.0);
                        ELSE
                            dLmn:=LMN+((LMN_HLM-LMN_LLM)*rCycle/100.0);
                        END_IF;   
             ELSE
                        stUpMan:=T#0MS;
                        stDownMan:=T#0MS;
                        dLmn:=LMN;
                    END_IF;
                END_IF;
                IF dLmn > LMN_HLM
                THEN
                    dLmn:=LMN_HLM;
                ELSE
                    IF dLmn < LMN_LLM
                    THEN
                        dLmn:=LMN_LLM;
                    END_IF;
                END_IF;
            ELSE
                dLmn:=MAN;
                stUpMan:=T#0MS;
                stDownMan:=T#0MS;
            END_IF;
        ELSE
            dLmn:=rPidOutv;
            stUpMan:=T#0MS;
            stDownMan:=T#0MS;
        END_IF;
        MP1:=dLmn;
        IF LMNOP_ON THEN dLmn:=LMN_OP; END_IF;
        IF dLmn>=LMN_HLM
        THEN
            QLMN_HLM:=1;
            QLMN_LLM:=0;
            dLmn:=LMN_HLM;
            IF LMNR_IN >= dLmn THEN bArwHLmOn:=1; END_IF;
        ELSE
            QLMN_HLM:=0;
            IF dLmn <= LMN_LLM
            THEN
                QLMN_LLM:=1;
                dLmn:=LMN_LLM;
                IF LMNR_IN <= dLmn THEN bArwLLmOn:=1; END_IF;
            ELSE
                QLMN_LLM:=0;
            END_IF;
        END_IF;
        sInt:=0.0;
        ThreeStepIn:=dLmn-LMNR_IN;
        AdapIn1:=dLmn-rPidSctr;
        AdapIn2:=LMNR_IN-rPidSctr;
    ELSE
        LmnHlm:=100.0;
        LmnLlm:=-100.0;
        IF LMNS_ON
        THEN
            sInt:=0.0;
        ELSE
            IF siImpAus <> 0
            THEN
                IntIn:=DINT_TO_REAL(INT_TO_DINT(siImpAus))*rCycle/rMtrTm;
            ELSE
                IF ((rPidSctr > 0.0) AND bArwHLmOn) OR ((rPidSctr < 0.0) AND  bArwLLmOn)
                THEN
                    IntIn:=0.0;
   ELSE
                    IntIn:=(-rPidSctr)*rCycle;
                END_IF;
            END_IF;
            sInt:=sInt+IntIn;
        END_IF;
        stUpMan:=T#0MS;
        stDownMan:=T#0MS;
        QLMN_HLM:=0;
        QLMN_LLM:=0;
        dLmn:=0.0;
        MP1:=0.0;
        ThreeStepIn:=rPidOutv-sInt;
        AdapIn1:=rPidOutv;
        AdapIn2:=sInt;
    END_IF;
    rThrOff:=55.0/rMtrTm*rCycle;
    IF PULSE_TM>CYCLE
    THEN
        rMinThrOn:=DINT_TO_REAL(TIME_TO_DINT(PULSE_TM))/1000.0;
    ELSE
        rMinThrOn:=rCycle;
    END_IF;
    rMinThrOn:=100.0*rMinThrOn/rMtrTm;
    IF NOT (((MAN_ON OR LMNOP_ON OR QLMN_HLM OR QLMN_LLM) AND LMNR_ON) OR LMNR_HS OR LMNR_LS)
    THEN
        IF NOT (QLMNUP OR QLMNDN)
        THEN
            AdapIn1:=ABS(AdapIn1);
            AdapIn2:=ABS(AdapIn2);
            IF AdapIn1 < AdapIn2
            THEN
                sThrOn:=AdapIn1;
            ELSE
                sThrOn:=AdapIn2;
            END_IF;
            IF sThrOn>10.0      THEN sThrOn:=10.0;      END_IF;
            IF sThrOn<rMinThrOn THEN sThrOn:=rMinThrOn; END_IF;
        END_IF;       
    ELSE           
        sThrOn:=rMinThrOn;          
    END_IF;       
   IF ((siImpAus=100) AND (ThreeStepIn>rThrOff)) OR (ThreeStepIn>=sThrOn)
    THEN
        iImpEin:=100;
    ELSE
        IF ((siImpAus=-100) AND (ThreeStepIn<-rThrOff)) OR (ThreeStepIn<=-sThrOn)
        THEN
            iImpEin:=-100;
        ELSE
            iImpEin:=0;
        END_IF;
    END_IF;
    IF LMNS_ON
    THEN
        IF LMNUP XOR LMNDN
        THEN
            IF LMNUP
            THEN
                iImpEin:=100;
            ELSE
                iImpEin:=-100;
            END_IF;
        ELSE
            iImpEin:=0;
        END_IF;
    END_IF;
    IF LMNSOPON
    THEN
        IF LMNUP_OP XOR LMNDN_OP
        THEN
            IF LMNUP_OP
            THEN
                iImpEin:=100;
            ELSE
                iImpEin:=-100;
            END_IF;
        ELSE
            iImpEin:=0;
        END_IF;
    END_IF;
    IF ((iImpEin=100) AND LMNR_HS) OR ((iImpEin=-100) AND LMNR_LS)
    THEN
        iImpEin:=0;
    END_IF;
    IF ((siImpAus=-100) AND (iImpEin=100)) OR ((siImpAus=100) AND (iImpEin=-100))
    THEN
        iImpEin:=0;
    END_IF;
    IF siImpAus<>iImpEin
    THEN
        IF iImpEin=0
        THEN
            IF stImpDauer<=T#0MS
            THEN
                siImpAus:=0;
                stPausDauer:=BREAK_TM;
            END_IF;
        ELSE
            IF stPausDauer<=T#0MS
            THEN
                siImpAus:=iImpEin;
                stImpDauer:=PULSE_TM;
            END_IF;
        END_IF;
    END_IF;
    IF stImpDauer>T#0MS
    THEN
        stImpDauer:=stImpDauer-CYCLE;
    ELSE
        stImpDauer:=T#0MS;
    END_IF;
    IF stPausDauer>T#0MS
    THEN
        stPausDauer:=stPausDauer-CYCLE;
    ELSE
        stPausDauer:=T#0MS;
    END_IF;
    IF ((siImpAus=100) AND LMNR_HS) OR ((siImpAus=-100) AND LMNR_LS)
    THEN
        siImpAus:=0;
        stImpDauer:=T#0MS;
    END_IF;
    IF (NOT LMNRS_ON) OR LMNR_ON
    THEN
        LmnrSim:=LMNRSVAL;
    ELSE
        LmnrSim:=INT_TO_REAL(siImpAus)*rCycle/rMtrTm+LMNR_SIM;
        IF LmnrSim>=100.0
        THEN
            LmnrSim:=100.0;
        ELSE
            IF LmnrSim<=0.0
            THEN
                LmnrSim:=0.0;
            END_IF;     
        END_IF;
    END_IF;
    LMN:=dLmn;
    LMNR_SIM:=LmnrSim;
    IF siImpAus=0
    THEN
        QLMNUP:=0;
        QLMNDN:=0;
    ELSE
        IF siImpAus=100
        THEN
            QLMNUP:=1;
            QLMNDN:=0;
            bArwHLmOn:=1;
        ELSE
            QLMNUP:=0;
            QLMNDN:=1;
            bArwLLmOn:=1;
        END_IF;
    END_IF;
END_IF;
LMNG_PID.LMN:= LMN;
LMNG_PID.LMN_HLM:=LMN_HLM;
LMNG_PID.LMN_LLM:=LMN_LLM;
LMNG_PID.ARWHL_ON:=bArwHLmOn;
LMNG_PID.ARWLL_ON:=bArwLLmOn;
LMNG_PID.R_MTR_TM:=rMtrTm;
LMNG_PID.MAN_ON:=((MAN_ON OR LMNOP_ON) AND LMNR_ON) OR LMNS_ON OR LMNSOPON;
LMNG_PID.LMNGS_ON:=1;
LMNG_PID.LMNR_ON:=LMNR_ON;
END_FUNCTION_BLOCK





Ïðîñìîòðîâ: 9087

Êîììåíòàðèè ê ìàòåðèàëó

Äîáàâëåí: Ñòåëñåð    Äàòà: 2013-02-01

Êòî íèáóäü ïîíèìàåò, ÷òî îçíà÷àåò ýòîò êóñîê êîäà:
Ianteil:=sIanteilAlt+Diff; sRestInt:=sIanteilAlt-Ianteil+Diff;
????

Äîáàâëåí: XHunter    Äàòà: 2015-02-10

À ÷òî òóò íåïîíÿòíîãî: sRestInt:=0; ïðîãðàììåð ïðèêîëîëñÿ.

Äîáàâëåí: denzhig    Äàòà: 2019-02-22

Òàê óõîäÿò îò èñêàæåíèÿ ðåçóëüòàòà ïðè ñëîæåíèè Î×ÅÍÜ áîëüøîãî REAL-îâñêîãî ÷èñëà ñ î÷åíü ìàëåíüêèì.

Äîáàâëåí: serereg    Äàòà: 2019-04-04

"Òàê óõîäÿò îò èñêàæåíèÿ ðåçóëüòàòà ïðè ñëîæåíèè Î×ÅÍÜ áîëüøîãî REAL-îâñêîãî ÷èñëà ñ î÷åíü ìàëåíüêèì."
Ìîæíî ïîïîäðîáíåå?

Äîáàâëåí: Mansun    Äàòà: 2020-06-24

Äðóçüÿ, ïîäñêàæèòå, à â ÷åì ïðèíöèïèàëüíîå îòëè÷èå èñïîëüçîâàíèÿ ñâÿçêè PID+LMNGEN_S ñ âêëþ÷åííûì LMNR îò ÏÈÄ-ðåãóëÿòîðà ñ îáû÷íûì "àíàëîãîâûì" âûõîäîì (òîò æå PID+LMNGEN_C)â ñâÿçêå ñ ïðîãðàììíûì ïîçèöèîíåðîì (ïðåäïîëîæèì, ÷òî òàêîâîé íàïèñàí, êîòîðûé ïðè ïîìîùè äâóõ ðåëå ðåãóëèðóåò ñòåïåíü îòêðûòèÿ êëàïàíà, çàäàííóþ ÏÈÄ, îñíîâûâàÿñü íà äàííûõ ôèäáåêà LMNR_IN)? ß ïîêà òîëüêî çàìåòèë, ÷òî ïðè ðàáîòå PID+LMNGEN_S áëàãîäàðÿ îáìåíó áîëüøèì êîëè÷åñòâîì ïåðåìåííûõ â ñòðóêòóðàõ PID_LMNG è LMNG_PID (îáðàòíàÿ ñâÿçü) âû÷èñëåíèå èíòåãðàëüíîé ñîñòàâëÿþùåé áëîêèðóåòñÿ â òî âðåìÿ,êîãäà QLMNUP èëè QLMNDN = TRUE, à òàêæå ÷òî â íåêîòîðûõ ñëó÷àÿõ "çàãðóáëÿåòñÿ" ïîðîã ñðàáàòûâàíèÿ êîìïàðàòîðà, êîòîðûé ýòè èìïóëüñû ôîðìèðóåò. Ìîæåò áûòü, ýòî è õîðîøî, íî âîò ÷åì? Åñòü æå êó÷à ïðèìåðîâ, êîãäà ïîçèöèîíåð (ñ÷èòàé LMNGEN_S) âñòðîåí â ñàì êëàïàí, è òîãäà îí ïðîñòî ïîëó÷àåò àíàëîãîâûé ñèãíàë îò ÏÈÄ, áåçî âñÿêîé îáðàòíîé ñâÿçè, è òåì íå ìåíåå, êàê-òî âñå ýòî äåëî ðàáîòàåò.  ÷åì òîãäà ïðåèìóùåñòâî òàêîãî ïîäõîäà ñ îáðàòíîé ñâÿçüþ?

Äîáàâèòü êîììåíòàðèé

Âàøå èìÿ:

Òåêñò êîììåíòàðèÿ (4000 max):

Ââåäèòå ñóììó ñ êàðòèíêè: