SPS- Programmierung mit ST

nach IEC 61131 mit CODESYS V2.3, CODESYS V3, e!COCKPIT

Lösungen Kapitel 9 Funktionsblöcke (FBs) für CODESYS V3 oder e!COCKPIT ,  für CoDeSys V2.3

  Kopieren Sie den Programmcode und fügen Sie diesen in Ihre Entwicklungsumgebung ein.
  


Aufgabe 9.1 SR
  

PROGRAM PLC_PRG
(*vorrangig setzen*)
VAR
 S1_Start AT %IX0.1:BOOL;
 S0_Stopp AT %IX0.0:BOOL;
 Out AT %QX1.0:BOOL;
 SR1 :SR; (*Instanz*)
END_VAR
(*Instanzaufruf des FBs mit Parameterübergabe*)
SR1(SET1:= S1_Start, RESET:= S0_Stopp);
Out:= SR1.Q1;
  
Aufgabe 9.2 Bandsteuerung
  

VAR_GLOBAL
 S0_Band_AUS AT %IX2.0:BOOL;(*Ö*)
 S1_Band_Ein AT %IX2.1:BOOL;
 Q1_Band1 AT %QX0.0:BOOL;
 Q2_Band2 AT %QX0.1:BOOL;
END_VAR

PROGRAM BANDANL
VAR
(*Instanzen*)
 RS_Band_1:RS;
 TON_1:TON;
 TOF_1,TOF_2:TOF;
END_VAR
(*Band 1*)
RS_Band_1(SET:= S1_Band_Ein,
          RESET1:= NOT S0_Band_AUS);
