plc4good.org.ua

Íåïðåðûâíûé ðåãóëÿòîð CONT_C (FB41) ñòàíäàðòíûé áëîê ÏÈÄ ðåãóëÿòîðà Siemens

 ýòîì ìàòåðèàëå ðàññìîòðèì ñòàíäàðòíûé áëîê ÏÈÄ ðåãóëÿòîðà Siemens (CONT_C)
Ëó÷øàÿ äîêóìåíòàöèÿ ê ïðîãðàììíîìó áëîêó - åå èñõîäíûé òåêñò.

Ñêîìïèëèðîâàííûé áëîê èäåíòè÷åí îðèãèíàëüíîìó.

Äîêóìåíòàöèÿ ïî ôóíêöèè:
english - download .pdf 0.3Ìá
ðóññêàÿ - ñêà÷àòü .pdf 0.3Ìá

pid

FUNCTION_BLOCK FB41
TITLE ="Íåïðåðûâíûé PID ðåãóëÿòîð"
AUTHOR : SIMATIC
FAMILY : ICONT
NAME : CONT_C
VERSION : " 1.5"
//reversed by komatic
VAR_INPUT
  COM_RST               : BOOL ;                    //Ïîëíûé ðåñòàðò
  MAN_ON                : BOOL  := TRUE;            //Ðó÷íîé ðåæèì âêëþ÷èòü
  PVPER_ON              : BOOL ;                    //×òåíèå âõîäíîé ïåðåìåííîé ñ ïåðèôåðèè âêëþ÷èòü
  P_SEL                 : BOOL  := TRUE;            //Ïðîïîðöèîíàëüíóþ ñîñòàâëÿþùóþ âêëþ÷èòü
  I_SEL                 : BOOL  := TRUE;            //Èíòåãðàëüíóþ ñîñòàâëÿþùóþ âêëþ÷èòü
  INT_HOLD              : BOOL ;                    //Óäåðæàíèå èíòåãðàëüíîé ñîñòàâëÿþùåé
  I_ITL_ON              : BOOL ;                    //Èíèöèàëèçèðîâàòü èíòåãðàëüíóþ ñîñòàâëÿþùóþ
  D_SEL                 : BOOL ;                    //Äèôôåðåíöèàëüíóþ ñîñòàâëÿþùóþ âêëþ÷èòü
  CYCLE                 : TIME  := T#1S;            //Âðåìÿ âûïîëíåíèÿ áëîêà
  SP_INT                : REAL ;                    //Âíóòðåííåå çàäàíèå
  PV_IN                 : REAL ;                    //Âõîäíàÿ ïåðåìåííàÿ
  PV_PER                : WORD ;                    //Âõîäíàÿ ïåðåìåííàÿ (ïåðèôåðèÿ)
  MAN                   : REAL ;                    //Ðó÷íîé âûõîä
  GAIN                  : REAL  := 2.000000e+000;   //Êîýôôèöèåíò ïðîïîðöèîíàëüíîñòè
  TI                    : TIME  := T#20S;           //Âðåìÿ èíòåãðèðîâàíèÿ
  TD                    : TIME  := T#10S;           //Âðåìÿ äèôôåðåíöèðîâàíèÿ
  TM_LAG                : TIME  := T#2S;            //Âðåìÿ äåéñòâèÿ äèôôåðåíöèàëüíîé ñîñòàâëÿþùåé
  DEADB_W               : REAL ;                    //Øèðèíà çîíû íå÷óâñòâèòåëüíîñòè
  LMN_HLM               : REAL  := 1.000000e+002;   //Âåðõíèé ïðåäåë âûõîäíîãî ñèãíàëà
  LMN_LLM               : REAL ;                    //Íèæíèé ïðåäåë âûõîäíîãî ñèãíàëà
  PV_FAC                : REAL  := 1.000000e+000;   //Êîýôôèöèåíò äëÿ êîððåêòèðîâêè âõîäíîé ïåðåìåííîé (óìíîæåíèå)
  PV_OFF                : REAL ;                    //Êîýôôèöèåíò äëÿ êîððåêòèðîâêè âõîäíîé ïåðåìåííîé (ñëîæåíèå)
  LMN_FAC               : REAL  := 1.000000e+000;   //Êîýôôèöèåíò äëÿ êîððåêòèðîâêè âûõîäíîé ïåðåìåííîé (óìíîæåíèå)
  LMN_OFF               : REAL ;                    //Êîýôôèöèåíò äëÿ êîððåêòèðîâêè âõîäíîé ïåðåìåííîé (ñëîæåíèå)
  I_ITLVAL              : REAL ;                    //Íà÷àëüíîå çíà÷åíèå èíòåãðàëüíîé ñîñòàâëÿþùåé
  DISV                  : REAL ;                    //Âîçìóùàþùàÿ ïåðåìåííàÿ
