11. Lösungen: Bibliotheken verwenden ======================================================================= Aufgaben 11.1 Zeitversetztes Zentral-Ein- und Ausschalten Vergessen Sie nicht, die Bibliothek "GEBAEUDE.library" in Ihr Projekt über die Bibliotheksverwaltung einzubinden. VAR_GLOBAL S1_Licht AT %IX2.0:BOOL; Q1_Lichtband1 AT %QX0.0:BOOL; Q2_Lichtband2 AT %QX0.1:BOOL; Q3_Lichtband3 AT %QX0.2:BOOL; Q4_Lichtband4 AT %QX0.3:BOOL; END_VAR PROGRAM PLC_PRG (********************************************* Zeitversetztes Zentral-Ein- und Ausschalten Bibliothek: GEBAEUDE.library Version: 1.0 Firma: ........´Datum: ........ **********************************************) VAR Fb_LichtZentral1: Fb_LichtZentral; END_VAR //Instanzaufruf Fb_LichtZentral1( xEingang:= GVL.S1_Licht, uiTvein:= 50, uiTvaus:= 50, xAusgang1=> GVL.Q1_Lichtband1, xAusgang2=> GVL.Q2_Lichtband2, xAusgang3=> GVL.Q3_Lichtband3, xAusgang4=> GVL.Q4_Lichtband4); Wenn Sie die Bibliothek GEBAEUDE.library nicht benutzen, so finden Sie hier den Baustein FUNCTION_BLOCK Fb_LichtZentral VAR_INPUT xEingang:BOOL; uiTvein:UINT:=10; uiTvaus:UINT:=10; END_VAR VAR_OUTPUT xAusgang1, xAusgang2, xAusgang3, xAusgang4:BOOL; END_VAR VAR tTvein, tTvaus:TIME; TON1:TON; TOF1: TOF; END_VAR //Tv in Datentyp TIME tTvein:= UINT_TO_TIME(uiTvein*10); tTvaus:= UINT_TO_TIME(uiTvaus*10); TON1(IN:= xEingang, PT:= 3*tTvein); TOF1(IN:= xEingang, PT:= 3*tTvaus); //Ausgänge schalten xAusgang1:=xEingang; IF TON1.ET >= tTvein THEN xAusgang2:=TRUE; END_IF; IF TOF1.ET >= tTvaus THEN xAusgang2:=FALSE; END_IF; IF TON1.ET >= 2*tTvein THEN xAusgang3:=TRUE; END_IF; IF TOF1.ET >= 2*tTvaus THEN xAusgang3:=FALSE; END_IF; IF TON1.ET >= 3*tTvein THEN xAusgang4:=TRUE; END_IF; IF TOF1.ET >= 3*tTvaus THEN xAusgang4:=FALSE; END_IF; _______________________________________________________________________ Aufgaben 11.2 Lichtszenen schalten Vergessen Sie nicht, die Bibliotheken "GEBAEUDE" und "BUILDING" in Ihr Projekt über die Bibliotheksverwaltung einzubinden. VAR_GLOBAL (*Lichtszenen schalten*) S20_Lichtszene AT %IX2.1:BOOL; Q20_Licht AT %QX0.4:BOOL; Q21_Licht AT %QX0.5:BOOL; Q22_Licht AT %QX0.6:BOOL; Q23_Licht AT %QX0.7:BOOL; END_VAR PROGRAM PLC_PRG (********************************************** Bibliotheken: OSCAT Building 1.0.0.0 und GEBAEUDE Zur Simulation, nach dem Einloggen und Start, können Sie in der Visualisierung die Lichtszenen umschalten ***********************************************) VAR S20visu:BOOL; SzenenNr:BYTE:= 1; CLICK_MODE1:OSCAT_BUILDING.CLICK_MODE; FbSzeneDigital1:FbSzeneDigital; END_VAR CLICK_MODE1(IN:= S20visu OR S20_Lichtszene); IF CLICK_MODE1.SINGLE THEN SzenenNr:= SzenenNr + 1; END_IF; IF SzenenNr= 9 OR CLICK_MODE1.DOUBLE THEN SzenenNr:= 1; END_IF; FbSzeneDigital1( bAktorSzenenNr1bis8:= SzenenNr, xSchaltaktor1:= , xSchaltaktor2:= , xSchaltaktor3:= , xSchaltaktor4:= , xSpeichern:= , xDoSchaltAktor1=> Q20_Licht, xDoSchaltAktor2=> Q21_Licht, xDoSchaltAktor3=> Q22_Licht, xDoSchaltAktor4=> Q23_Licht); Wenn Sie die Bibliothek GEBAEUDE.library nicht benutzen, so finden Sie hier den Baustein FUNCTION_BLOCK FbSzeneDigital VAR_INPUT bAktorSzenenNr1bis8:BYTE; xSchaltaktor1, xSchaltaktor2, xSchaltaktor3, xSchaltaktor4:BOOL; xSpeichern:BOOL; END_VAR VAR_OUTPUT xDoSchaltAktor1, xDoSchaltAktor2, xDoSchaltAktor3, xDoSchaltAktor4:BOOL; END_VAR VAR xSzeneAktor:ARRAY[1..8,1..4] OF BOOL:=[FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE]; END_VAR // Szenenwerte festlegen IF xSpeichern THEN CASE bAktorSzenenNr1bis8 OF 1: xSzeneAktor[1,1]:= xSchaltaktor1; xSzeneAktor[1,2]:= xSchaltaktor2; xSzeneAktor[1,3]:= xSchaltaktor3; xSzeneAktor[1,4]:= xSchaltaktor4; 2: xSzeneAktor[2,1]:= xSchaltaktor1; xSzeneAktor[2,2]:= xSchaltaktor2; xSzeneAktor[2,3]:= xSchaltaktor3; xSzeneAktor[2,4]:= xSchaltaktor4; 3: xSzeneAktor[3,1]:= xSchaltaktor1; xSzeneAktor[3,2]:= xSchaltaktor2; xSzeneAktor[3,3]:= xSchaltaktor3; xSzeneAktor[3,4]:= xSchaltaktor4; 4: xSzeneAktor[4,1]:= xSchaltaktor1; xSzeneAktor[4,2]:= xSchaltaktor2; xSzeneAktor[4,3]:= xSchaltaktor3; xSzeneAktor[4,4]:= xSchaltaktor4; 5: xSzeneAktor[5,1]:= xSchaltaktor1; xSzeneAktor[5,2]:= xSchaltaktor2; xSzeneAktor[5,3]:= xSchaltaktor3; xSzeneAktor[5,4]:= xSchaltaktor4; 6: xSzeneAktor[6,1]:= xSchaltaktor1; xSzeneAktor[6,2]:= xSchaltaktor2; xSzeneAktor[6,3]:= xSchaltaktor3; xSzeneAktor[6,4]:= xSchaltaktor4; 7: xSzeneAktor[7,1]:= xSchaltaktor1; xSzeneAktor[7,2]:= xSchaltaktor2; xSzeneAktor[7,3]:= xSchaltaktor3; xSzeneAktor[7,4]:= xSchaltaktor4; 8: xSzeneAktor[8,1]:= xSchaltaktor1; xSzeneAktor[8,2]:= xSchaltaktor2; xSzeneAktor[8,3]:= xSchaltaktor3; xSzeneAktor[8,4]:= xSchaltaktor4; END_CASE; END_IF; //Ausgänge xDoSchaltAktor1:=xSzeneAktor[bAktorSzenenNr1bis8,1]; xDoSchaltAktor2:=xSzeneAktor[bAktorSzenenNr1bis8,2]; xDoSchaltAktor3:=xSzeneAktor[bAktorSzenenNr1bis8,3]; xDoSchaltAktor4:=xSzeneAktor[bAktorSzenenNr1bis8,4]; _______________________________________________________________________ Aufgabe 11.3 Temperaturregelung mit dem PID-Reglerbaustein Vergessen Sie nicht, die Bibliothek "Util" in Ihr Projekt über die Bibliotheksverwaltung einzubinden. FUNCTION_BLOCK PT2 (*Strecke mit Ausgleich*) VAR_INPUT Y:REAL;(*Stellwert*) N:USINT:= 30; (*zeitliches Verhalten*) END_VAR VAR_OUTPUT X:REAL;(*Istwert*) END_VAR VAR LOW_PASS_1, LOW_PASS_2:LOW_PASS;(*Instanzen*) x1: REAL; END_VAR LOW_PASS_1(IN:= Y, N:= N); x1:= LOW_PASS_1.OUT; LOW_PASS_2(IN:= x1, N:= N); X:= LOW_PASS_2.OUT; FUNCTION_BLOCK LOW_PASS (*Einfacher Tiefpass, Ausgangsverlauf ist nahe der e-Funktion*) VAR_INPUT IN: REAL; N: USINT;(*nach N Zyklen wird der Endwert erreicht*) END_VAR VAR_OUTPUT FAULT: BOOL; OUT: REAL; END_VAR IF N<5 OR N>200 THEN N:= 50; FAULT:= TRUE; ELSE FAULT:= FALSE; END_IF; OUT:=((IN-OUT)/N)+ OUT; PROGRAM TEMP_REG (******************************************* Temperaturregelung: Abtastzeit: 100 ms Version: 1.0, Datum: .... ., Autor: SchmittK Bibliothek: Util ********************************************) VAR w:REAL;(*Sollwert 0...1*) x: REAL;(*Istwert = Temperatur normiert 0...1*) e:REAL;(*Regeldifferenz*) y: REAL;(*Stellwert 0...1.0 = Heizleistung normiert*) PT2_1:PT2;(*Instanz*) Fb_Control_PID_1:PID; END_VAR (*Simulation der Regelstrecke mit Ausgleich, Tg=10s, Tu=1.2s*) PT2_1(Y:= y, N:=); x:=PT2_1.X; (*PID-Regler, Reglerparameter optimiert nach Takahashi*) Fb_Control_PID_1( ACTUAL:= x, SET_POINT:= w, KP:= (1.2*10.0/(1.2+0.1)), //aus Sprungantwort TN:= (2.0*(1.25*1.25)/(1.3)), TV:= (0.5*(1.2+0.1)), Y_MANUAL:= , Y_OFFSET:= , Y_MIN:= 0.0 , Y_MAX:= 1.0, MANUAL:= 0, RESET:= , Y=> y, LIMITS_ACTIVE=> , OVERFLOW=> ); _______________________________________________________________________ Übung 11.1 Zufallszahl erraten PROGRAM PLC_PRG (********************************************************************* Funktion: Es wird eine Zufallszahl erzeugt die durch Eingabe zu erraten ist. Bibliothek: OSCAT_BASIC 3.3.3 **********************************************************************) VAR Zufallszahl: USINT; Eingabezahl: USINT;(*Visu*) Meldung: STRING; Meld_ok:STRING:='Die Zahl ist richtig!'; Meld_gr:STRING:='Die Zahl ist zu groß!'; Meld_kl:STRING:='Die Zahl ist zu klein!'; richtig: BOOL:=TRUE;(*Visu*) go: BOOL;(*Taster in der Visu "Neue Zahl"*) Versuche: INT;(*Anzahl der Versuche*) Eingabezahl_alt: USINT; END_VAR IF go OR Zufallszahl = 0 THEN Zufallszahl:= REAL_TO_USINT(OSCAT_BASIC.RDM(last:=0 )*100.0); Versuche:=0; END_IF; IF Eingabezahl = Zufallszahl THEN Meldung:=Meld_ok; richtig:=TRUE; ELSIF Eingabezahl > Zufallszahl THEN Meldung:=Meld_gr; richtig:=FALSE; ELSE Meldung:=Meld_kl; richtig:=FALSE; END_IF; IF Eingabezahl <> Eingabezahl_alt THEN Versuche:= Versuche + 1; END_IF; Eingabezahl_alt:=Eingabezahl; _______________________________________________________________________ Übung 11.2 PIG Würfelspiel Fügen Sie die Bibliothek Oscat Basic hinzu. PROGRAM PLC_PRG (************************************ PIG Würfelspiel für zwei Spieler Bibliothek: Oscat Basic *************************************) VAR instPIG1, instPIG2:PIG; xSpieler, xNeuesSpiel:BOOL;(*Schalter Visu*) END_VAR (*Spieler 1*) instPIG1(xSPIELEN:= NOT xSpieler, xNEUES_SPIEL:= xNeuesSpiel); (*Spieler 2*) instPIG2(xSPIELEN:= xSpieler, xNEUES_SPIEL:= xNeuesSpiel); Lösungsvariante 1 mit Hilfe des PAP FUNCTION_BLOCK PIG VAR_INPUT xSPIELEN, xWUERFELN, xNEUES_SPIEL:BOOL; END_VAR VAR_OUTPUT usiWUERFELZAHL:USINT; uiSPIELSTAND:UINT; END_VAR VAR instWUERFELN_TRIG:Standard.R_TRIG; usiWuerfelzahlNeu: USINT; END_VAR IF xSPIELEN THEN instWUERFELN_TRIG(CLK:= xWUERFELN); usiWuerfelzahlNeu:= 0; IF instWUERFELN_TRIG.Q THEN WHILE usiWuerfelzahlNeu < 1 OR usiWuerfelzahlNeu > 6 DO usiWuerfelzahlNeu:= REAL_TO_USINT(OSCAT_BASIC.RDM(last:= 0)*10.0); END_WHILE; IF usiWuerfelzahlNeu > 1 THEN uiSPIELSTAND:= uiSPIELSTAND + usiWuerfelzahlNeu; ELSE uiSPIELSTAND:= 0; END_IF; usiWUERFELZAHL:= usiWuerfelzahlNeu; END_IF; END_IF; IF xNEUES_SPIEL THEN uiSPIELSTAND:= 0; usiWuerfelzahl:= 0; END_IF; Lösungsvariante 2 mit Hilfe des GRAFCETs FUNCTION FC_ZUFALLSZAHL : USINT (*Zahl 1...6 erzeugen*) VAR usiWuerfelzahlNeu: USINT; END_VAR WHILE usiWuerfelzahlNeu < 1 OR usiWuerfelzahlNeu > 6 DO usiWuerfelzahlNeu:= REAL_TO_USINT(OSCAT_BASIC.RDM(last:= 0)*10.0); END_WHILE; FC_ZUFALLSZAHL:= usiWuerfelzahlNeu; FUNCTION_BLOCK PIG VAR_INPUT xSPIELEN, xWUERFELN, xNEUES_SPIEL:BOOL; END_VAR VAR_OUTPUT usiWUERFELZAHL: USINT; uiSPIELSTAND: UINT; END_VAR VAR usiSchrittNr:USINT; instWUERFELN_TRIG_R:Standard.R_TRIG; instWUERFELN_TRIG_F:Standard.F_TRIG; usiWuerfelzahlNeu: USINT; END_VAR CASE usiSchrittNr OF 0: IF instWUERFELN_TRIG_R.Q AND xSPIELEN THEN usiSchrittNr:= 1; END_IF; 1: usiWUERFELZAHL:= FC_ZUFALLSZAHL();(*Funktionsaufruf*) IF usiWUERFELZAHL > 1 THEN usiSchrittNr:= 2; END_IF; IF usiWUERFELZAHL = 1 THEN usiSchrittNr:= 3; END_IF; 2: IF instWUERFELN_TRIG_F.Q AND xSPIELEN THEN uiSPIELSTAND:= uiSPIELSTAND + usiWUERFELZAHL; END_IF; IF instWUERFELN_TRIG_R.Q AND xSPIELEN THEN usiSchrittNr:= 1; END_IF; IF xNEUES_SPIEL THEN usiSchrittNr:= 4; END_IF; 3: uiSPIELSTAND:= 0; IF instWUERFELN_TRIG_R.Q AND xSPIELEN THEN usiSchrittNr:= 1; END_IF; IF xNEUES_SPIEL THEN usiSchrittNr:= 4; END_IF; 4: uiSPIELSTAND:= 0; usiWUERFELZAHL:= 0; IF instWUERFELN_TRIG_R.Q AND xSPIELEN THEN usiSchrittNr:= 1; END_IF; END_CASE; =======================================================================