TOF_1(IN:= RS_Band_1.Q1, PT:= T#2s);
Q1_Band1:= TOF_1.Q;
(*Band 2*)
TON_1(IN:= Q1_Band1, PT:= T#1s500ms);
TOF_2(IN:= TON_1.Q, PT:= T#3s);
Q2_Band2:= TOF_2.Q;


PROGRAM PLC_PRG
VAR
END_VAR
BANDANL();(*Aufruf des Unterprogramms*)
  
Aufgabe 9.3 a) Behälterfüllung
  

VAR_GLOBAL
 M10_Ventil_A AT %QX0.0:BOOL;
 M11_Ventil_B AT %QX0.1:BOOL;
END_VAR

PROGRAM PLC_PRG
(*Behälter füllen*)
VAR
 xStart:BOOL;(*visu. Schaltfläche*)
 rK :REAL:=2.0;(*Mischverhältnis VA/VB*)
 tTa, tTb: TIME;(*Ventilöffnungszeiten*)
 rTa, rTb: REAL;(*in ms*)
 TP_A, TP_B :TP;(*Instanzen*)
END_VAR
(*Öffnungszeit abhängig von k berechnen*)
IF rK>0.0 THEN
 rTa:= 30.0/(rK+1.0)* rK;
 rTb:= 30.0-rTa;
 tTa:=REAL_TO_TIME(rTa*1000.0);
 tTb:=REAL_TO_TIME(rTb*1000.0);
 (*Aufruf der Instanzen von TP*)
 TP_A(IN:=xStart , PT:=tTa);
 M10_Ventil_A:=TP_A.Q;
 TP_B(IN:=TP_A.Q , PT:=tTb);
 M11_Ventil_B:=TP_B.Q;
END_IF;
  
b) Behälterfüllung
  
VAR_GLOBAL
 M10_Ventil_A AT %QX0.0:BOOL;
 M11_Ventil_B AT %QX0.1:BOOL;
 M20_Ventil_A AT %QX0.2:BOOL;
 M21_Ventil_B AT %QX0.3:BOOL;
END_VAR
 
Lösung 1
 
TYPE BEHAELTER :
STRUCT
 xStart, xVentil_A, xVentil_B:BOOL;
 rK:REAL:=2.0;(*Mischverhältnis VA/VB*)
 tTa, tTb:TIME;(*Öffnungszeit der Ventile*)
 rTa,rTb:REAL;(*in ms*)
 TP_A, TP_B:TP;(*Instanz*)
END_STRUCT
END_TYPE

PROGRAM PLC_PRG
(*2 Behälter füllen*)
VAR
 Beh_1:BEHAELTER;
 Beh_2:BEHAELTER;
END_VAR
(*Behälter 1 Öffnungszeit abhängig von k berechnen*)
IF Beh_1.rK > 0.0 THEN
 Beh_1.rTa:= 30.0/(Beh_1.rK+1.0)*Beh_1.rK;
 Beh_1.rTb:=30.0-Beh_1.rTa;
 Beh_1.tTa:=REAL_TO_TIME(Beh_1.rTa*1000.0);
 Beh_1.tTb:=REAL_TO_TIME(Beh_1.rTb*1000.0);
 (*Aufruf der Instanzen von TP*)
 Beh_1.TP_A(IN:=Beh_1.xStart , PT:= Beh_1.tTa);
 Beh_1.xVentil_A:= Beh_1.TP_A.Q;
 Beh_1.TP_B(IN:= Beh_1.TP_A.Q, PT:= Beh_1.tTb);
 Beh_1.xVentil_B:= Beh_1.TP_B.Q;
END_IF;
M10_Ventil_A:= Beh_1.xVentil_A;
M11_Ventil_B:=Beh_1.xVentil_B;
(*Behälter 2 Öffnungszeit abhängig von k berechnen*)
IF Beh_2.rK > 0.0 THEN
 Beh_2.rTa:= 30.0/(Beh_2.rK+1.0)*Beh_2.rK;
 Beh_2.rTb:=30.0-Beh_2.rTa;
 Beh_2.tTa:=REAL_TO_TIME(Beh_2.rTa*1000.0);
 Beh_2.tTb:=REAL_TO_TIME(Beh_2.rTb*1000.0);
 (*Aufruf der Instanzen von TP*)
 Beh_2.TP_A(IN:=Beh_2.xStart , PT:= Beh_2.tTa);
 Beh_2.xVentil_A:= Beh_2.TP_A.Q;
 Beh_2.TP_B(IN:= Beh_2.TP_A.Q, PT:= Beh_2.tTb);
 Beh_2.xVentil_B:= Beh_2.TP_B.Q;
END_IF;
M20_Ventil_A:=Beh_2.xVentil_A;
M21_Ventil_B:=Beh_2.xVentil_B;
  
Lösung 2 mit FOR-Schleife
  
PROGRAM PLC_PRG
(*Zwei Behälter füllen*)
VAR
 Beh:ARRAY[1..2] OF BEHAELTER;
 i: USINT;
END_VAR
FOR i := 1 TO 2 DO
 (*Öffnungszeit abhängig von k berechnen*)
 IF Beh[i].rK > 0.0 THEN
  Beh[i].rTa:= 30.0/(Beh[i].rK+1.0)*Beh[i].rK;
  Beh[i].rTb:= 30.0-Beh[i].rTa;
  Beh[i].tTa:= REAL_TO_TIME(Beh[i].rTa*1000.0);
  Beh[i].tTb:= REAL_TO_TIME(Beh[i].rTb*1000.0);
  (*Aufruf der Instanzen von TP*)
  Beh[i].TP_A(IN:=Beh[i].xStart , PT:= Beh[i].tTa);
  Beh[i].xVentil_A:= Beh[i].TP_A.Q;
  Beh[i].TP_B(IN:= Beh[i].TP_A.Q, PT:= Beh[i].tTb);
  Beh[i].xVentil_B:= Beh[i].TP_B.Q;
 END_IF;
END_FOR;
(*Ventile Behälter 1*)
M10_Ventil_A:= Beh[1].xVentil_A;
M11_Ventil_B:= Beh[1].xVentil_B;
(*Ventile Behälter 2*)
M20_Ventil_A:=Beh[2].xVentil_A;
M21_Ventil_B:=Beh[2].xVentil_B;
  
Aufgabe 9.4 a) Zwei Behälter mit FB
  

VAR_GLOBAL
 M10_Ventil_A AT %QX0.0:BOOL;
 M11_Ventil_B AT %QX0.1:BOOL;
 M20_Ventil_A AT %QX0.2:BOOL;
 M21_Ventil_B AT %QX0.3:BOOL;
END_VAR

PROGRAM PLC_PRG
(***********************************************************************
Behälter füllen mit anwenderdefinierten FB.
Zur Simulation werden nach dem Einloggen und Start die
Werte von xStart und rK vorbereitet und geschrieben (Strg+F7).
Beobachten Sie in der GLV das verzögerte Schalten von M10_Ventil_A ...
abhängig vom rK-Wert.
************************************************************************)
VAR
(*Behälter 1*)
 xStart_1:BOOL;
 rK_1:REAL:=2.0;
 BEHAELTER1: BEHAELTER_K;