END_VAR
VAR_OUTPUT
  LMN                   : REAL ;                    //Âûõîäíîå çíà÷åíèå
  LMN_PER               : WORD ;                    //Âûõîäíîå çíà÷åíèå (ïåðåôåðèÿ)
  QLMN_HLM              : BOOL ;                    //Âåðõíèé ïðåäåë âûõîäà äîñòèãíóò
  QLMN_LLM              : BOOL ;                    //Íèæíèé ïðåäåë âûõîäà äîñòèãíóò
  LMN_P                 : REAL ;                    //Ïðîïîðöèîíàëüíàÿ ñîñòàâëÿþùàÿ
  LMN_I                 : REAL ;                    //Èíòåãðàëüíàÿ ñîñòàâëÿþùàÿ
  LMN_D                 : REAL ;                    //Äèôôåðåíöèàëüíàÿ ñîñòàâëÿþùàÿ
  PV                    : REAL ;                    //Âõîäíàÿ ïåðåìåííàÿ
  ER                    : REAL ;                    //Ñèãíàë ðàññîãëàñîâàíèÿ
END_VAR
VAR
  sInvAlt               : REAL ;   
  sIanteilAlt           : REAL ;   
  sRestInt              : REAL ;   
  sRestDif              : REAL ;   
  sRueck                : REAL ;   
  sLmn                  : REAL ;   
  sbArwHLmOn            : BOOL ;                    //Âûõîä äîñòèã ìàêñèìàëüíîãî çíà÷åíèÿ 
  sbArwLLmOn            : BOOL ;                    //Âûõîä äîñòèã ìèíèìàëüíîãî çíà÷åíèÿ
  sbILimOn              : BOOL  := TRUE;   
END_VAR
VAR_TEMP
  Hvar                  : REAL ;                    //Hilfsvariable
  rCycle                : REAL ;                    //Abtastzeit in real
  Diff                  : REAL ;                    //Änderungswert
  Istwert               : REAL ;                    //Istwert
  ErKp                  : REAL ;                    //Âñïîìîãàòåëüíàÿ ïåðåìåííàÿ
  rTi                   : REAL ;                    //Integrationszeit in real
  rTd                   : REAL ;                    //Differentiationszeit in real
  rTmLag                : REAL ;                    //Verzögerungszeit in real
  Panteil               : REAL ;                    //P-Anteil
  Ianteil               : REAL ;                    //I-Anteil
  Danteil               : REAL ;                    //D-Anteil
  Verstaerk             : REAL ;                    //Verstärkung
  RueckDiff             : REAL ;                    //Differenz des Rückkopplungswertes
  RueckAlt              : REAL ;                    //Alter Rückkopplungswert
  dLmn                  : REAL ;                    //Stellwert
  gf                    : REAL ;                    //Hilfwert
  rVal                  : REAL ;                    //Real Hilfsvariable
