ROC_LIM c ModPID

Промышленные Логические Контроллеры SIMATIC S7-200/300/400
anisimow
Posts: 1
Joined: Thu Jan 03, 2013 10:36 am

ROC_LIM c ModPID

Post by anisimow »

Кому интересно попробовал переписать ROC_LIM c ModPID в SCL язык. Это скорей всего для образовательных целей, потому что он не тестировался должным образом.
ROC_LIM c ModPID в SCL
Show

Code: Select all

FUNCTION_BLOCK FB22
TITLE = ''
AUTHOR : KMA
NAME : Sync_Clk
VERSION : '1.0'


VAR_INPUT
  INV : REAL;
  UPRLM_P: REAL:=1.000000e+001;
  DNRLM_P: REAL:=1.000000e+001;
  UPRLM_N: REAL:=1.000000e+001;
  DNRLM_N: REAL:=1.000000e+001;
  H_LM: REAL:=1.000000e+002;
  L_LM: REAL;
  PV: REAL;
  DF_OUTV: REAL;
  DFOUT_ON: BOOL;
  TRACK: BOOL;
  MAN_ON: BOOL;
  COM_RST: BOOL;
  CYCLE: TIME:=T#1S;    
END_VAR
VAR_OUTPUT
  OUTV : REAL;
  QUPRLM_P: BOOL;
  QDNRLM_P: BOOL;
  QUPRLM_N: BOOL;
  QDNRLM_N: BOOL;
  QH_LM: BOOL;
  QL_LM: BOOL;    
END_VAR
VAR
  sbMerkManOn : BOOL;      
END_VAR
VAR_TEMP
  dHvar: REAL;
  drOutv: REAL;
  drCycle: REAL;
  dUpP: BOOL;
  dDownP: BOOL;
  dUpN: BOOL;
  dDownN: BOOL;
  dHLm: BOOL;
  dLLm: BOOL;    
END_VAR
BEGIN
      dUpP:=0;
      dDownP:=0;
      dUpN:=0;
      dDownN:=0;
      dHLm:=0;
      dLLm:=0;
      drCycle := DINT_TO_REAL(TIME_TO_DINT(CYCLE)) * 1.000000e-003;
      drOutv := INV;

    IF COM_RST THEN
        sbMerkManOn := TRUE;
        IF DFOUT_ON THEN
            drOutv := DF_OUTV;
            IF drOutv >= H_LM THEN
                drOutv := H_LM; 
                dHLm := TRUE;  
            END_IF; 
            IF drOutv <= L_LM THEN
                drOutv :=  L_LM;  
                dLLm := TRUE; 
            END_IF;
        ELSE
            drOutv := 0.000000e+000;
        END_IF;
    
        ELSIF MAN_ON THEN
            drOutv := PV;
            sbMerkManOn := FALSE;
        ELSE    
            IF DFOUT_ON THEN
                drOutv := DF_OUTV;
            ELSIF TRACK THEN
                    drOutv:= INV; 
                         
            ELSIF OUTV < 0.000000e+000 THEN
        
                IF OUTV > INV THEN
                    dHvar := OUTV - (UPRLM_N * drCycle);
                    IF INV < dHvar THEN
                        dUpN := TRUE;
                        drOutv := dHvar;
                    END_IF;
                ELSE      
                    IF DNRLM_N = 0.000000e+000 THEN
                        dDownN := TRUE;
                        drOutv := INV;  
                    ELSIF INV <= 0.000000e+000 THEN
                        dHvar := (DNRLM_N * drCycle) + OUTV;
                        IF  INV > dHvar THEN
                            dDownN := TRUE;
                            drOutv := dHvar;
                        END_IF;        
                    ELSE 
                        dHvar := -OUTV/DNRLM_N;
                        IF dHvar <= drCycle THEN
                            dHvar := (drCycle - dHvar)*UPRLM_P;
                            IF INV > dHvar THEN
                                dDownN := TRUE;
                                dUpP := TRUE;
                                drOutv := dHvar;
                             END_IF;   
                        ELSE
                            dDownN := TRUE;
                            dUpP := TRUE;
                            drOutv := (drCycle * DNRLM_N) + OUTV;
                        END_IF;
                    END_IF; 
                END_IF; 
            ELSE
                IF OUTV < INV THEN
                    dHvar := (UPRLM_P * drCycle) + OUTV;
                    IF INV > dHvar THEN
                        dUpP := TRUE;
                        drOutv := dHvar;
                    END_IF;    
                END_IF;
            
                IF OUTV >= INV THEN
                    IF DNRLM_P = 0.000000e+000 THEN
                        dDownP := TRUE;
                        drOutv := INV;
                    ELSIF INV >= 0.000000e+000 THEN
                        dHvar := OUTV - (DNRLM_P * drCycle);  
                        IF INV < dHvar THEN
                            dDownP := TRUE;
                            drOutv := dHvar;
                        END_IF;  
                    ELSE 
                        dHvar := OUTV/DNRLM_P;
                        IF dHvar <= drCycle THEN
                            dHvar := -(drCycle - dHvar) * UPRLM_N;
                            IF INV < dHvar THEN
                                dDownP := TRUE;
                                dUpN := TRUE;
                                drOutv := dHvar;
                            END_IF;
                        ELSE
                            dDownP := TRUE;
                            dUpN := TRUE;
                            drOutv :=  OUTV - (drCycle * DNRLM_P); 
                        END_IF;                           
                    END_IF;
               END_IF;     
        END_IF;
                
        IF drOutv >= H_LM THEN
            dHLm := TRUE;
            IF sbMerkManOn THEN
                drOutv := H_LM;
                IF  (drOutv - OUTV) < UPRLM_P * drCycle THEN
                    dUpP := FALSE;
                END_IF;
            END_IF;  
        ELSIF drOutv <= L_LM THEN
            dLLm := TRUE;
            IF sbMerkManOn THEN
                drOutv := L_LM;
                IF (OUTV - drOutv) < UPRLM_N * drCycle THEN
                    dUpN := FALSE;
                END_IF;    
            END_IF;
        ELSE
            sbMerkManOn := TRUE;          
        END_IF;
END_IF;

OUTV := drOutv;
QUPRLM_P := dUpP;
QDNRLM_P := dDownP;
QUPRLM_N := dUpN;
QDNRLM_N := dDownN;
QH_LM := dHLm;
QL_LM := dLLm;

END_FUNCTION_BLOCK