(*Behälter 2*)
 xStart_2:BOOL;
 rK_2:REAL:=0.5;
 BEHAELTER2: BEHAELTER_K;
END_VAR
(*Aufruf der Instanzen des FBs*)
BEHAELTER1(START:= xStart_1, K:= rK_1,
           YA=> M10_Ventil_A, YB=> M11_Ventil_B);
BEHAELTER2(START:= xStart_2, K:= rK_2,
           YA=> M20_Ventil_A, YB=> M21_Ventil_B );

FUNCTION_BLOCK BEHAELTER_K
(*Behälter, Mischverhältnis, Füllzeit*)
VAR_INPUT
 START:BOOL;
 K:REAL;(*Mischverhältnis VA/VB*)
END_VAR
VAR_OUTPUT
 YA:BOOL;
 YB:BOOL;
END_VAR
VAR
 ta, tb: TIME;(*Öffnungszeit der Ventile A,B in ms*)
 ta_real, tb_real: REAL;(*Öffnungszeit der Ventile*)
 TP_A, TP_B:TP;(*Instanzen*)
END_VAR
(*Öffnungszeit abhängig von k berechnen*)
ta_real:= 15.0 / (K + 1.0)*K;
tb_real:= 15.0 - ta_real;
ta:=REAL_TO_TIME(ta_real*1000.0);
tb:=REAL_TO_TIME(tb_real*1000.0);
(*Aufruf der Instanzen von TP*)
TP_A(IN:=START , PT:=ta);
YA:=TP_A.Q;
TP_B(IN:=YA , PT:=tb);
YB:=TP_B.Q;
 
b) Zwei Behälter mit FB und Übergabe der max. Füllzeit

VAR_GLOBAL
 M10_Ventil_A AT %QX0.0:BOOL;
 M11_Ventil_B AT %QX0.1:BOOL;
 M20_Ventil_A AT %QX0.2:BOOL;
 M21_Ventil_B AT %QX0.3:BOOL;
END_VAR

PROGRAM PLC_PRG
VAR
(*Behälter 1*)
  start_1:BOOL;
  k_1:REAL:=2.0;
  Fuellzeit_1:TIME:=T#10s;
  BEHAELTER1: BEHAELTER_K;
(*Behälter 2*)
  start_2:BOOL;
  k_2:REAL:=0.5;
  Fuellzeit_2:TIME:=T#15s;
  BEHAELTER2: BEHAELTER_K;
END_VAR
BEHAELTER1(START:= start_1 , K:= k_1, T_FUELL:= Fuellzeit_1);
M10_Ventil_A:= BEHAELTER1.YA;
M11_Ventil_B:= BEHAELTER1.YB;
BEHAELTER2(START:= start_2 , K:= k_2, T_FUELL:= Fuellzeit_2);
M20_Ventil_A:= BEHAELTER2.YA;
M21_Ventil_B:= BEHAELTER2.YB;

oder

PROGRAM PLC_PRG
(*Die Eingangsparameter werden direkt über die Visu beschrieben*)
VAR
(*Behälter 1*)
 BEHAELTER1: BEHAELTER_K;
(*Behälter 2*)
 BEHAELTER2: BEHAELTER_K;
END_VAR
BEHAELTER1(
           YA=> M10_Ventil_A,
           YB=> M11_Ventil_B);
BEHAELTER2(
           YA=> M20_Ventil_A,
           YB=> M21_Ventil_B);

FUNCTION_BLOCK BEHAELTER_K
(*Behälter, Mischverhältnis, Füllzeit*)
VAR_INPUT
 START:BOOL;
 K:REAL:=1.0;(*Mischverhältnis VA/VB*)
 T_FUELL:TIME:=T#10s;(*Füllzeit*)
END_VAR
VAR_OUTPUT
 YA:BOOL;
 YB:BOOL;
END_VAR
VAR
 ta, tb: TIME;(*Öffnungszeit der Ventile A,B in ms*)
 ta_real, tb_real, tf_real: REAL;(*Öffnungszeit der Ventile*)
 TP_A, TP_B:TP;(*Instanzen*)