END_VAR
BEGIN
IF COM_RST                                          //Ïîëíûé ðåñòàðò
THEN
    // Îáíóëåíèå ïåðåìåííûõ
    sIanteilAlt:=I_ITLVAL;
    LMN:=0.0;                                       //Âûõîäíîå çíà÷åíèå
    QLMN_HLM:=0;                                    //Âåðõíèé ïðåäåë âûõîäà äîñòèãíóò
    QLMN_LLM:=0;                                    //Íèæíèé ïðåäåë âûõîäà äîñòèãíóò
    LMN_P:=0.0;                                     //Ïðîïîðöèîíàëüíàÿ ñîñòàâëÿþùàÿ
    LMN_I:=0.0;                                     //Èíòåãðàëüíàÿ ñîñòàâëÿþùàÿ
    LMN_D:=0.0;                                     //Äèôôåðåíöèàëüíàÿ ñîñòàâëÿþùàÿ
    LMN_PER:=0;        //Âûõîäíîå çíà÷åíèå (ïåðèôåðèÿ)
    PV:=0.0;                                        //Âõîäíàÿ ïåðåìåííàÿ
    ER:=0.0;                                        //Ñèãíàë ðàññîãëàñîâàíèÿ
    sInvAlt:=0.0;
    sRestInt:=0.0;
    sRestDif:=0.0;
    sRueck:=0.0;
    sLmn:=0.0;
    sbArwHLmOn:=0;
    sbArwLLmOn:=0;
