8. Lösungen: Abgeleitete Funktionen (FCs), Bibliotheken, Rezepturen ======================================================================= Aufgabe 8.2 FC MUX_INT benutzen Bibliothek "ANALOG" über den Bibliotheksverwalter hinzufügen VAR_GLOBAL iTemp1 AT %IW0:INT; iTemp2 AT %IW1:INT; iTemp3 AT %IW2:INT; iTemp4 AT %IW3:INT; iDruck1 AT %IW4:INT; iDruck2 AT %IW5:INT; iDruck3 AT %IW6:INT; iDruck4 AT %IW7:INT; END_VAR Beispiel einer Rezeptur .iTemp1:= -100 .iTemp2:= 200 .iTemp3:= 500 .iTemp4:= 1500 .iDruck1:= 10000 .iDruck2:= 15000 .iDruck3:= 20000 .iDruck4:= 32760 PROGRAM MESSWERTE (*Task 100ms*) (*Zeigt 4 Messwerte abhängig von einer Auswahlvariable an*) (*Autor: Schmitt, Version 1.0, Bibliothek: ANALOG.lib*) VAR iAuswahl_Temp, iAnzeige_Temp:INT; iAuswahl_Druck, iAnzeige_Druck:INT; END_VAR iAnzeige_Temp:= MUX_INT( iMW1:= iTemp1, iMW2:= iTemp2, iMW3:= iTemp3, iMW4:= iTemp4, iSEL:= iAuswahl_Temp);(*in der Visualisierung wird skaliert*) (*Werte skaliert übergeben*) iAnzeige_Druck:= MUX_INT( iMW1:= REAL_TO_INT(INT_TO_REAL(iDruck1) * 10.0/32760.0), iMW2:= REAL_TO_INT(INT_TO_REAL(iDruck2) * 10.0/32760.0), iMW3:= REAL_TO_INT(INT_TO_REAL(iDruck3) * 10.0/32760.0), iMW4:= REAL_TO_INT(INT_TO_REAL(iDruck4) * 10.0/32760.0), iSEL:= iAuswahl_Druck); _______________________________________________________________________ Aufgabe 8.3 Analogwertverarbeitung 1, SCALE FUNCTION SCALE : REAL VAR_INPUT iX:INT; rY_MAX,rY_MIN:REAL; END_VAR SCALE:=(rY_MAX-rY_MIN)/32760.0*iX+rY_MIN;(*Implizierte Typenumwandlung*) oder FUNCTION SCALE : REAL VAR_INPUT iX:INT; rY_MAX,rY_MIN:REAL; END_VAR VAR r_m:REAL;(*Steigung*) END_VAR r_m:= (rY_MAX – rY_MIN)/32760.0; SCALE:= r_m * iX + rY_MIN; PROGRAM PLC_PRG(*Testen der Funktion*) VAR iDruck_Per:INT;(*Speicher*) rDruck:REAL; END_VAR rDruck:=SCALE(iX:= iDruck_Per, rY_MAX:= 10.0, rY_MIN:= 6.0); _______________________________________________________________________ Übung 8.1 Analogwertverarbeitung 2, SCALE VAR_GLOBAL iTemp_Per AT %IW0 :INT;(*0...32760*) END_VAR PROGRAM PLC_PRG (*Skalieren 0...32760 -> -100...400*) (*Autor: xxx, Version: 1.0, Bibliothek: ANALOG.lib*) VAR r_Temp:REAL; END_VAR r_Temp:=SCALE(iX:=iTemp_Per, rY_MAX:=400.0, rY_MIN:=-100.0); _______________________________________________________________________ Übungen 8.2 a) FC-Radizieren_INT VAR_GLOBAL iMesswert1:INT:=25; iMesswert2:INT:=36; iOut1, iOut2:INT; END_VAR PROGRAM PLC_PRG (*messwert 1 und 2 radizieren und in iOut1 und 2 speichern*) VAR END_VAR iOut1:=RADIZIERER_INT(iMesswert1); iOut2:=RADIZIERER_INT(iMesswert2); FUNCTION RADIZIERER_INT : INT VAR_INPUT iIN:INT; END_VAR VAR rMw_in, rMw_out:REAL; END_VAR rMw_in:= INT_TO_REAL(iIN); rMw_out:= SQRT(rMw_in); RADIZIERER_INT:=REAL_TO_INT(rMw_out); _______________________________________________________________________ Übungen 8.2 b) SIN berechnen bei einem Winkel in Grad FUNCTION SIN_GRAD : REAL (*berechnet den SIN bei einem Winkel in Grad*) VAR_INPUT rIN:REAL; END_VAR VAR pi:REAL:= 3.14159; rBogenmass:REAL; END_VAR (*Grad in Bogenmaß*) rBogenmass:= 2*pi*(rIN/360.0); (*Rückgabewert berechnen*) SIN_GRAD:= SIN(rBogenmass); PROGRAM PLC_PRG (*Test der FC-SIN_GRAD()*) VAR a,b,c,d: REAL; END_VAR a:= SIN_GRAD(90.0); b:= SIN_GRAD(60.0); c:= SIN_GRAD(30.0); (*der Standard SIN-FC muss der Winkel im Bogenmaß übergeben werden*) d:= SIN(2 * 3.14159/4);(*90°*) _______________________________________________________________________ Übungen 8.2 c) Bahnkorrektur Lösung 1 FUNCTION ALARM : BOOL VAR_INPUT xSENSOR_L, xSENSOR_M, xSENSOR_R:BOOL; END_VAR xALARM:= (NOT xSENSOR_L AND NOT xSENSOR_M AND NOT xSENSOR_R) OR(xSENSOR_L AND xSENSOR_R); FUNCTION LINKS : BOOL VAR_INPUT xSENSOR_L, xSENSOR_M, xSENSOR_R:BOOL; END_VAR xLINKS:= xSENSOR_L AND NOT xSENSOR_R; FUNCTION RECHTS : BOOL VAR_INPUT xSENSOR_L, xSENSOR_M, xSENSOR_R:BOOL; END_VAR xRECHTS:= NOT xSENSOR_L AND xSENSOR_R; PROGRAM PLC_PRG (*Test*) VAR B1 AT %IX2.0:BOOL;(*Sensor links*) B2 AT %IX2.1:BOOL;(*Sensor mitte*) B3 AT %IX2.2:BOOL;(*Sensor rechts*) P1_Alarm AT %QX0.0:BOOL;(*Anzeige*) K1_Links AT %QX0.1:BOOL;(*Korrektur*) K2_Rechts AT %QX0.2:BOOL;(*Korrektur*) END_VAR P1_Alarm:= ALARM(xSENSOR_L:=B1, xSENSOR_M:=B2, xSENSOR_R:=B3); K1_Links:= LINKS(xSENSOR_L:=B1, xSENSOR_M:=B2, xSENSOR_R:=B3); K2_Rechts:= RECHTS(xSENSOR_L:=B1, xSENSOR_M:=B2, xSENSOR_R:=B3); Lösung 2: Bahnkorrektur mit anwenderdef. Datentypen, der Rückgabewert ist vom Datentyp KORREKTUR TYPE typKORREKTUR : STRUCT li, re, ok, alarm:BOOL; END_STRUCT END_TYPE FUNCTION FcBAHNKORREKTUR : typKORREKTUR VAR_INPUT SENSOR_li, SENSOR_mitte, SENSOR_re:BOOL; END_VAR FcBAHNKORREKTUR.li:=SENSOR_li AND NOT SENSOR_mitte AND NOT SENSOR_re OR SENSOR_li AND SENSOR_mitte AND NOT SENSOR_re; FcBAHNKORREKTUR.re:=NOT SENSOR_li AND NOT SENSOR_mitte AND SENSOR_re OR NOT SENSOR_li AND SENSOR_mitte AND SENSOR_re; FcBAHNKORREKTUR.ok:=NOT SENSOR_li AND SENSOR_mitte AND NOT SENSOR_re; FcBAHNKORREKTUR.alarm:=NOT SENSOR_li AND NOT SENSOR_mitte AND NOT SENSOR_re OR SENSOR_li AND NOT SENSOR_mitte AND SENSOR_re OR SENSOR_li AND SENSOR_mitte AND SENSOR_re; PROGRAM PLC_PRG (*************************************************** Bahnkorrektur aus Übung 3.3 als Funktion mit anwenderdefiniertem Datentyp. Verändern Sie den Wert von B1...B3 nach dem Einloggen und Start, beobachten Sie P1...K2. *************************************************************************) VAR B1 AT %IX0.0:BOOL;(*Sensor links*) B2 AT %IX0.1:BOOL;(*Sensor mitte*) B3 AT %IX0.2:BOOL;(*Sensor rechts*) P1_Alarm AT %QX0.0:BOOL;(*Anzeige*) K1_Links AT %QX0.1:BOOL;(*Korrektur*) K2_Rechts AT %QX0.2:BOOL;(*Korrektur*) ROBOTER_1:typKORREKTUR; END_VAR (**** Funktionsaufruf- Werte übergeben ****) ROBOTER_1:= FcBAHNKORREKTUR(SENSOR_li:=B1, SENSOR_mitte:=B2, SENSOR_re:=B3); (**** Ergebnis ins PAA schreiben ****) P1_Alarm:=ROBOTER_1.alarm; K1_Links:=ROBOTER_1.li; K2_Rechts:=ROBOTER_1.re; _______________________________________________________________________ Übungen 8.3 Volumenberechnung mit anwenderdefiniertem Datentyp als Parametertyp TYPE KUGEL : STRUCT rFuellhoehe, rDurchmesser, rVolumen:REAL; END_STRUCT END_TYPE FUNCTION VOLUMEN : REAL VAR_INPUT ABMESSUNGEN:KUGEL; END_VAR VAR Pi:REAL:=3.14; END_VAR VOLUMEN:=Pi*EXPT(ABMESSUNGEN.rFuellhoehe, 2)* (ABMESSUNGEN.rDurchmesser/2.0 - ABMESSUNGEN.rFuellhoehe/3.0); PROGRAM PLC_PRG (******************************************************************* Volumenberechnung mit anwenderdefiniertem Datentyp als Parametertyp des Füllvolumens von drei kugelförmigen Tanks. Geben Sie zum Test die Füllhohe und den Durchmesser ein, Überprüfen Sie das Füllvolumen. ********************************************************************) VAR Tank:ARRAY[1..3] OF KUGEL; i: INT; END_VAR FOR i:=1 TO 3 DO Tank[i].rVolumen:=VOLUMEN(ABMESSUNGEN:=Tank[i]); END_FOR; _______________________________________________________________________ Übung 8.4 Bandanlage a) TYPE BAND : STRUCT OUT_LEFT,OUT_RIGHT,OUT_SLOW:BOOL; END_STRUCT END_TYPE FUNCTION FC_BAND : BAND VAR_INPUT LEFT,SLOW,RIGHT:BOOL; END_VAR VAR END_VAR FC_BAND.OUT_RIGHT:=NOT LEFT AND NOT SLOW AND RIGHT OR NOT LEFT AND SLOW AND RIGHT; FC_BAND.OUT_LEFT:=LEFT AND NOT SLOW AND NOT RIGHT OR LEFT AND SLOW AND NOT RIGHT; FC_BAND.OUT_SLOW:=LEFT AND SLOW AND NOT RIGHT OR NOT LEFT AND SLOW AND RIGHT; PROGRAM PLC_PRG VAR S0_Links AT %IX2.0:BOOL;(*Öffner*) S1_Schleich AT %IX2.1:BOOL;(*vor*) S2_Rechts AT %IX2.2:BOOL;(*zurück*) Q1_vor AT %QX0.4:BOOL; Q2_zur AT %QX0.5:BOOL; Q3_schleich AT %QX0.6:BOOL; Band1:Band; END_VAR Band1:=FC_BAND(LEFT:=S0_Links, SLOW:=S1_Schleich, RIGHT:=S2_Rechts); Q1_vor:=Band1.OUT_RIGHT; Q2_zur:=Band1.OUT_LEFT; Q3_schleich:=Band1.OUT_SLOW; b) mit WebVisu Type und FC wie a) Rufen Sie das MAIN-Programm alle 10ms auf damit Übertragungszeit für die Webvisu zur verfügung steht. Achtivieren Sie in den Zielsystemeinstellungen die Webvisualisierung. PROGRAM MAIN VAR S0_L_visu, S1_S_visu, S2_R_visu:BOOL; Q1_vor AT %QX0.4:BOOL; Q2_zur AT %QX0.5:BOOL; Q3_schleich AT %QX0.6:BOOL; Band1:Band; END_VAR Band1:=FC_BAND(LEFT:= S0_L_visu, SLOW:= S1_S_visu, RIGHT:= S2_R_visu); Q1_vor:=Band1.OUT_RIGHT; Q2_zur:=Band1.OUT_LEFT; Q3_schleich:=Band1.OUT_SLOW; =======================================================================