END_VAR
(*T_FUELL in REAL umwandeln und in s umrechnen*)
tf_real:= TIME_TO_REAL(T_FUELL)/1000.0;
(*Öffnungszeit abhängig von k berechnen*)
ta_real:= tf_real/(K + 1.0)*K;
tb_real:= tf_real-ta_real;
ta:= REAL_TO_TIME(ta_real*1000.0);
tb:= REAL_TO_TIME(tb_real*1000.0);
(*Aufruf der Instanzen von TP*)
TP_A(IN:=START , PT:=ta);
YA:=TP_A.Q;
TP_B(IN:=YA , PT:=tb);
YB:=TP_B.Q;
 
c) Aufruf der Instanzen über eine Schleife

PROGRAM PLC_PRG
VAR
 xStart:ARRAY [1..2]OF BOOL;
 rK:ARRAY [1..2]OF REAL:= [2.0, 0.5];
 tFuellzeit:ARRAY [1..2]OF TIME:= [T#10s, T#15s];
 BEHAELTER:ARRAY [1..2]OF BEHAELTER_K;
 i:INT:=1;
END_VAR
FOR i := 1 TO 2 DO
 BEHAELTER[i](START:= xStart[i], K:= rK[i], T_FUELL:= tFuellzeit[i]);
END_FOR;
M10_Ventil_A:= BEHAELTER[1].YA;
M11_Ventil_B:= BEHAELTER[1].YB;
M20_Ventil_A:= BEHAELTER[2].YA;
M21_Ventil_B:= BEHAELTER[2].YB;

oder

PROGRAM PLC_PRG
(*Die Eingangsparameter werden direkt über die Visu beschrieben*)
VAR
 BEHAELTER:ARRAY [1..2]OF BEHAELTER_K;
 i:INT:=1;
END_VAR
FOR i := 1 TO 2 DO
 BEHAELTER[i]();
END_FOR;
M10_Ventil_A:=BEHAELTER[1].YA;
M11_Ventil_B:=BEHAELTER[1].YB;
M20_Ventil_A:=BEHAELTER[2].YA;
M21_Ventil_B:=BEHAELTER[2].YB;
  
Aufgabe 9.5 a) FB-Zweipunktregler
  

FUNCTION_BLOCK Z_REG
(*Zweipunktregler*)
VAR_INPUT
 W:REAL;(*Sollwert*)
 X:REAL;(*Istwert*)
 H:REAL;(*Hysterese*)
END_VAR
VAR_OUTPUT
 Y:BOOL;(*Stellwert*)
END_VAR
(*Schalten*)
IF X > W + H/2.0
  THEN Y := FALSE;
 ELSIF X < W – H/2.0
  THEN Y := TRUE;
END_IF;

PROGRAM PLC_PRG
(*Aufruf der Zweipunktregler:
y1 und y2 werden abhängig vom Sollwert w1, w2, dem Istwert x1, x2
und der Hysterese h1, h2 geschaltet.
Den Istwert liefert der Prozess, in der Simulation wird er vorgegeben*)
VAR
 w1:REAL:= 150.0; x1:REAL;
 h1:REAL:= 10.0; y1:BOOL;
 w2:REAL:= 200.0; x2:REAL;
 h2:REAL:= 5.0; y2:BOOL;
 Z_REG1:Z_REG;(*Instanz*)
 Z_REG2:Z_REG;(*Instanz*)
END_VAR
(*Aufruf mit Parameterübergabe*)
Z_REG1(W:= w1,X:= x1,H:= h1);
y1:= Z_REG1.Y;
Z_REG2(W:= w2,X:= x2,H:= h2);
y2:= Z_REG2.Y;
  
b) Mehrere FBs-Zweipunktregler über eine Schleife aufrufen

PROGRAM PLC_PRG
(*Mehrere FBs-Zweipunktregler über eine Schleife aufrufen*)
VAR
 i: INT;
 Z_REG_:ARRAY [0..2]OF Z_REG;
 rW:ARRAY [0..2]OF REAL:= [150.0, 120.0, 180.0];
 rX:ARRAY [0..2]OF REAL;
 rH:ARRAY [0..2]OF REAL:= [10.0, 20.0, 30.0];