ELSE
    rCycle:= DINT_TO_REAL(TIME_TO_DINT(CYCLE)) / 1000.0;            //Âðåìÿ âûïîëíåíèÿ áëîêà â ñåêóíäàõ
    Istwert:=INT_TO_REAL(WORD_TO_INT(PV_PER)) * 100.0 / 27648.0;    // Ïîëó÷èëè âõîäíóþ ïåðåìåííóþ îò ïåðèôåðèè (0-2768 â 0-100)
    Istwert:=Istwert * PV_FAC + PV_OFF;                             // Ñêîððåêòèðîâàëè âõîäíóþ ïåðåìåííóþ
    IF NOT PVPER_ON THEN Istwert:=PV_IN; END_IF;                    // Åñëè ïåðèôåðèéíûé âõîä îòêëþ÷åí áåðåì ïåðåìåííóþ èç PV_IN
    PV:= Istwert;                                                   // Âõîäíàÿ ïåðåìåííàÿ
    ErKp:=SP_INT - PV;                                              // Ïîëó÷èëè ðàññîãëàñîâàíèå ìåæäó çàäàíèåì è âõîäîì
    IF     ErKp < (-DEADB_W)     THEN ER:=ErKp+DEADB_W;             // Åñëè ðàññîãëàñîâàíèå áîëüøå çîíû íå÷óâñòâèòåëüíîñòè
    ELSIF  ErKp >   DEADB_W      THEN ER:=ErKp-DEADB_W;             // óìåíüøàåì ðàññîãëàñîâàíèå íà âåëè÷èíó çîíû íå÷óñòâ.
    ELSE                              ER:=0.0;                      // èíà÷å ïðèíèìàåì ðàññîãëàñîâàíèå ðàâíûì íóëþ.
    END_IF;
    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;            // Âðåìÿ äåéñòâèÿ äèô.ñîñòàâëÿþùåé â ñåêóíäàõ
    // Ïðîâåðêà íà äîïóñòèìîñòü âðåìåííûõ íàñòðîåê ðåãóëÿòîðà
    IF rTi < (rCycle * 0.5)     THEN    rTi:=rCycle * 0.5;      END_IF; // Ìèíèìàëüíîå âðåìÿ èíòåãðèðîâàíèÿ - Cycle / 2
    IF rTd < rCycle             THEN    rTd:=rCycle;            END_IF; // Ìèíèìàëüíîå âðåìÿ äèôôåðåíöèðîâàíèÿ - Cycle
    IF rTmLag < rCycle * 0.5    THEN    rTmLag:=rCycle * 0.5;   END_IF; // Ìèíèìàëüíîå âðåìÿ äåéñòâèÿ äèô.ñîñò.- Cycle / 2
    // Âû÷èñëåíèå ïðîïîðöèîíàëüíîé ñîñòàâëÿþùåé
    IF P_SEL
    THEN
        Panteil:=ErKp;                                              // Åñëè âûáðàíà ïðîïîðöèîíàëüíàÿ ñîñòàâëÿþùàÿ
    ELSE
        Panteil:=0.0;
    END_IF;
    //---------------------------------------------------------------------------------------------
    // Âû÷èñëåíèå èíòåãðàëüíîé ñîñòàâëÿþùåé
    //---------------------------------------------------------------------------------------------   
    IF I_SEL                    //Èíòåãðàëüíóþ ñîñòàâëÿþùóþ âêëþ÷èòü
    THEN
        IF I_ITL_ON             //Èíèöèàëèçèðîâàòü èíòåãðàëüíóþ ñîñòàâëÿþùóþ
        THEN
            Ianteil:=I_ITLVAL;
            sRestInt:=0.0;
        ELSE
            IF MAN_ON           //Ðó÷íîé ðåæèì
            THEN
                Ianteil:=sLmn - Panteil - DISV;
                sRestInt:=0.0;
            ELSE                //Àâòîìàòè÷åñêèé ðåæèì
                Diff:=rCycle / rTi *(ErKp + sInvAlt) *  0.5 + sRestInt;
                IF ((Diff>0.0) AND sbArwHLmOn OR INT_HOLD)OR ((Diff<0.0) AND sbArwLLmOn) 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;
    //---------------------------------------------------------------------------------------------
    //Ôîðìèðîâàíèå äèôôåðåíöèàëüíîé ñîñòàâëÿþùåé
    //---------------------------------------------------------------------------------------------   
    Diff:=ErKp;
    IF (NOT 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;
    //---------------------------------------------------------------------------------------------
    //Ôîðìèðîâàíèå âûõîäà
    //---------------------------------------------------------------------------------------------
    dLmn:=Panteil + Ianteil + Danteil + DISV;
    IF MAN_ON           // Åñëè ðó÷íîé ðåæèì
    THEN
        dLmn:=MAN;      // Ðó÷íîé âûõîä
    ELSE
        IF (NOT I_ITL_ON) AND I_SEL
        THEN
            IF (Ianteil > (LMN_HLM - DISV)) AND (dLmn > LMN_HLM) AND ((dLmn - LMN_D)> LMN_HLM)
            THEN
                rVal:=LMN_HLM - DISV;
                gf:=  dLmn - LMN_HLM;
                rVal:=Ianteil - rVal;
                IF  rVal > gf THEN rVal:=gf; END_IF;
                Ianteil:=Ianteil - rVal;
            ELSE
                IF (Ianteil < (LMN_LLM - DISV)) AND (dLmn < LMN_LLM) AND ((dLmn - LMN_D) < LMN_LLM)
                THEN
                    rVal:=LMN_LLM - DISV;
                    gf:=dLmn - LMN_LLM;
                    rVal:=Ianteil - rVal;
                    IF rVal < gf  THEN rVal:=gf; END_IF;
                    Ianteil:=Ianteil - rVal;
                END_IF;   
             END_IF;      
        END_IF;
    END_IF;
    LMN_P:=Panteil;
    LMN_I:=Ianteil;
    LMN_D:=Danteil;
    sInvAlt:=ErKp;
    sIanteilAlt:=Ianteil;
    sbArwHLmOn:=0;
    sbArwLLmOn:=0;
    IF (dLmn >= LMN_HLM)
    THEN
        QLMN_HLM:=1;
        QLMN_LLM:=0;
        dLmn:=LMN_HLM;
        sbArwHLmOn:=1;
    ELSE
        QLMN_HLM:=0;
        IF (dLmn <= LMN_LLM)
        THEN
            QLMN_LLM:=1;
            dLmn:=LMN_LLM;
            sbArwLLmOn:=1;
        ELSE
            QLMN_LLM:=0
        END_IF;
    END_IF;
    sLmn:=dLmn;
    dLmn:=sLmn * LMN_FAC + LMN_OFF;  
    LMN:=dLmn;
    dLmn:=LMN * 2.764800e+002;
    IF dLmn >= 3.251100e+004
    THEN
        dLmn:=3.251100e+004;
    ELSE
        IF dLmn <= -3.251200e+004
        THEN
            dLmn:=-3.251200e+004;
        END_IF;
    END_IF;
    LMN_PER:= INT_TO_WORD(REAL_TO_INT(dLmn));
END_IF;   
END_FUNCTION_BLOCK

Íàçàä