FUNCTION_BLOCK "MHMOmniSchleuse" TITLE = HM-Omni-Schleuse (Schrittkette) { S7_Optimized_Access := 'FALSE' } AUTHOR : IBAE FAMILY : Module NAME : MHMOmni //SCL-Portierung des AWL-Bausteins FB1274 "MHMOmniSchleuse" (verhaltensgleich). //Statische Daten (SAVE/Para/Status2/Schleuse/Dyn) sind unveraendert -> Instanz-DBs bleiben gueltig. // //ABWEICHUNGEN ZUM AWL-ORIGINAL (bei Inbetriebnahme pruefen!): // - DatenOut-Aufrufe verwenden lokale Puffer statt der Merker-Scratch-Bereiche // MW200/M220../MB199/MW196 (Ergebnis identisch, keine Nebenwirkung auf Merker). // Die Merker-Schnittstelle zu den indirekten FCs (MW190..MW198, MD182, MD192, // M180.x) und die Fehler-Schnittstelle MW200/M200.x/M201.x bleiben erhalten. // - Erfolg von "DatenOut" wird ueber RE_VAL Bit7 statt BR/JBI erkannt // (bei PARA=0-Suchen aequivalent). // - Indirekte Aufrufe UC FC[LeserFC/ZielFC/DraussenFC] sind als CASE ueber die // projektierten FC-Nummern ausgefuehrt (Station UH06). // - Registerindirekte Zugriffe auf Weichen-/Leser-DB sind durch PEEK/POKE ersetzt. // - NW21 ("Schrittkette anhalten") ist im Original durch CLR+JU deaktiviert -> entfaellt. // - NW10-Schritt "NoLesung": das AWL verglich HMI.TrolleyID_Input mit einem // undefinierten Akku-Altwert; hier wird die beabsichtigte Pruefung // (TrolleyID_Input <> 0) verwendet. VERHALTEN PRUEFEN! VAR_INPUT Schleusen_Nr : Int; // Aufruf fuer Schleuse ErrQuit : Bool; // Ablaufstoerung quittieren B_VorSchleuse : Bool; // Sensor Trolley faehrt in Bereich B_InSchleuse : Bool; // Sensor Trolley ist in Schleuse B_AusSchleuse : Bool; // Sensor Trolley hat Schleuse verlassen B_Stau_raus : Bool; // Sensor Stau im Bereich rausfahren Start_Ok : Bool; // Starten ist erlaubt Antrieb_Schleuse_aktiv : Bool; // Kreisel-Antrieb aktiv Antrieb_plus_aktiv : Bool; // Kreisel-Antrieb plus aktiv "Schleuse_geöffnet" : Bool; // Schleuse hat geoeffnet RestZeit_Bereich_plus : Int := 999; // Bereich +1: Restzeit bis AFS stoppt (s) END_VAR VAR_OUTPUT Y_Schleuse_Auf : Bool; // Schleuse oeffnen Error : Word; // Stoerungen uebergeben END_VAR VAR_IN_OUT Antrieb_Schleuse_vor : Bool; // Schleusen-Antrieb einschalten Antrieb_Schleuse_start : Bool; // Schleusen-Antrieb mit Zeit starten Antrieb_Schleuse_stop : Bool; // Schleusen-Antrieb stoppen Antrieb_Schleuse_PS : Bool; // Schleusen-Antrieb Energie sparen Antrieb_plus_vor : Bool; // Antrieb plus einschalten Antrieb_plus_start : Bool; // Antrieb plus mit Zeit starten hStOk : Bool; // Anzeige Start n. Stoerung aktivieren END_VAR VAR SAVE : Struct Weichen_DB : Int; // Weichen-FIFO-DB Weichen_DW : Int; // Weichen-FIFO-DW "Weiche+1" : Int; // Weiche +1, wo reserviert wurde Frei18 : Int; Frei20 : Int; END_STRUCT; Para : Struct // Parameter Schleusen_DL_DB : Int; // Einsprung Schleuse-Datenliste-DB Weichen_DL_DB : Int; // Einsprung Weichen-Datenliste-DB Leser_DL_DB : Int; // Einsprung Leser-Datenliste-DB END_STRUCT; Status2 : Struct Trolley_an_Schleuse : Bool; // Trolley ist an Schleuse "Warten_3.V" : Bool; // Warten auf 3.V "2.Lesung_aktiv" : Bool; // 2.Lesung erfolgt "3.Lesung_aktiv" : Bool; // 3.Lesung erfolgt "TrolleyPos_übergeben" : Bool; // Trolley-Pos. uebergeben "Warten_4.V" : Bool; // Warten auf 4.V Ausfahrzeit_lernen : Bool; // Ausfahrzeit lernen "Weichen-Schritt" : Bool; // Schritt 13-17 aktiv (Weiche evtl. belegen) Trolley_ist_draussen : Bool; // Rueckmeldung von Sensor / Weiche Einfahrzeit_lernen : Bool; // Einfahrzeit lernen Telegramm_gesendet : Bool; // Telegramm wurde in Send-FIFO eingetragen END_STRUCT; Schleuse : "UDLHMOmniSchleuse"; // Statische Schleusendaten (aus DL) Dyn : Struct // Dynamische Daten Status : Struct "Trolley_fährt_in_Schleuse" : Bool; // Trolley faehrt in Schleuse Trolley_wartet_Lesung : Bool; // Trolley wartet auf Auftrag "Trolley_wartet_auf_Ziel-FC" : Bool; "Trolley_wartet_auf_Weiche+1" : Bool; "Trolley_wartet_Bereich+1" : Bool; // Trolley wartet auf Bereich +1 "Trolley_fährt_aus" : Bool; // Trolley faehrt aus MindestZeit_ok : Bool; // Schleuse ist MindestZeit geoeffnet Trolley_draussen : Bool; // Trolley ist ausgefahren Leser_triggern : Bool; SF_angefordert : Bool; Kein_Stop_mehr : Bool; // Kein Stop mehr, Antrieb soll starten "Trolley_fährt_rückwärts" : Bool; // Trolley in Schleuse rueckwaerts erkannt Weiche_geschaltet : Bool; "Trolley ausserhalb Weiche" : Bool; // Trolley hat Weiche verlassen (von Weiche) Error_aktiv : Bool; // Stoerung vorhanden Reset_aktiv : Bool := TRUE; // Reset aktiv END_STRUCT; TrolleyID_Schleuse : DInt; // Trolley-Nr in der Schleuse Trolley_EndZiel : Word; // Trolley-EndZiel Trolley_ZwischenZiel : Word; // Trolley-ZwischenZiel Trolley_ShopGroup : DInt; // Trolley-ShopGroup Weichen_Ziel : Word; // Weichen-Ziel (fuer WeichenModul von Ziel-FC) TrolleyID_Eingefahren : DInt; // Trolley-Nr von Bereich -1 gemeldet TrolleyID_ausgefahren : DInt; // TrolleyID des ausgefahrenen Trolleys HMI : Struct TrolleyID_in_Schleuse : DInt; // Trolley-Nr in Schleuse (IN:PLC, OUT:PLC) TrolleyID_Input : DInt; // Trolley-Nr Input (IN:HMI, OUT:PLC) Schleuse_resetten : Bool; // Schleuse resetten (IN:HMI, Out:PLC) END_STRUCT; Sk : "USk_ILS"; // Status der Schrittkette Leser : Struct "IN" : Struct xOutReadyForNewScan : Bool; // DBX10.1: Reader ist bereit fuer Leseanforderung xOutReadingDone : Bool; // DBX10.0: Lesevorgang abgeschlossen / Handshake raus xOutCodeGood : Bool; // DBX278.0: Gute Lesung xOutCodeBad : Bool; // DBX278.1: Schlechte Lesung nOutBarcode : DInt; // DBD12: Trolley ID END_STRUCT; "OUT" : Struct xInStartReading : Bool; // DBX4.1: Starte Lesevorgang xInHandshakeDone : Bool; // DBX4.2: Handshake Daten abgeholt xInErrQuit : Bool; // DBX4.4: Fehler ruecksetzen xInReset : Bool; // DBX4.5: Allgemeines Ruecksetzen des Bausteins END_STRUCT; END_STRUCT; TrolleyID_unbekannt_Schleuse : DInt; // TrolleyID unbekannt (Trolley in Schleuse) Rueckmld : Struct RET_VAL_BLKMOV_Schleuse : Int; // Rueckmeldung nach BLKMOV-Aufruf RET_VAL_DL_Schleuse : Byte; RET_VAL_DL_Weiche : Byte; // Rueckmeldung nach DatenOut-Aufruf RET_VAL_DL_Leser : Byte; // Rueckmeldung nach DatenOut-Aufruf END_STRUCT; Error : "UErrHMOmniSchleuse"; Stau_Zeit : Int; // Sensor B_VorSep ist belegt [100ms] Mindest_Zeit : Int; // Sensor B_VorSep ist frei [100ms] Leer_Zeit : Int; Stop_Ursache : Word; // Stop-Stelle: Nw + Position Vereinzelungstakte : DInt; // Anzahl der getaetigten Vereinzelungstakte ZwischenZiel_eingefahren : Word; // Trolley-ZwischenZiel von Bereich -1 Ohne_B : Int; SAVE2 : Struct Leser_DB : Int; // Leser-FIFO-DB Leser_DD : DInt; // Leser-FIFO-DD END_STRUCT; WarteZeit_PS : Int; Restzeit_bis_Schleuse : Int; Res200 : Array[1..16] of Int; // Reserve END_STRUCT; END_VAR VAR_TEMP Ueb_akt : Bool; // Ueberwachungszeit aktivieren Weiter : Bool; // Weiterschaltbedingung ist erfuellt Warte_neu : Bool; // Wartezeit neu triggern Warte_stop : Bool; // Wartezeit stoppen "Kein_Weichenbereich +1" : Bool; "Reservierung_Weiche+1_aktiv" : Bool; Leser_Zugriff : Bool; // Leser-Zugriff vorhanden LeserFC_vorhanden : Bool; ZielFC_vorhanden : Bool; DraussenFC_vorhanden : Bool; "TrolleyID_Bereich-1" : Bool; // Trolley-ID von Bereich -1 gemeldet Einfahrzeit_nicht_bekannt : Bool; LeserFC : Int; // Leser-FC ZielFC : Int; // Ziel-FC DraussenFC : Int; // Draussen-FC tReVal : Byte; // Rueckmeldung DatenOut (statt MB199) tPosition : Int; // Position von DatenOut (statt MW196) tSuchInt : Int; // Suchdaten 1 Wort (statt MW200) tSuchID : DInt; // Suchdaten TrolleyID (statt MD220) tOutDaten : Array[0..19] of Word; // OutDaten-Puffer (statt M220..) tByte : Byte; // Byte-Zwischenwert (statt MB200-Scratch) tNeuSchritt : Int; // Uebergabe an Neu_Mig tWartezeit : Int; // Uebergabe an Plus (*10ms) tUebzeit : Int; // Uebergabe an tueb (*1s) tWeichDb : DInt; // Weichen-DB fuer PEEK/POKE tWeichBase : DInt; // Weichen-DW Basisoffset tLeserDb : DInt; // Leser-DB fuer PEEK/POKE tLeserBase : DInt; // Leser-DD Basisoffset END_VAR BEGIN REGION NW1: Parameter-Uebergabe #Para.Schleusen_DL_DB := 274; // Einsprung Schleuse-DL (vor Aufruf uebergeben!) #Para.Weichen_DL_DB := 279; // Einsprung Weichen-DL #Para.Leser_DL_DB := 273; // Einsprung Leser-DL END_REGION REGION NW2: Anzeige OP IF #ErrQuit THEN #Dyn.Sk.Err_Uebzeit := FALSE; // Ueberwachungszeit abgelaufen quittieren END_IF; IF NOT #Dyn.Sk.Bereich_ok THEN #Dyn.Sk.OP_Schritt := 252; // Bereichsstop / Not-Aus ELSIF NOT #Dyn.Sk.Auto_akt AND NOT #Dyn.Sk.Hand_akt THEN #Dyn.Sk.OP_Schritt := 253; // Keine Betriebsart ELSIF #Dyn.Sk.Hand_akt THEN #Dyn.Sk.OP_Schritt := 255; // Handbetrieb aktiv ELSE #Dyn.Sk.OP_Schritt := #Dyn.Sk.Akt_Schritt; // Aktiver Schritt END_IF; END_REGION REGION NW3: Out-Bits zum Zuruecksetzen (jeden Zyklus neu) #Y_Schleuse_Auf := FALSE; #Dyn.Status.Trolley_wartet_Lesung := FALSE; #Dyn.Status."Trolley_wartet_auf_Ziel-FC" := FALSE; #Dyn.Status."Trolley_wartet_auf_Weiche+1" := FALSE; #Dyn.Status."Trolley_wartet_Bereich+1" := FALSE; #Dyn.Status."Trolley_fährt_aus" := FALSE; #Dyn.Status.Trolley_draussen := FALSE; #Leser_Zugriff := FALSE; #Status2."Weichen-Schritt" := FALSE; #Dyn.Status.Reset_aktiv := #Dyn.Sk.Reset_Akt; END_REGION REGION NW4: HMI-Zeug IF #Dyn.HMI.Schleuse_resetten THEN // von HMI #Dyn.HMI.Schleuse_resetten := FALSE; #Dyn.Sk.Reset := TRUE; // SK zuruecksetzen END_IF; #Dyn.HMI.TrolleyID_in_Schleuse := #Dyn.TrolleyID_Schleuse; // an HMI END_REGION REGION NW5: Schrittkette zuruecksetzen IF #ErrQuit THEN #Dyn.Sk.Err_Uebzeit := FALSE; END_IF; IF #Dyn.Sk.Reset THEN // SK zuruecksetzen #Dyn.Sk.Akt_Schritt := 0; // Schritt 0: Warten #Dyn.Sk.Terr_Zelle := 0; // Zeitwerte loeschen #Dyn.Sk.Tok_Zelle := 0; #Dyn.Error.Err_BLKMov := FALSE; #Dyn.Sk.Reset := FALSE; #Dyn.Sk.Err_Schritt := FALSE; #Dyn.Sk.Err_Uebzeit := FALSE; #Status2.Telegramm_gesendet := FALSE; #Dyn.Sk.Reset_Akt := TRUE; // Reset ist aktiv #Dyn.Error.Schleuse_DL := FALSE; #Dyn.Error.Undef_Schleuse := FALSE; #Dyn.Error.Err_Trolley_nicht_in_Schleuse := FALSE; #Dyn.Error.Err_Uebzeit := FALSE; #Dyn.Error.Err_Schritt := FALSE; #Dyn.Error.Err_Stau_Einfahrt := FALSE; #Dyn.Error.Err_Trolley_raus := FALSE; #Dyn.Error.Err_Raus_Sensor := FALSE; #Dyn.Error.Err_Ziel := FALSE; #Dyn.Error.Err_Weichen_DL := FALSE; #Dyn.Error.Err_Undef_Weiche := FALSE; #Dyn.Error.Err_Weiche_belegt := FALSE; #Dyn.Error.Err_Kein_LeseErgebnis := FALSE; #Dyn.Error.Err_Leser_nicht_bereit := FALSE; #Dyn.Leser."IN".nOutBarcode := 0; #Dyn.Stau_Zeit := 0; #Dyn.Mindest_Zeit := 0; #SAVE."Weiche+1" := 0; #SAVE.Weichen_DB := 0; #SAVE.Weichen_DW := 0; #Dyn.SAVE2.Leser_DB := 0; #Dyn.SAVE2.Leser_DD := 0; #Schleuse.Schleusen_Nr := 0; // Damit statische Werte neu aus Datenbank geholt werden! GOTO mRET; END_IF; END_REGION REGION NW6: Stoerungen nach aussen uebergeben (Schnittstelle MW200) "MW200" := 16#0000; "M200.0" := #Dyn.Error.Schleuse_DL; // Schleuse-Datenliste fehlerhaft "M200.1" := #Dyn.Error.Undef_Schleuse; // undefinierte Schleuse "M200.2" := #Dyn.Error.Err_Trolley_nicht_in_Schleuse; // Trolley faehrt nicht in Schleuse #Dyn.Error.Err_Uebzeit := #Dyn.Sk.Err_Uebzeit; // Ueberwachungszeit ist abgelaufen "M200.3" := #Dyn.Sk.Err_Uebzeit; IF NOT #Dyn.Sk.Err_Uebzeit THEN // AWL: NEG + R #Dyn.Sk.Err_Uebzeit_AnzOk := FALSE; END_IF; #Dyn.Error.Err_Schritt := #Dyn.Sk.Err_Schritt; // Schritt-Nummer ist nicht definiert "M200.4" := #Dyn.Sk.Err_Schritt; "M200.5" := #Dyn.Error.Err_Stau_Einfahrt AND NOT #B_InSchleuse AND NOT #Y_Schleuse_Auf; "M200.6" := #Dyn.Error.Err_BLKMov; // Error bei Block kopieren "M200.7" := #Dyn.Error.Err_Trolley_raus; // Trolley faehrt nicht aus "M201.0" := #Dyn.Error.Err_Raus_Sensor; // Raus-/Belade-Sensor wird nicht erreicht "M201.1" := #Dyn.Error.Err_Ziel; // Trolley-Ziel nicht bekannt "M201.2" := #Dyn.Error.Err_Weichen_DL; // Weichen-Datenliste fehlerhaft "M201.3" := #Dyn.Error.Err_Undef_Weiche; // undefinierte Weiche "M201.4" := #Dyn.Error.Err_Weiche_belegt; // Weiche bleibt belegt "M201.5" := #Dyn.Error.Err_Kein_LeseErgebnis; "M201.6" := #Dyn.Error.Err_Leser_nicht_bereit; "M201.7" := #Dyn.Error.Barcode_nicht_bekannt; // Andere Meldung als Ueberwachungszeit aktiv? IF (("MW200" AND 2#1111_0111_1111_1111) <> 16#0000) OR NOT #Dyn.Sk.Err_Uebzeit_AnzOk THEN "M200.3" := FALSE; // Ueb.Zeit-Meldung nicht an PC senden END_IF; IF #Dyn.Sk.Err_Uebzeit THEN #Dyn.Sk.Err_Uebzeit_AnzOk := TRUE; // Stoerung anzeigen ok, da 2.Zyklus aktiv! END_IF; #Error := "MW200"; // Schnittstelle nach aussen // Stoerung vorhanden: #Dyn.Status.Error_aktiv := ("MW200" <> 16#0000); IF #Dyn.Status.Error_aktiv THEN #hStOk := TRUE; END_IF; // Antrieb stoppen: IF NOT #Dyn.Sk.Auto_akt OR #Dyn.Sk.Hand_akt OR NOT #Dyn.Sk.Bereich_ok THEN #Antrieb_Schleuse_stop := TRUE; // SystemVoraussetzungen fehlen END_IF; // Stoerungen pro Zyklus neu erzeugen: #Dyn.Error.Schleuse_DL := FALSE; #Dyn.Error.Undef_Schleuse := FALSE; #Dyn.Error.Err_Schritt := FALSE; #Dyn.Error.Err_BLKMov := FALSE; #Dyn.Error.Err_Raus_Sensor := FALSE; #Dyn.Error.Err_Ziel := FALSE; #Dyn.Error.Err_Weichen_DL := FALSE; #Dyn.Error.Err_Undef_Weiche := FALSE; #Dyn.Error.Err_Weiche_belegt := FALSE; #Dyn.Error.Barcode_nicht_bekannt := FALSE; IF NOT #Dyn.Sk.Err_Uebzeit THEN #Dyn.Error.Err_Trolley_nicht_in_Schleuse := FALSE; #Dyn.Error.Err_Trolley_raus := FALSE; #Dyn.Error.Err_Raus_Sensor := FALSE; END_IF; END_REGION REGION NW7: Statische Schleusen-Parameter holen IF #Schleuse.Schleusen_Nr = #Schleusen_Nr THEN // schon geholt #Dyn.Error.Schleuse_DL := FALSE; #Dyn.Error.Undef_Schleuse := FALSE; ELSE #tSuchInt := #Schleusen_Nr; // Search-Daten (AWL: MW200) "DatenOut"(SSDB := #Para.Schleusen_DL_DB, SSDW := 0, PARA := WORD#16#0000, SEARCHDATEN := #tSuchInt, RE_VAL => #tReVal, Position => #tPosition, OUTDATEN := #Schleuse); // Datensatz direkt in Schleuse-Struktur #Dyn.Rueckmld.RET_VAL_DL_Schleuse := #tReVal; IF #tReVal.%X7 THEN // AWL: JBI G_Ok (Datensatz gefunden) #Dyn.Error.Schleuse_DL := FALSE; #Dyn.Error.Undef_Schleuse := FALSE; #Dyn.Rueckmld.RET_VAL_BLKMOV_Schleuse := 0; // kein BLKMOV mehr noetig #Dyn.Error.Err_BLKMov := FALSE; #Dyn.Stop_Ursache := 16#A063; IF #Schleuse.Schleusen_Typ <> 1274 THEN // Dieser Aufruf-FB? #Dyn.Error.Undef_Schleuse := TRUE; // undefinierte Schleuse #Schleuse.Schleusen_Nr := 0; // Schleuse ungueltig! #Dyn.Stop_Ursache := 16#A064; END_IF; ELSIF #tReVal.%X0 THEN // kein Datenlisten-Bereich #Dyn.Error.Schleuse_DL := TRUE; // Schleusendatenbank fehlerhaft #Dyn.Stop_Ursache := 16#A061; ELSE #Dyn.Error.Undef_Schleuse := TRUE; // undefinierte Schleuse #Dyn.Stop_Ursache := 16#A062; END_IF; GOTO mRET; // in diesem Zyklus keine Schrittkette END_IF; END_REGION REGION NW8: Einsprung Weiche plus ermitteln IF #SAVE.Weichen_DB > 0 THEN // Einsprung-Zeiger bekannt #"Kein_Weichenbereich +1" := FALSE; ELSE #"Kein_Weichenbereich +1" := (#Schleuse.RausWeichen_Nr = 0); IF #"Kein_Weichenbereich +1" THEN #Dyn.Error.Err_Undef_Weiche := FALSE; // keine Weiche projektiert ELSE #tSuchInt := #Schleuse.RausWeichen_Nr; // Search-Daten "DatenOut"(SSDB := #Para.Weichen_DL_DB, SSDW := 0, PARA := WORD#16#0000, SEARCHDATEN := #tSuchInt, RE_VAL => #tReVal, Position => #tPosition, OUTDATEN := #tOutDaten); #Dyn.Rueckmld.RET_VAL_DL_Weiche := #tReVal; IF #tReVal.%X7 THEN // AWL: JBI W_Ok #SAVE.Weichen_DB := WORD_TO_INT(#tOutDaten[2]); // (AWL: MW224) IF #SAVE.Weichen_DB <= 0 THEN // sinnvoller Wert? #Dyn.Error.Err_Undef_Weiche := TRUE; // undefinierte Weiche ELSE #SAVE.Weichen_DW := WORD_TO_INT(#tOutDaten[3]); // (AWL: MW226) END_IF; ELSE #Dyn.Error.Err_Weichen_DL := #tReVal.%X0; // Weichen-Datenliste fehlerhaft IF NOT #tReVal.%X0 THEN #Dyn.Error.Err_Undef_Weiche := TRUE; // undefinierte Weiche END_IF; END_IF; END_IF; END_IF; END_REGION REGION NW9: Trolley in Schleuse entprellen IF #B_InSchleuse THEN #Dyn.Ohne_B := 0; ELSIF #Status2.Trolley_an_Schleuse AND "1s-Impuls" THEN #Dyn.Ohne_B := #Dyn.Ohne_B + 1; // Zeit ohne Sensor +1s IF #Dyn.Ohne_B >= 3 THEN // Nach ca. 3s #Status2.Trolley_an_Schleuse := FALSE; #Dyn.Ohne_B := 0; END_IF; END_IF; END_REGION REGION NW10: Antrieb zusaetzlich starten / stoppen / Schleuse geoeffnet IF #ErrQuit OR #"Schleuse_geöffnet" THEN #Antrieb_Schleuse_start := TRUE; // Antrieb starten #Antrieb_plus_start := TRUE; // Kreisel-Antrieb plus starten END_IF; IF #"Schleuse_geöffnet" THEN #Dyn.Status."Trolley_fährt_in_Schleuse" := FALSE; END_IF; IF #"Schleuse_geöffnet" AND (#Dyn.Status.Weiche_geschaltet OR #"Kein_Weichenbereich +1") AND #Schleuse.Parameter_allg.Antrieb_Plus_vorhanden THEN #Antrieb_plus_vor := TRUE; // Antrieb plus einschalten END_IF; IF #"Schleuse_geöffnet" AND (#Dyn.Status.Weiche_geschaltet OR #"Kein_Weichenbereich +1") AND (#Antrieb_plus_aktiv OR NOT #Schleuse.Parameter_allg.Antrieb_Plus_vorhanden) THEN #Antrieb_Schleuse_vor := TRUE; // Antrieb einschalten END_IF; // Trolley ist in Schleuse und wartet -> Energiesparen nach ca. 3s IF (#Status2.Trolley_an_Schleuse AND NOT #"Schleuse_geöffnet" AND (NOT #B_VorSchleuse OR #Dyn.Error.Err_Stau_Einfahrt) AND NOT #Dyn.Status.Kein_Stop_mehr) OR (#"Schleuse_geöffnet" AND #Schleuse.Parameter_allg.Antrieb_Plus_vorhanden AND NOT #Antrieb_plus_aktiv) THEN IF #Dyn.WarteZeit_PS < 3 THEN // ca. 3s rum? IF "1s-Impuls" THEN #Dyn.WarteZeit_PS := #Dyn.WarteZeit_PS + 1; END_IF; ELSE #Antrieb_Schleuse_PS := TRUE; // Antrieb in Energiesparen schalten END_IF; ELSE #Dyn.WarteZeit_PS := 0; END_IF; END_REGION REGION NW11: Einfahrzeit lernen #Einfahrzeit_nicht_bekannt := (#Schleuse.EinfahrZeit = 0) OR #Status2.Einfahrzeit_lernen; IF #Einfahrzeit_nicht_bekannt AND #B_VorSchleuse AND #Antrieb_Schleuse_aktiv AND NOT #B_InSchleuse AND NOT #"Schleuse_geöffnet" THEN #Status2.Einfahrzeit_lernen := TRUE; END_IF; IF #B_InSchleuse AND NOT #"Schleuse_geöffnet" THEN #Status2.Einfahrzeit_lernen := FALSE; END_IF; IF #Status2.Einfahrzeit_lernen THEN #Antrieb_Schleuse_vor := TRUE; // Antrieb einschalten END_IF; IF #Status2.Einfahrzeit_lernen AND #Antrieb_Schleuse_aktiv AND "1s-Impuls" THEN #Schleuse.EinfahrZeit := #Schleuse.EinfahrZeit + 1; END_IF; END_REGION REGION NW12: PS deaktivieren, da Trolley einfaehrt IF NOT #Einfahrzeit_nicht_bekannt THEN // also bekannt IF #B_VorSchleuse THEN // Neuer Trolley faehrt ein #Dyn.Restzeit_bis_Schleuse := #Schleuse.EinfahrZeit; END_IF; // Restzeit zurueckzaehlen: IF #Antrieb_Schleuse_aktiv AND NOT #"Schleuse_geöffnet" AND "1s-Impuls" THEN #Dyn.Restzeit_bis_Schleuse := #Dyn.Restzeit_bis_Schleuse - 1; IF #Dyn.Restzeit_bis_Schleuse <= 0 THEN #Dyn.Restzeit_bis_Schleuse := 0; // Minimum uebergeben END_IF; END_IF; // Trolley faehrt noch ein: IF (#Dyn.Restzeit_bis_Schleuse > 0) AND NOT #B_InSchleuse AND NOT #"Schleuse_geöffnet" THEN #Antrieb_Schleuse_vor := TRUE; // dadurch wird PS-Modus deaktiviert END_IF; END_IF; END_REGION REGION NW13: Ausfahrzeit lernen IF #Status2.Ausfahrzeit_lernen AND #Antrieb_Schleuse_aktiv AND "1s-Impuls" THEN #Schleuse.AusfahrZeit := #Schleuse.AusfahrZeit + 1; END_IF; END_REGION REGION NW14: Spezial-FCs vorhanden? #LeserFC := #Schleuse.Leser_FC; #LeserFC_vorhanden := (#LeserFC > 0); #ZielFC := #Schleuse.Ziel_FC; #ZielFC_vorhanden := (#ZielFC > 0); #DraussenFC := #Schleuse.Draussen_FC; #DraussenFC_vorhanden := (#DraussenFC > 0); END_REGION REGION NW15: Error: Stau Bereich-Eingang // TrolleyID zum Einfahren gemeldet / Trolley faehrt in Bereich: #"TrolleyID_Bereich-1" := (#Dyn.TrolleyID_Eingefahren <> 0); IF #"TrolleyID_Bereich-1" OR #B_VorSchleuse THEN #Dyn.Status."Trolley_fährt_in_Schleuse" := TRUE; END_IF; // Antrieb einschalten: IF #B_VorSchleuse AND NOT #B_InSchleuse AND NOT #"Schleuse_geöffnet" THEN #Antrieb_Schleuse_vor := TRUE; END_IF; IF #B_VorSchleuse THEN #Antrieb_Schleuse_start := TRUE; END_IF; // Sensor bei Bereichs-Einfahrt bleibt belegt? IF NOT #B_VorSchleuse OR #"Schleuse_geöffnet" THEN #Dyn.Error.Err_Stau_Einfahrt := FALSE; #Dyn.Stau_Zeit := 0; // StauZeit neu aufziehen ELSIF "1s-Impuls" AND NOT (#Schleuse.Parameter_allg.Antrieb_vorhanden AND NOT #Antrieb_Schleuse_aktiv) AND NOT #Dyn.Error.Err_Stau_Einfahrt THEN #Dyn.Stau_Zeit := #Dyn.Stau_Zeit + 1; // Sensor B_VorSep ist belegt [1s] IF #Dyn.Stau_Zeit >= 20 THEN // Stau-Zeit erreicht? #Dyn.Error.Err_Stau_Einfahrt := TRUE; // Stau bei Einfahrt #Dyn.Stau_Zeit := 0; END_IF; END_IF; END_REGION REGION NW16: Schleuse Mindestzeit geoeffnet/frei IF (#Dyn.Sk.Akt_Schritt < 3) OR (#Dyn.Sk.Akt_Schritt > 6) OR NOT #"Schleuse_geöffnet" THEN #Dyn.Status.MindestZeit_ok := FALSE; #Dyn.Mindest_Zeit := 0; // FreiZeit neu aufziehen ELSIF NOT ((#Schleuse.Parameter_allg.Antrieb_vorhanden AND NOT #Antrieb_Schleuse_aktiv) OR (#Schleuse.Parameter_allg.Antrieb_Plus_vorhanden AND NOT #Antrieb_plus_aktiv) OR #Dyn.Status.MindestZeit_ok OR NOT "1s-Impuls") THEN #Dyn.Mindest_Zeit := #Dyn.Mindest_Zeit + 1; IF #Dyn.Mindest_Zeit >= #Schleuse.Mindeszeit_Schleuse_geoeffnet THEN // Mindest-Zeit erreicht? #Dyn.Status.MindestZeit_ok := TRUE; #Dyn.Mindest_Zeit := 0; END_IF; END_IF; END_REGION REGION NW17: Schleuse: Trolley ist draussen (Sensor/Weiche) IF (#Dyn.Sk.Akt_Schritt < 5) OR (#Dyn.Sk.Akt_Schritt > 6) OR NOT #"Schleuse_geöffnet" THEN #Status2.Trolley_ist_draussen := FALSE; #Status2.Ausfahrzeit_lernen := FALSE; ELSE // Trolley ist draussen sofort (Rueckmeldung von Sensor/Weiche): IF (#B_AusSchleuse AND #Schleuse.Parameter_allg.B_AusSep_vorhanden) OR (#Dyn.Status."Trolley ausserhalb Weiche" AND NOT #"Kein_Weichenbereich +1") THEN #Status2.Trolley_ist_draussen := TRUE; END_IF; END_IF; END_REGION REGION NW18: Einsprung Leser ermitteln IF #Dyn.SAVE2.Leser_DB > 0 THEN // Einsprung-Zeiger bekannt #Leser_Zugriff := TRUE; ELSIF WORD_TO_INT(#Schleuse.Leser_ID) <> 0 THEN // Leser angegeben? #tSuchInt := WORD_TO_INT(#Schleuse.Leser_ID); // Search-Daten "DatenOut"(SSDB := #Para.Leser_DL_DB, SSDW := 0, PARA := WORD#16#0000, SEARCHDATEN := #tSuchInt, RE_VAL => #tReVal, Position => #tPosition, OUTDATEN := #tOutDaten); #Dyn.Rueckmld.RET_VAL_DL_Leser := #tReVal; IF #tReVal.%X7 THEN // AWL: JBI W_OkL #Dyn.SAVE2.Leser_DB := WORD_TO_INT(#tOutDaten[1]); // (AWL: MW222) IF #Dyn.SAVE2.Leser_DB <= 0 THEN // sinnvoller Wert? #Dyn.Error.Err_Leser_nicht_bereit := TRUE; // undefinierter Leser ELSE // (AWL: MD224) #Dyn.SAVE2.Leser_DD := DWORD_TO_DINT( SHL(IN := WORD_TO_DWORD(#tOutDaten[2]), N := 16) OR WORD_TO_DWORD(#tOutDaten[3])); #Dyn.Error.Err_Leser_nicht_bereit := FALSE; #Leser_Zugriff := TRUE; // Leser-Zugriff vorhanden END_IF; ELSE #Dyn.Error.Err_Leser_nicht_bereit := TRUE; // Leser-Datenliste fehlerhaft END_IF; END_IF; END_REGION REGION NW19: Reservierung bei Weiche plus noch aktiv? IF #"Kein_Weichenbereich +1" THEN #"Reservierung_Weiche+1_aktiv" := FALSE; ELSE #tWeichDb := INT_TO_DINT(#SAVE.Weichen_DB); #tWeichBase := INT_TO_DINT(#SAVE.Weichen_DW); // Schleuse -1 (DBW 78) mit dieser Schleuse belegt? #"Reservierung_Weiche+1_aktiv" := (WORD_TO_INT(PEEK_WORD(area := 16#84, dbNumber := #tWeichDb, byteOffset := #tWeichBase + 78)) = #Schleusen_Nr); // Mindestzeit nachtriggern (DBX 71.3): IF #"Schleuse_geöffnet" AND #B_InSchleuse THEN POKE_BOOL(area := 16#84, dbNumber := #tWeichDb, byteOffset := #tWeichBase + 71, bitOffset := 3, value := TRUE); END_IF; END_IF; END_REGION REGION NW20: Leser-Einheit managen (Inputs holen) IF NOT #Leser_Zugriff OR NOT #Schleuse.Parameter_allg.Leser_eingebaut THEN #Dyn.Status.Leser_triggern := FALSE; // fuer Status-Anzeige ELSE #tLeserDb := INT_TO_DINT(#Dyn.SAVE2.Leser_DB); #tLeserBase := #Dyn.SAVE2.Leser_DD; // Offset 10: #tByte := PEEK(area := 16#84, dbNumber := #tLeserDb, byteOffset := #tLeserBase + 10); #Dyn.Leser."IN".xOutReadingDone := #tByte.%X0; #Dyn.Leser."IN".xOutReadyForNewScan := #tByte.%X1; // Offset 274: #tByte := PEEK(area := 16#84, dbNumber := #tLeserDb, byteOffset := #tLeserBase + 274); #Dyn.Leser."IN".xOutCodeGood := #tByte.%X0; #Dyn.Leser."IN".xOutCodeBad := #tByte.%X1; // Offset 12: #Dyn.Leser."IN".nOutBarcode := DWORD_TO_DINT( PEEK_DWORD(area := 16#84, dbNumber := #tLeserDb, byteOffset := #tLeserBase + 12)); END_IF; END_REGION // NW21 "Schrittkette anhalten": im AWL-Original durch CLR + JU dauerhaft // deaktiviert (toter Code) -> entfaellt. REGION NW22: Trolley wurde zurueckgezogen IF NOT ((#Dyn.Sk.Akt_Schritt < 10) OR (#Dyn.Sk.Akt_Schritt > 12) OR #Status2.Trolley_an_Schleuse OR #"Schleuse_geöffnet") THEN #Antrieb_Schleuse_start := TRUE; #Dyn.Leser."OUT".xInReset := TRUE; #Dyn.Sk.Akt_Schritt := 0; // Neubeginn IF #Schleuse.Parameter_allg.Leser_eingebaut THEN // sonst Daten behalten #Dyn.Trolley_ZwischenZiel := 16#0000; #Dyn.TrolleyID_Schleuse := 0; END_IF; END_IF; END_REGION REGION NW23: Sprungverteiler IF #Dyn.Sk.Neu_Schritt <> -1 THEN // Schritt fuer naechsten Zyklus angegeben? #Dyn.Sk.Akt_Schritt := #Dyn.Sk.Neu_Schritt; // Neuen Schritt uebergeben #Dyn.Sk.Neu_Schritt := -1; // Urzustand END_IF; END_REGION mNEU: #Warte_neu := FALSE; // Wartezeit neutriggern #Warte_stop := FALSE; // Wartezeit stoppen CASE #Dyn.Sk.Akt_Schritt OF 0: // NW25 Schritt 0: Warten auf Trolley #Weiter := #B_InSchleuse AND #Dyn.Sk.Auto_akt AND #Dyn.Sk.Bereich_ok; // Trolley-Schleusendaten loeschen: #Dyn.TrolleyID_Schleuse := 0; #Dyn.Trolley_ShopGroup := 0; #Dyn.Trolley_EndZiel := 16#0000; #Dyn.Weichen_Ziel := 16#0000; #Dyn.HMI.TrolleyID_Input := 0; // HMI-Zeug IF #Dyn.Sk.Reset_Akt THEN // Reset ist aktiv #tNeuSchritt := 20; GOTO mNeuMig; END_IF; #Dyn.Error.Err_Leser_nicht_bereit := FALSE; #Dyn.Error.Err_Kein_LeseErgebnis := FALSE; #Dyn.Status.SF_angefordert := FALSE; #Status2."TrolleyPos_übergeben" := FALSE; #Status2.Telegramm_gesendet := FALSE; IF #Weiter THEN // Weiterschaltbedingung ist erfuellt #Dyn.Sk.Err_Uebzeit := FALSE; // Sofort weiter! #tWartezeit := 50; // Angabe der Wartezeit (*10ms) GOTO mPlus; END_IF; #Dyn.Stop_Ursache := 16#B001; IF #Dyn.Status."Trolley_fährt_in_Schleuse" AND NOT #B_InSchleuse THEN #Antrieb_Schleuse_vor := TRUE; // Antrieb einschalten // S000A: Ueberwachungszeit starten #Ueb_akt := #Dyn.Status."Trolley_fährt_in_Schleuse" AND NOT #B_InSchleuse AND (#Antrieb_Schleuse_aktiv OR NOT #Schleuse.Parameter_allg.Antrieb_vorhanden); IF #Dyn.Sk.Err_Uebzeit THEN #Dyn.Sk.Err_Uebzeit := FALSE; #Dyn.Error.Err_Trolley_nicht_in_Schleuse := TRUE; #Dyn.Status."Trolley_fährt_in_Schleuse" := FALSE; END_IF; #tUebzeit := #Schleuse."Übzeit_in_Schleuse"; GOTO mTueb; END_IF; #Dyn.Sk.Err_Uebzeit := FALSE; #Dyn.Stop_Ursache := 16#B000; GOTO mRET; 1: // NW26 Schritt 1: Trolley in Schleuse / Leser? / Daten vorhanden? IF #B_InSchleuse THEN #Status2.Trolley_an_Schleuse := TRUE; END_IF; IF NOT #Status2.Trolley_an_Schleuse AND #Schleuse.Parameter_allg.Leser_eingebaut THEN #tNeuSchritt := 0; // Weiter mit Schritt 0 GOTO mNeuMig; END_IF; // Zwischen-Ziel von Bereich -1 vorhanden? IF (#Dyn.ZwischenZiel_eingefahren <> 16#0000) AND NOT #Schleuse.Parameter_allg.Leser_eingebaut THEN // Daten von Bereich -1 uebergeben: #Dyn.Trolley_ZwischenZiel := #Dyn.ZwischenZiel_eingefahren; #Dyn.ZwischenZiel_eingefahren := 16#0000; #Dyn.TrolleyID_Schleuse := #Dyn.TrolleyID_Eingefahren; #Dyn.TrolleyID_Eingefahren := 0; #tNeuSchritt := 12; // Weiter mit Schritt 12 GOTO mNeuMig; END_IF; // X001: #Dyn.Trolley_ZwischenZiel := 16#0000; IF #Schleuse.Parameter_allg.Leser_eingebaut THEN // Leser vorhanden #Dyn.Error.Err_Kein_LeseErgebnis := FALSE; #tNeuSchritt := 9; // Weiter mit Schritt 9 (Leser bereit) GOTO mNeuMig; END_IF; // Trolleydaten vorhanden? (Uebergabe von Bereich -1) #Dyn.TrolleyID_Schleuse := #Dyn.TrolleyID_Eingefahren; IF #Dyn.TrolleyID_Eingefahren <> 0 THEN #tNeuSchritt := 11; // Weiter mit Schritt 11 (Trolleydaten lesen) GOTO mNeuMig; END_IF; IF #ZielFC_vorhanden THEN #tNeuSchritt := 12; // Weiter mit Schritt 12 (Ziel-FC) GOTO mNeuMig; END_IF; #tNeuSchritt := 14; // Weiter mit Schritt 14 (Weichenbereich +1 vorhanden) GOTO mNeuMig; 2: // NW27 Schritt 2: Ausfahren ok? IF NOT #Status2.Trolley_an_Schleuse AND #Schleuse.Parameter_allg.Leser_eingebaut THEN #tNeuSchritt := 0; // Weiter mit Schritt 0 GOTO mNeuMig; END_IF; // Anlage aus oder Stoerung: #Dyn.Stop_Ursache := 16#B021; IF NOT #Dyn.Sk.Auto_akt OR NOT #Dyn.Sk.Bereich_ok THEN GOTO mRET; END_IF; // Starten erlaubt? #Dyn.Stop_Ursache := 16#B022; IF NOT #Start_Ok THEN GOTO mRET; END_IF; // Stau im Bereich +1: #Dyn.Stop_Ursache := 16#B023; #Dyn.Status."Trolley_wartet_Bereich+1" := TRUE; IF #B_Stau_raus THEN // Sensor Stau im Bereich rausfahren GOTO mRET; END_IF; // B_Aus_Schleuse aktiv: #Dyn.Stop_Ursache := 16#B024; #Dyn.Error.Err_Raus_Sensor := #Schleuse.Parameter_allg.B_AusSep_vorhanden AND #B_AusSchleuse; IF #Dyn.Error.Err_Raus_Sensor THEN GOTO mRET; END_IF; // Restzeit zum Ausfahren ausreichend? #Dyn.Stop_Ursache := 16#B025; IF ((#RestZeit_Bereich_plus < #Schleuse.AusfahrZeit) OR (#Schleuse.AusfahrZeit = 0)) AND (#RestZeit_Bereich_plus <> 999) THEN RETURN; // AWL: BEC (Baustein sofort beenden, NW50 entfaellt) END_IF; // Antriebe aktivieren / aktiv? IF #Schleuse.Parameter_allg.Antrieb_Plus_vorhanden THEN #Antrieb_plus_vor := TRUE; END_IF; IF #Antrieb_plus_aktiv OR NOT #Schleuse.Parameter_allg.Antrieb_Plus_vorhanden THEN #Antrieb_Schleuse_vor := TRUE; END_IF; #Dyn.Stop_Ursache := 16#B026; IF NOT #Antrieb_plus_aktiv AND #Schleuse.Parameter_allg.Antrieb_Plus_vorhanden THEN GOTO mRET; END_IF; #Dyn.Status.Kein_Stop_mehr := NOT #Antrieb_Schleuse_aktiv AND #Schleuse.Parameter_allg.Antrieb_vorhanden; IF #Dyn.Status.Kein_Stop_mehr THEN GOTO mRET; END_IF; #Status2."Warten_3.V" := FALSE; IF NOT #Schleuse.Parameter_allg."2.V_bei_Ausfahrt_checken" THEN #tNeuSchritt := 5; // Nur 1 langes Signal! ELSE #tNeuSchritt := 3; // 2.V bei Ausfahrt checken END_IF; GOTO mNeuMig; 3: // NW28 Schritt 3: Trolley faehrt aus / 1.V ausgefahren? #Weiter := NOT #B_InSchleuse; #Y_Schleuse_Auf := TRUE; // Schleuse oeffnen #Dyn.Status."Trolley_fährt_aus" := TRUE; IF #Weiter THEN #Dyn.Sk.Err_Uebzeit := FALSE; // Sofort weiter! #Dyn.Error.Err_Trolley_raus := FALSE; #tWartezeit := 30; // Angabe der Wartezeit (*10ms) GOTO mPlus; END_IF; IF NOT #"Kein_Weichenbereich +1" AND NOT #"Reservierung_Weiche+1_aktiv" THEN #Dyn.Sk.Err_Uebzeit := FALSE; // Weiche nicht mehr angemeldet #tNeuSchritt := 0; // Weiter mit Schritt 0 GOTO mNeuMig; END_IF; IF #Dyn.Sk.Err_Uebzeit THEN #Dyn.Error.Err_Trolley_raus := TRUE; // Trolley faehrt nicht aus END_IF; #Dyn.Stop_Ursache := 16#B031; #Ueb_akt := #Antrieb_Schleuse_aktiv OR NOT #Schleuse.Parameter_allg.Antrieb_vorhanden; #tUebzeit := #Schleuse."Übzeit_aus_Schleuse"; GOTO mTueb; 4: // NW29 Schritt 4: Trolley faehrt aus / Warten auf 2.V #Weiter := #B_InSchleuse OR #Dyn.Status."Trolley ausserhalb Weiche"; // Bei Raus-Sensor nicht zaehlen: IF #Schleuse.Parameter_allg.B_AusSep_vorhanden AND #B_AusSchleuse THEN #Dyn.Sk.Err_Uebzeit := FALSE; #Dyn.Error.Err_Trolley_raus := FALSE; #tNeuSchritt := 5; // Zaehlen ueberspringen GOTO mNeuMig; END_IF; #Y_Schleuse_Auf := TRUE; // Schleuse oeffnen #Dyn.Status."Trolley_fährt_aus" := TRUE; IF #Weiter THEN #Dyn.Sk.Err_Uebzeit := FALSE; #Dyn.Error.Err_Trolley_raus := FALSE; #tWartezeit := 0; GOTO mPlus; END_IF; IF NOT #"Kein_Weichenbereich +1" AND NOT #"Reservierung_Weiche+1_aktiv" THEN #Dyn.Sk.Err_Uebzeit := FALSE; #tNeuSchritt := 0; GOTO mNeuMig; END_IF; IF #Dyn.Sk.Err_Uebzeit THEN #Dyn.Error.Err_Trolley_raus := TRUE; END_IF; #Dyn.Stop_Ursache := 16#B041; #Ueb_akt := #Antrieb_Schleuse_aktiv OR NOT #Schleuse.Parameter_allg.Antrieb_vorhanden; #tUebzeit := #Schleuse."Übzeit_aus_Schleuse"; GOTO mTueb; 5: // NW30 Schritt 5: Trolley faehrt aus? #Weiter := NOT #B_InSchleuse AND (#Antrieb_Schleuse_aktiv OR NOT #Schleuse.Parameter_allg.Antrieb_vorhanden) AND (#Antrieb_plus_aktiv OR NOT #Schleuse.Parameter_allg.Antrieb_Plus_vorhanden); // Ausfahrzeit lernen: IF NOT #Schleuse.Parameter_allg.B_AusSep_vorhanden THEN #Schleuse.AusfahrZeit := #Schleuse."Übzeit_aus_Schleuse"; // ohne Sensor: Ueb.Zeit uebergeben END_IF; IF (#Schleuse.AusfahrZeit = 0) AND #Schleuse.Parameter_allg.B_AusSep_vorhanden THEN #Status2.Ausfahrzeit_lernen := TRUE; END_IF; #Y_Schleuse_Auf := TRUE; // Schleuse oeffnen #Dyn.Status."Trolley_fährt_aus" := TRUE; IF #B_InSchleuse THEN // B in Schleuse aktiv #Dyn.Sk.Tok_Zelle := 0; END_IF; // Trolley ist draussen mit Verzoegerung: IF #Weiter THEN #Dyn.Sk.Err_Uebzeit := FALSE; #Dyn.Error.Err_Trolley_raus := FALSE; #tWartezeit := 300; GOTO mPlus; END_IF; // Trolley faehrt nicht raus! IF #Dyn.Sk.Err_Uebzeit THEN #Dyn.Error.Err_Trolley_raus := TRUE; END_IF; #Dyn.Stop_Ursache := 16#B051; #Ueb_akt := #Antrieb_Schleuse_aktiv OR NOT #Schleuse.Parameter_allg.Antrieb_vorhanden; #tUebzeit := #Schleuse."Übzeit_aus_Schleuse"; GOTO mTueb; 6: // NW31 Schritt 6: Schleuse Mindestzeit geoeffnet / Trolley draussen? #Weiter := #Dyn.Status.MindestZeit_ok AND NOT #B_InSchleuse AND ((NOT #Schleuse.Parameter_allg.B_AusSep_vorhanden AND #"Kein_Weichenbereich +1") OR #Status2.Trolley_ist_draussen); IF #Weiter THEN #Dyn.Sk.Err_Uebzeit := FALSE; // Sofort weiter! #Dyn.Error.Err_Trolley_raus := FALSE; END_IF; #Y_Schleuse_Auf := TRUE; // Schleuse oeffnen #Dyn.Status."Trolley_fährt_aus" := TRUE; // Erneutes Signal von B in Schleuse? IF #B_InSchleuse THEN #Dyn.Sk.Neu_Schritt := 5; #Dyn.Mindest_Zeit := 0; // Mindest-Zeit neu starten #Dyn.Status.MindestZeit_ok := FALSE; GOTO mRET; END_IF; IF NOT #Weiter THEN // X060 #Dyn.Stop_Ursache := 16#B061; // Trolley faehrt nicht raus! IF #Dyn.Sk.Err_Uebzeit THEN #Dyn.Error.Err_Trolley_raus := TRUE; END_IF; IF #Dyn.Error.Err_Trolley_raus AND NOT #Status2.Trolley_ist_draussen AND #Schleuse.Parameter_allg.B_AusSep_vorhanden THEN #Dyn.Error.Err_Trolley_raus := FALSE; #Dyn.Error.Err_Raus_Sensor := TRUE; // Raus-Sensor wird nicht erreicht! END_IF; #Ueb_akt := #Antrieb_Schleuse_aktiv OR NOT #Schleuse.Parameter_allg.Antrieb_vorhanden; #tUebzeit := #Schleuse."Übzeit_aus_Schleuse"; GOTO mTueb; END_IF; // X006: Trolley hat Schleuse verlassen #Dyn.Status.Trolley_draussen := TRUE; // 1 Zyklus #Dyn.Status."Trolley_fährt_in_Schleuse" := FALSE; #Status2.Telegramm_gesendet := FALSE; #Dyn.Vereinzelungstakte := #Dyn.Vereinzelungstakte + 1; // Draussen-FC? IF #DraussenFC_vorhanden THEN "MW190" := INT_TO_WORD(#Schleusen_Nr); // Schleusen-Nr uebergeben "MD182" := DINT_TO_DWORD(#Dyn.Trolley_ShopGroup); // Shop-Gruppe "MW198" := #Dyn.Weichen_Ziel; // Weichenziel CASE #DraussenFC OF // AWL: UC FC[#DraussenFC] 1182: "Arbeitsplatz_Draussen_FC"(); ELSE ; // unbekannter Draussen-FC END_CASE; END_IF; #tNeuSchritt := 7; // Weiter mit Schritt 7 GOTO mNeuMig; 7: // NW32 Schritt 7: Trolley ausserhalb der Weiche #Weiter := (NOT #"Kein_Weichenbereich +1" AND NOT #"Reservierung_Weiche+1_aktiv") OR #Dyn.Status."Trolley ausserhalb Weiche" OR #"Kein_Weichenbereich +1"; #Y_Schleuse_Auf := TRUE; // Schleuse oeffnen #Dyn.Status."Trolley_fährt_aus" := TRUE; IF #Dyn.Status.Weiche_geschaltet OR #"Kein_Weichenbereich +1" THEN #Antrieb_Schleuse_vor := TRUE; #Antrieb_plus_vor := TRUE; END_IF; IF NOT #Weiter THEN #Dyn.Stop_Ursache := 16#B071; GOTO mRET; END_IF; // X007: Trolley ist ausserhalb der Weiche? IF #"Kein_Weichenbereich +1" THEN GOTO mEndeMig; END_IF; // Weichen-Rueckmeldungen loeschen: #Dyn.Status.Weiche_geschaltet := FALSE; #Dyn.Status."Trolley ausserhalb Weiche" := FALSE; // Weichen-Reservierung loeschen: #tWeichDb := INT_TO_DINT(#SAVE.Weichen_DB); #tWeichBase := INT_TO_DINT(#SAVE.Weichen_DW); IF WORD_TO_INT(PEEK_WORD(area := 16#84, dbNumber := #tWeichDb, byteOffset := #tWeichBase + 78)) <> #Schleusen_Nr THEN GOTO mEndeMig; // nicht diese Schleuse END_IF; POKE(area := 16#84, dbNumber := #tWeichDb, byteOffset := #tWeichBase + 78, value := WORD#16#0000); // Schleuse -1 (DBW 78) loeschen #SAVE."Weiche+1" := 0; // Hier wurde reserviert #tWartezeit := 0; GOTO mPlus; // Naechsten Schritt starten (Schritt 8) 8: // NW33 Schritt 8: Weichen-Rueckmeldungen = 0? IF NOT #Dyn.Status.Weiche_geschaltet AND NOT #Dyn.Status."Trolley ausserhalb Weiche" THEN GOTO mEndeMig; END_IF; #Dyn.Stop_Ursache := 16#B080; GOTO mRET; 9: // NW34 Schritt 9: Lese-Einheit bereit? #Weiter := (#Dyn.Leser."IN".nOutBarcode = 0) AND #Dyn.Leser."IN".xOutReadyForNewScan AND NOT #Dyn.Leser."IN".xOutReadingDone AND NOT #Dyn.Leser."IN".xOutCodeGood AND NOT #Dyn.Leser."IN".xOutCodeBad; IF #Weiter THEN #Dyn.Error.Err_Leser_nicht_bereit := FALSE; END_IF; IF NOT #Status2.Trolley_an_Schleuse AND #Schleuse.Parameter_allg.Leser_eingebaut THEN #Dyn.Error.Err_Leser_nicht_bereit := FALSE; #tNeuSchritt := 0; // Weiter mit Schritt 0 GOTO mNeuMig; END_IF; #Dyn.Leser."OUT".xInStartReading := #Weiter; // Leser triggern IF #Weiter THEN #tWartezeit := 0; GOTO mPlus; END_IF; // Leser nicht bereit: IF #Dyn.Leser."IN".xOutReadingDone OR #Dyn.Leser."IN".xOutCodeGood OR #Dyn.Leser."IN".xOutCodeBad THEN #Dyn.Leser."OUT".xInHandshakeDone := TRUE; // Falls altes Handshake noch gewollt END_IF; IF #Dyn.Sk.Err_Uebzeit THEN #Dyn.Sk.Err_Uebzeit := FALSE; // Sofort weiter! #Dyn.Error.Err_Leser_nicht_bereit := TRUE; #Dyn.Leser."OUT".xInErrQuit := TRUE; // Vielleicht hilft es END_IF; IF #Dyn.Error.Err_Leser_nicht_bereit AND #ErrQuit THEN #Dyn.Leser."OUT".xInReset := TRUE; // Mit Quittierung zusaetzlich reset! END_IF; // HMI-TrolleyID bei Leser nicht bereit: IF (#Dyn.HMI.TrolleyID_Input <> 0) AND #Dyn.Error.Err_Leser_nicht_bereit THEN #tWartezeit := 0; GOTO mPlus; END_IF; #Ueb_akt := TRUE; #tUebzeit := 5; // Angabe der Ueberwachungszeit (*1s) GOTO mTueb; 10: // NW35 Schritt 10: Warten auf Leseeinheit #Weiter := #Dyn.Leser."IN".xOutReadingDone AND #Dyn.Leser."IN".xOutCodeGood AND NOT #Dyn.Leser."IN".xOutCodeBad; IF #Weiter THEN #Dyn.Error.Err_Kein_LeseErgebnis := FALSE; END_IF; IF NOT #Status2.Trolley_an_Schleuse AND #Schleuse.Parameter_allg.Leser_eingebaut THEN #Dyn.Error.Err_Kein_LeseErgebnis := FALSE; #tNeuSchritt := 0; // Weiter mit Schritt 0 GOTO mNeuMig; END_IF; #Dyn.Leser."OUT".xInStartReading := FALSE; // Leseeinheit triggern IF #Weiter THEN // X010: Leserdaten uebergeben #Dyn.Leser."OUT".xInHandshakeDone := TRUE; #Dyn.Sk.Err_Uebzeit := FALSE; // Sofort weiter! #Dyn.TrolleyID_Schleuse := #Dyn.Leser."IN".nOutBarcode; IF (#Dyn.Leser."IN".nOutBarcode = 0) OR (#Dyn.Leser."IN".nOutBarcode = -1) THEN #Dyn.Error.Err_Kein_LeseErgebnis := TRUE; // Unbekannt / Fehl-Lesung #tNeuSchritt := 9; // Weiter mit Schritt 9 (Leser bereit) GOTO mNeuMig; END_IF; #tNeuSchritt := 11; // Weiter mit Schritt 11 GOTO mNeuMig; END_IF; #Dyn.Status.Trolley_wartet_Lesung := TRUE; IF NOT #Dyn.Error.Err_Leser_nicht_bereit THEN // von Schritt 9 IF #Dyn.Sk.Err_Uebzeit OR #Dyn.Leser."IN".xOutCodeBad THEN #Dyn.Leser."OUT".xInHandshakeDone := TRUE; // L2: Erst bei 3.Fehllesung Error! IF NOT #Status2."2.Lesung_aktiv" THEN #Status2."2.Lesung_aktiv" := TRUE; #Dyn.Sk.Err_Uebzeit := FALSE; // Sofort weiter! #Dyn.Sk.Neu_Schritt := 9; GOTO mRET; END_IF; // L3: IF NOT #Status2."3.Lesung_aktiv" THEN #Status2."3.Lesung_aktiv" := TRUE; #Dyn.Sk.Err_Uebzeit := FALSE; // Sofort weiter! #Dyn.Sk.Neu_Schritt := 9; GOTO mRET; END_IF; // LX: Nach 3.Fehl-Lesung erst Leserfehler! #Dyn.Sk.Err_Uebzeit := FALSE; #Dyn.Error.Err_Kein_LeseErgebnis := TRUE; ELSE #Dyn.Stop_Ursache := 16#B101; #Ueb_akt := TRUE; #tUebzeit := 10; // Angabe der Ueberwachungszeit (*1s) GOTO mTueb; END_IF; ELSE // LX (direkt von Schritt-9-Fehler): #Dyn.Sk.Err_Uebzeit := FALSE; #Dyn.Error.Err_Kein_LeseErgebnis := TRUE; END_IF; // NoLesung: HMI-Eingabe? #Dyn.TrolleyID_Schleuse := #Dyn.HMI.TrolleyID_Input; IF #Dyn.HMI.TrolleyID_Input <> 0 THEN // ACHTUNG: AWL verglich mit undefiniertem Akku! #Dyn.Error.Err_Kein_LeseErgebnis := FALSE; #Dyn.Error.Err_Leser_nicht_bereit := FALSE; // von Schritt 9 #tWartezeit := 0; GOTO mPlus; END_IF; // No_HMIa: Leser-FC aufrufen: IF #LeserFC_vorhanden THEN "MW190" := INT_TO_WORD(#Schleusen_Nr); // Schleusen-Nr uebergeben "MW196" := #Dyn.Trolley_ZwischenZiel; "M180.0" := #Dyn.Error.Err_Kein_LeseErgebnis; "M180.1" := FALSE; CASE #LeserFC OF // AWL: UC FC[#LeserFC] (Beeinflussung der Fehllesung) 1180: "Arbeitsplatz_Leser_FC"(); ELSE ; // unbekannter Leser-FC END_CASE; #Dyn.Stop_Ursache := 16#B102; #Dyn.Trolley_ZwischenZiel := "MW196"; // Zwischenziel uebergeben IF "MW196" <> 16#0000 THEN #Dyn.Error.Err_Kein_LeseErgebnis := FALSE; #tNeuSchritt := 12; // Weiter mit Schritt 12 GOTO mNeuMig; END_IF; END_IF; // NoLFC: #Dyn.Sk.Neu_Schritt := 9; GOTO mRET; 11: // NW36 Schritt 11: Trolleydaten aus DL lesen #Dyn.TrolleyID_Eingefahren := 0; // Eintrag von Weiche -1 #tSuchID := #Dyn.TrolleyID_Schleuse; // Search-Daten (AWL: MD220) "DatenOut"(SSDB := #Schleuse.Gesamt_Trolley_DL, SSDW := 0, PARA := WORD#16#0000, SEARCHDATEN := #tSuchID, RE_VAL => #tReVal, Position => #tPosition, OUTDATEN := "TrolleyDL_OutDaten".OUTDaten); // Eintrag lesen (AWL: DB1011.DBX0.0) #Dyn.Stop_Ursache := 16#B111; #Dyn.Error.Barcode_nicht_bekannt := NOT #tReVal.%X7; IF NOT #Dyn.Error.Barcode_nicht_bekannt THEN // Relevante Trolleydaten auslesen: #Dyn.Trolley_EndZiel := "TrolleyDL_OutDaten".OUTDaten.EndZiel; IF #Dyn.Trolley_ZwischenZiel = 16#0000 THEN // ZwischenZiel nicht ueberschreiben #Dyn.Trolley_ZwischenZiel := "TrolleyDL_OutDaten".OUTDaten.ZwischenZiel; END_IF; #Dyn.Trolley_ShopGroup := "TrolleyDL_OutDaten".OUTDaten.ShopGroup; #tWartezeit := 0; GOTO mPlus; // Naechsten Schritt starten END_IF; // UnbekanntBC / Nix_HMI: Leser-FC aufrufen: IF #LeserFC_vorhanden THEN "MW190" := INT_TO_WORD(#Schleusen_Nr); "MD192" := DINT_TO_DWORD(#Dyn.TrolleyID_Schleuse); "MW196" := #Dyn.Trolley_ZwischenZiel; "M180.1" := #Dyn.Error.Barcode_nicht_bekannt; "M180.0" := FALSE; CASE #LeserFC OF // AWL: UC FC[#LeserFC] (Weiterfahrt bei nicht bekanntem Trolley) 1180: "Arbeitsplatz_Leser_FC"(); ELSE ; END_CASE; #Dyn.Trolley_ZwischenZiel := "MW196"; // ZwischenZiel uebergeben IF "MW196" <> 16#0000 THEN #Dyn.Error.Err_Kein_LeseErgebnis := FALSE; #tNeuSchritt := 12; // Weiter mit Schritt 12 GOTO mNeuMig; END_IF; END_IF; // Nix_LFC: GOTO mRET; 12: // NW37 Schritt 12: Ziel-FC IF NOT #Status2.Trolley_an_Schleuse AND #Schleuse.Parameter_allg.Leser_eingebaut AND NOT #"Schleuse_geöffnet" THEN #tNeuSchritt := 0; // Weiter mit Schritt 0 GOTO mNeuMig; END_IF; #Dyn.Status."Trolley_wartet_auf_Ziel-FC" := TRUE; IF NOT #ZielFC_vorhanden THEN #Dyn.Status."Trolley_wartet_auf_Ziel-FC" := FALSE; #tNeuSchritt := 13; // Weiter mit Schritt 13 GOTO mNeuMig; END_IF; "M180.6" := FALSE; // Rueckmeldungen erst mal resetten "MW190" := INT_TO_WORD(#Schleusen_Nr); // Schleusen-Nr uebergeben "MD182" := DINT_TO_DWORD(#Dyn.Trolley_ShopGroup); // Shop-Gruppe "MW194" := #Dyn.Trolley_EndZiel; // End-Ziel "MW196" := #Dyn.Trolley_ZwischenZiel; "MW198" := 16#0000; // Weichenziel erst mal nullen CASE #ZielFC OF // AWL: UC FC[#ZielFC] (Beeinflussung der Weiterfahrt) 181: "HWtoAMRZielFC"(); 1181: "Arbeitsplatz_Ziel_FC"(); 2181: "HWtoOB_Ziel_FC"(); ELSE ; // unbekannter Ziel-FC END_CASE; #Dyn.Stop_Ursache := 16#B122; // Spezial-Fall bei Uebergabe an Sorter / Turm (M180.6 wird nie im Ziel-FC gesetzt!) // aber anderer Partner hat Schleuse extern geoeffnet: IF #"Schleuse_geöffnet" AND NOT "M180.6" AND NOT #Status2."TrolleyPos_übergeben" THEN #Status2."TrolleyPos_übergeben" := TRUE; // Nur einmalig #Dyn.Vereinzelungstakte := #Dyn.Vereinzelungstakte + 1; "Trolley_DL_Neue_Pos"(Gesamt_Trolley_DL := #Schleuse.Gesamt_Trolley_DL, TrolleyID := #Dyn.TrolleyID_Schleuse, Position := #Schleuse.Leser_ID, ShopGroup := DINT#0, Err => "M199.0"); // Draussen-FC? IF NOT #DraussenFC_vorhanden THEN GOTO mRET; END_IF; "MW190" := INT_TO_WORD(#Schleusen_Nr); CASE #DraussenFC OF // AWL: UC FC[#DraussenFC] (z.B. Daten anpassen) 1182: "Arbeitsplatz_Draussen_FC"(); ELSE ; END_CASE; GOTO mRET; END_IF; // Normal: IF "M180.6" THEN // Weiterfahrt von Ziel-FC erlaubt // X012: #Dyn.Trolley_ZwischenZiel := "MW196"; // zurueckschreiben, falls veraendert #Dyn.Weichen_Ziel := "MW198"; // Weichenziel uebergeben #tNeuSchritt := 13; // Weiter mit Schritt 13 GOTO mNeuMig; END_IF; IF NOT #Schleuse.Parameter_allg.Leser_eingebaut THEN GOTO mRET; END_IF; #Dyn.Sk.Neu_Schritt := 11; GOTO mRET; 13: // NW38 Schritt 13: Schleusen-Position zurueckschreiben #Status2."Weichen-Schritt" := TRUE; // Neue Position an Gesamt-Trolley-DL uebergeben: "Trolley_DL_Neue_Pos"(Gesamt_Trolley_DL := #Schleuse.Gesamt_Trolley_DL, TrolleyID := #Dyn.TrolleyID_Schleuse, Position := #Schleuse.Leser_ID, ShopGroup := DINT#0, Err => "M199.0"); #tWartezeit := 0; GOTO mPlus; // Naechsten Schritt starten 14: // NW39 Schritt 14: Weichenbereich +1 vorhanden IF #"Kein_Weichenbereich +1" THEN #tNeuSchritt := 2; // Weiter mit Schritt 2 (Ausfahren ok?) GOTO mNeuMig; END_IF; #Status2."Weichen-Schritt" := TRUE; #Dyn.Status.Weiche_geschaltet := FALSE; #Dyn.Status."Trolley ausserhalb Weiche" := FALSE; #tWartezeit := 0; GOTO mPlus; 15: // NW40 Schritt 15: Weichenbereich raus bereit? #Status2."Weichen-Schritt" := TRUE; IF #Dyn.Weichen_Ziel = 16#0000 THEN // Weichenziel bekannt? #Dyn.Sk.Neu_Schritt := 12; // Ziel-FC #Dyn.Stop_Ursache := 16#B154; GOTO mRET; END_IF; // X15A: #Dyn.Status."Trolley_wartet_auf_Weiche+1" := TRUE; #Dyn.Stop_Ursache := 16#B155; IF #SAVE.Weichen_DB <= 0 THEN // Einsprung-Zeiger bekannt? #Dyn.Stop_Ursache := 16#B150; GOTO mRET; END_IF; // S015A: Weichendaten auslesen #tWeichDb := INT_TO_DINT(#SAVE.Weichen_DB); #tWeichBase := INT_TO_DINT(#SAVE.Weichen_DW); #Dyn.Stop_Ursache := 16#B152; IF NOT (NOT PEEK_BOOL(area := 16#84, dbNumber := #tWeichDb, byteOffset := #tWeichBase + 70, bitOffset := 0) // Weichenbereich frei? (DBX70.0) OR #Dyn.Status.Weiche_geschaltet OR #Dyn.Status."Trolley ausserhalb Weiche") THEN #tNeuSchritt := 16; // Weiter mit Schritt 16 (Daten an Weiche uebergeben) GOTO mNeuMig; END_IF; // S015B: Reservierung schon erfolgt? #Dyn.Status.Weiche_geschaltet := FALSE; #Dyn.Status."Trolley ausserhalb Weiche" := FALSE; IF WORD_TO_INT(PEEK_WORD(area := 16#84, dbNumber := #tWeichDb, byteOffset := #tWeichBase + 78)) = #Schleusen_Nr THEN // Reservierung loeschen: POKE(area := 16#84, dbNumber := #tWeichDb, byteOffset := #tWeichBase + 78, value := WORD#16#0000); // Schleuse -1 (DBW 78) END_IF; GOTO mRET; 16: // NW41 Schritt 16: Daten an Rausweiche uebergeben #Status2."Weichen-Schritt" := TRUE; #tWeichDb := INT_TO_DINT(#SAVE.Weichen_DB); #tWeichBase := INT_TO_DINT(#SAVE.Weichen_DW); // Trolley-ID (DBD 72): POKE(area := 16#84, dbNumber := #tWeichDb, byteOffset := #tWeichBase + 72, value := DINT_TO_DWORD(#Dyn.TrolleyID_Schleuse)); // Weichenziel (DBW 76): POKE(area := 16#84, dbNumber := #tWeichDb, byteOffset := #tWeichBase + 76, value := #Dyn.Weichen_Ziel); // Zwischenziel (DBW 80): POKE(area := 16#84, dbNumber := #tWeichDb, byteOffset := #tWeichBase + 80, value := #Dyn.Trolley_ZwischenZiel); // Schleuse -1 (DBW 78): POKE(area := 16#84, dbNumber := #tWeichDb, byteOffset := #tWeichBase + 78, value := INT_TO_WORD(#Schleusen_Nr)); #"Reservierung_Weiche+1_aktiv" := TRUE; // (da erst im naechsten Zyklus gelesen) #SAVE."Weiche+1" := #Schleuse.RausWeichen_Nr; // Hier wurde reserviert #tNeuSchritt := 17; // Weiter mit Schritt 17 (Hat Weiche geschaltet?) GOTO mNeuMig; 17: // NW42 Schritt 17: Hat Rausweiche geschaltet? #Status2."Weichen-Schritt" := TRUE; // Weiche +1 noch mit dieser Schleuse aktiv? IF NOT #"Reservierung_Weiche+1_aktiv" THEN #tNeuSchritt := 14; // Weiter mit Schritt 14 GOTO mNeuMig; END_IF; #Dyn.Status."Trolley_wartet_auf_Weiche+1" := TRUE; #Dyn.Stop_Ursache := 16#B170; IF #Dyn.Status."Trolley ausserhalb Weiche" THEN // Rueckmeldung von Weiche +1 GOTO mRET; END_IF; IF #Dyn.Status.Weiche_geschaltet THEN // Rueckmeldung von Weiche +1 #tNeuSchritt := 2; // Weiter mit Schritt 2 (Ausfahren ok?) GOTO mNeuMig; END_IF; #Dyn.Stop_Ursache := 16#B171; GOTO mRET; 20: // NW43 Schritt 20: Schleuse resetten (Wartezeit) #Weiter := #B_InSchleuse; // ELS in Grundstellung fahren: #Antrieb_Schleuse_vor := TRUE; #Antrieb_Schleuse_start := TRUE; IF #Weiter OR #Dyn.Sk.Err_Uebzeit THEN #Dyn.Sk.Err_Uebzeit := FALSE; // Sofort weiter! #tNeuSchritt := 21; // Weiter mit Schritt 21 GOTO mNeuMig; END_IF; #Dyn.Stop_Ursache := 16#B201; #Ueb_akt := TRUE; #tUebzeit := 60; // AWL: L Wartezeit_bis_leer; L 60 -> 60 wirksam GOTO mTueb; 21: // NW44 Schritt 21: Reset ist zu Ende #Dyn.Sk.Reset_Akt := FALSE; // Reset ist aktiv #Status2."Warten_3.V" := FALSE; #Status2."TrolleyPos_übergeben" := FALSE; #Dyn.Error.Err_Trolley_nicht_in_Schleuse := FALSE; #Dyn.Error.Err_Uebzeit := FALSE; #Dyn.Error.Err_Stau_Einfahrt := FALSE; #Dyn.Error.Err_Trolley_raus := FALSE; #Dyn.Status."Trolley_fährt_in_Schleuse" := FALSE; #SAVE.Weichen_DB := 0; #SAVE.Weichen_DW := 0; #SAVE."Weiche+1" := 0; // Dadurch wird in Weiche Reservierung geloescht #Schleuse.Schleusen_Nr := 0; // Damit stat. Daten neu geholt werden! #Dyn.Status.Trolley_draussen := TRUE; GOTO mEndeMig; // Neubeginn ELSE // Schritte 18/19/22..30 und ungueltige Werte GOTO mEnde; // Undefinierter Schritt END_CASE; GOTO mEnde; // (nicht erreichbar; alle Zweige enden mit GOTO) REGION Schrittketten-Verwaltung (AWL: Ende / Neu_Mig / ENDE_Mig / Plus / tueb / RET) mEnde: // NW23 Ende: Undefinierter Schritt #Dyn.Sk.Err_Schritt := TRUE; #Dyn.Stop_Ursache := 16#A131; GOTO mRET; mNeuMig: // Neu_Mig: neuen Schritt sofort (im selben Zyklus) aktivieren IF #Dyn.Sk.Err_Uebzeit THEN // Stoerung noch nicht quittiert #Dyn.Stop_Ursache := 16#A132; GOTO mRET; END_IF; #Dyn.Sk.Akt_Schritt := #tNeuSchritt; #Dyn.Sk.Terr_Zelle := 0; // Zeitwerte loeschen #Dyn.Sk.Tok_Zelle := 0; GOTO mNEU; // zurueck zum Sprungverteiler mEndeMig: // NW45: Schrittkette beenden #Dyn.Sk.Akt_Schritt := 0; // Schritt 0: Warten #Dyn.Sk.Terr_Zelle := 0; // Zeitwert loeschen #Dyn.Sk.Tok_Zelle := 0; #Dyn.ZwischenZiel_eingefahren := 16#0000; #Dyn.TrolleyID_Eingefahren := 0; // Eintrag von Weiche -1 #Dyn.TrolleyID_Schleuse := 0; #Dyn.Trolley_ZwischenZiel := 16#0000; #Dyn.Trolley_EndZiel := 16#0000; #Dyn.Weichen_Ziel := 16#0000; #Dyn.Sk.Err_Uebzeit := FALSE; #Dyn.Status.Weiche_geschaltet := FALSE; #Dyn.Status."Trolley ausserhalb Weiche" := FALSE; #Dyn.Status."Trolley_fährt_rückwärts" := FALSE; #Status2."Warten_3.V" := FALSE; #Dyn.Error.Err_Kein_LeseErgebnis := FALSE; #Status2."2.Lesung_aktiv" := FALSE; #Status2."3.Lesung_aktiv" := FALSE; #Status2."TrolleyPos_übergeben" := FALSE; #Status2.Telegramm_gesendet := FALSE; #Dyn.HMI.TrolleyID_Input := 0; // HMI-Zeug GOTO mRET; mPlus: // NW46: Naechsten Schritt aktivieren (nach Wartezeit #tWartezeit *10ms) #Dyn.Sk.T_ok := #tWartezeit; // Wartezeit uebergeben IF #Dyn.Sk.Err_Uebzeit THEN // Stoerung noch nicht quittiert GOTO mRET; END_IF; IF #tWartezeit <> 0 THEN // sonst sofort weiter IF #Warte_neu THEN // Wartezeit neutriggern #Dyn.Sk.Tok_Zelle := 0; END_IF; IF #Warte_stop THEN // Wartezeit stoppen GOTO mRET; END_IF; #Dyn.Sk.Tok_Zelle := #Dyn.Sk.Tok_Zelle + WORD_TO_INT("MW4"); // Wartezeit +10ms IF #Dyn.Sk.Tok_Zelle < #Dyn.Sk.T_ok THEN // abgelaufen? Nein! GOTO mRET; END_IF; END_IF; #Dyn.Sk.Akt_Schritt := #Dyn.Sk.Akt_Schritt + 1; // Schritt +1 #Dyn.Sk.Terr_Zelle := 0; // Zeitwerte loeschen #Dyn.Sk.Tok_Zelle := 0; GOTO mRET; mTueb: // NW47/48: Ueberwachungszeit kontrollieren (#tUebzeit *1s) #Dyn.Sk.Ueb_akt := #Ueb_akt; // Fuer Statuskontrolle #Dyn.Sk.T_Err := #tUebzeit; // Fuer Statuskontrolle IF (#tUebzeit > #Dyn.Sk.Terr_Zelle) AND NOT #Dyn.Sk.Err_Uebzeit THEN // NW48: Ueberwachungszeit +1 IF #Dyn.Sk.Ueb_akt AND "1s-Impuls" THEN #Dyn.Sk.Terr_Zelle := #Dyn.Sk.Terr_Zelle + 1; // Ueb.zeit +1s END_IF; GOTO mRET; END_IF; IF #Ueb_akt THEN // Ueberwachungszeit aktiviert #Dyn.Sk.Err_Uebzeit := TRUE; END_IF; #Dyn.Sk.Terr_Zelle := 0; // Zeitwert loeschen GOTO mRET; END_REGION REGION NW50: Leser-Einheit managen (Outputs schreiben) mRET: IF #Leser_Zugriff AND #Schleuse.Parameter_allg.Leser_eingebaut THEN #tLeserDb := INT_TO_DINT(#Dyn.SAVE2.Leser_DB); #tLeserBase := #Dyn.SAVE2.Leser_DD; // Offset 4: Aktuelle Werte holen, Bits setzen, zurueckschreiben #tByte := PEEK(area := 16#84, dbNumber := #tLeserDb, byteOffset := #tLeserBase + 4); #tByte.%X1 := #Dyn.Leser."OUT".xInStartReading; #tByte.%X2 := #Dyn.Leser."OUT".xInHandshakeDone; #Dyn.Leser."OUT".xInHandshakeDone := FALSE; #tByte.%X4 := #Dyn.Leser."OUT".xInErrQuit; #Dyn.Leser."OUT".xInErrQuit := FALSE; #tByte.%X5 := #Dyn.Leser."OUT".xInReset; #Dyn.Leser."OUT".xInReset := FALSE; POKE(area := 16#84, dbNumber := #tLeserDb, byteOffset := #tLeserBase + 4, value := #tByte); // Veraenderte Werte zurueckschreiben END_IF; END_REGION END_FUNCTION_BLOCK