END_VAR
rX[0]:=INT_TO_REAL(Temp0); rX[1]:=INT_TO_REAL(Temp1);
rX[2]:=INT_TO_REAL(Temp2); (*Temperaturen lesen*)
FOR i := 0 TO 2 DO
 Z_REG_[i](W:= rW[i], X:= rX[i], H:= rH[i]);
END_FOR;
Q0:=Z_REG_[0].Y; Q1:=Z_REG_[1].Y; Q2:=Z_REG_[2].Y;(*Schütze schalten*)
  
Aufgabe 9.6 Tanksteuerung, IN_OUT-Parameter mit anwenderdefiniertem Datentyp
  

TYPE typTANK:
STRUCT
 rTemperatur:REAL;
 rDurchfluss:REAL;
 xHeizung, xEin:BOOL;
END_STRUCT
END_TYPE

FUNCTION_BLOCK FbTANK_ANL
(*Steuerung eines Tanks*)
VAR_IN_OUT
 ANL:typTANK;
END_VAR
IF ANL.xEIN AND ANL.rDurchfluss > 25.0 THEN
  IF ANL.rTemperatur > 100.0 THEN
    ANL.xHeizung:= FALSE;
   ELSIF ANL.rTemperatur < 95.0 THEN
    ANL.xHeizung:= TRUE;
  END_IF;
 ELSE ANL.xHeizung:= FALSE;
END_IF;

a) Aufruf der Instanzen

PROGRAM PLC_PRG
VAR
(******************************************************************
FB "TANK_ANL" mit IN-OUT-Parameter und anwenderdefiniertem Datentyp
erstellen und mehrere Instanzen aufrufen.
Zur Simulation werden nach dem Einloggen und Start die Werte in
Tankanlage_1 und 2 vorbereitet und geschrieben (Strg+F7).
Beurteilen Sie die xHeizung-Werte.
*******************************************************************)
 Tankanlage_1:typTANK;
 instTANK_ANL_1:FbTANK_ANL; (*Instanz des FBs*)
 Tankanlage_2:typTANK;
 instTANK_ANL_2:FbTANK_ANL;
END_VAR
(*Instanzaufrufe*)
instTANK_ANL_1(ANL:= Tankanlage_1);
instTANK_ANL_2(ANL:= Tankanlage_2);

b) Aufruf der Instanzen in einer FOR-Schleife mit GLV

VAR_GLOBAL
(*Tank1*)
  Temp1 AT %IW0 :INT; (*1000=>100°C*)
  Durchf1 AT %IW3 :INT;(*327600=>100Liter/min*)
  S1_Ein AT %IX2.0:BOOL;
  Q1_Heiz AT %QX0.0:BOOL;
(*Tank2*)
  Temp2 AT %IW1 :INT;
  Durchf2 AT %IW4 :INT;
  S2_Ein AT %IX2.1:BOOL;
  Q2_Heiz AT %QX0.1:BOOL;
END_VAR

PROGRAM PLC_PRG
VAR
(******************************************************************
FB "TANK_ANL" mit IN-OUT-Parameter und anwenderdefinirtem Datentyp
erstellen und mehrere Instanzen in einer FOR-Schleife aufrufen.
Zur Simulation werden nach dem Einloggen und Start die Werte in
der GVL vorbereitet und geschrieben (Strg+F7).
Beurteilen Sie die Q1 und Q2 Werte.
*******************************************************************)
 Tankanlage:ARRAY[1..2] OF typTANK;
 instTANK_ANL:ARRAY[1..2] OF FbTANK_ANL;
 i: INT;
END_VAR
(*Globale Var. lesen*)
Tankanlage[1].rTemperatur:=Temp1/10.0; (*1000=>100°C*)
Tankanlage[1].rDurchfluss:=Durchf1/327.60;(*327600=>100Liter/min*)
Tankanlage[1].xEin:=S1_Ein;
Tankanlage[2].rTemperatur:=Temp2/10.0;
Tankanlage[2].rDurchfluss:=Durchf2/327.60;
Tankanlage[2].xEin:=S2_Ein;
(*Instanzaufrufe*)
FOR i:=1 TO 2 DO
 instTANK_ANL[i](ANL:= Tankanlage[i]);
END_FOR;
(*Globale Var. beschreiben*)
Q1_Heiz:=Tankanlage[1].xHeizung;
Q2_Heiz:=Tankanlage[2].xHeizung;
  
Bandanlage Lösung

© Vogel Buchverlag