FUNCTION_BLOCK "MHMLeerpuffer" TITLE = Omni H&M-Leerpuffer-Modul { S7_Optimized_Access := 'FALSE' } AUTHOR : AE VERSION : 0.1 //COPYRIGHT by Ingenieurbüro A.Emmert //Ortsstr.33, D-869925 Fuchstal (Germany) //Tel.: 0049(0)8243-960629 // //Version: H&M Leerpuffer / 10.2025 // //Version: Omniflow 2100 / 10.2024 // //Schritt 0: Warten auf Trolley //Schritt 1: Trolley ist in Schleuse / Warten auf Bit "Einen Trolley ausfahren" //Schritt 2: Ausfahren ok ? //Schritt 5: Trolley fährt aus/ausgefahren ? Schritt 6: Schleuse Mindestzeit geöffnet ? Schritt 7: Trolleydaten ändern //Schritt 20: Schleuse resetten //Schritt 21: Reset ist zu Ende // VAR_INPUT LeerPuffer_Nr { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Int; // Aufruf für Leer-Puffer ErrQuit { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // Ablaufstörung quittieren B_LeerpufferEinfahrt { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // Sensor Trolley fährt in Leerpuffer B_InSchleuse { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // Sensor Trolley ist in Schleuse unten B_AusSchleuse { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // Sensor Trolley hat Schleuse unten verlassen B_Stau_raus_Out { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // Sensor Stau im Bereich unten rausfahren B_QuerTrolley_Out : Bool; // Crash-Trolley auf Crashkurs erkannt Antrieb_plus_aktiv { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // Kreisel-Antrieb plus aktiv Schleuse_geöffnet : Bool; // Schleuse unten hat geöffnet END_VAR VAR_OUTPUT Y_Schleuse_Auf { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // Schleuse unten öffnen Error { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Word; // Störungen übergeben END_VAR VAR_IN_OUT Start_Ok : Bool; // Starten von ausserhalb ist erlaubt Antrieb_plus_vor { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // Antrieb plus vorfahren Antrieb_plus_stoppen : Bool; // Antrieb plus stoppen hStOk : Bool; // Anzeige Start n. Störung aktivieren Ausfahr_Inks : Int; // Rest-Inks, wo sich Trolley befindet END_VAR VAR Res16 { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Array[1..2] of Int; // Reserve SAVE { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Struct Weichen_DB { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Int; // Weichen-FIFO-DB Weichen_DW { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Int; // Weichen-FIFO-DW END_STRUCT; Para { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Struct // Parameter Leerpuffer_DL_DB { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Int; // Einsprung Leerpuffer-Datenliste-DB Leerpuffer_DL_DW { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Int; // Einsprung Leerpuffer-Datenliste-DW Res1 { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Array[1..2] of Int; // Reserve END_STRUCT; Status2 { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Struct Einlagern_ist_aktiv { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // Puffer mit Einlagern aktiv Auslagern_ist_aktiv { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // Puffer mit Auslagern aktiv Eintrag_DL_Leerliste_erfolgt { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // Eintrag in DLLPPuffer_leer (DB500) erfolgt Eintrag_DL_Reinliste_erfolgt { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // Eintrag in DLLPPuffer_Einfahren (DB501) erfolgt Eintrag_Abrufliste_erfolgt { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // Eintrag in DLLPPuffer_Ausfahren (DB502) erfolgt END_STRUCT; Puffer { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : "UDLHMLeerPuffer"; // Statische Leerpufferdaten (aus DL) Dyn : Struct // Dynamische Daten Status { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Struct Puffer_leer { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // Puffer ist leer "Puffer_hat Platz" { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // Puffer hat noch Kapazität Kein_neuer_Trolley_kommt { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // Leerpuffer zeitlang ohne neuen Trolley Leer_Check_aktiv { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // Leerpuffer wird auf leer gecheckt Reset_aktiv { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // Reset aktiv Trolley_nicht_in_Schleuse { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // Trolley fährt nicht in Schleuse > Inilauf gestartet Puffer_nicht_leer { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // Puffer nicht leer > Inilauf gestartet Leerpuffer_initialisieren { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // Leerpuffer initialisieren MindestZeit_ok { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // Schleuse ist MindestZeit geöffnet Res711 { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; Res712 { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; "Trolley_wartet_Bereich+1" { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // Auslagerstrecke noch belegt Einen_LeerTrolley_ausfahren { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // Einen Leer-Trolley ausfahren Trolley_fährt_aus { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // Trolley fährt aus Puffer Trolley_draussen { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // Trolley ist ausgefahren (1 Zyklus) Error_aktiv { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // Störung vorhanden END_STRUCT; TrolleyID_Einfahrt { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : DInt; // Trolley-Nr ist eingefahren HMI : Struct Trolleys_LeerPuffer { ExternalWritable := 'False'} : Int; // Anzahl Trolleys unten (IN:PLC, OUT:PLC) Res_Trolleys_LeerPuffer { ExternalWritable := 'False'} : Int; // Anzahl reservierte Trolleys oben (IN:PLC, OUT:PLC) Frei_Plätze_LeerPuffer { ExternalWritable := 'False'} : Int; // Freiplätze für Trolleys (IN:PLC, OUT:PLC) Schleuse_resetten_Leerpuffer : Bool; // Schleuse resetten unten (IN:HMI, Out:PLC) LeerPuffer_initialisieren : Bool := 1; // Leerpuffer initialisieren (IN:HMI, Out:PLC) Einlagern_gesperrt : Bool; // Einlagern gesperrt (IN:HMI, OUT:HMI) AusLagern_gesperrt : Bool; // AusLagern gesperrt (IN:HMI, OUT:HMI) END_STRUCT; Sk { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : "USk_Omni" := ((), (), (), (), (), (), (), (), (), (), 1, (), (), (), (), (), ()); // Status der Schrittkette Schleuse OUT (unten) Rueckmld { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Struct RET_VAL_BLKMOV_Leerpuffer { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Int; // Rückmeldung nach BLKMOV-Aufruf RET_VAL_DL_Leerpuffer { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Byte; // Rückmeldung nach DatenOut-Aufruf RET_VAL_DL_Res { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Byte; // Rückmeldung nach DatenOut-Aufruf RET_VAL_DL_LeerpufferTrolley_IN { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Byte; // Rückmeldung nach DatenIN-Aufruf RET_VAL_DL_LeerpufferTrolley { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Byte; // Rückmeldung nach DatenOut-Aufruf END_STRUCT; Error { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'; S7_SetPoint := 'False'} : "UErrHMLeerPuffer"; Stau_Zeit { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Int; // Sensor B_Einfahrt ist belegt [1s] Mindest_Zeit { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Int; // Sensor B_in_Schleuse unten ist frei [1s] Leer_Zeit { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Int; // Puffer unten ist frei [1s] Stop_Ursache { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Word; // Stop-Stelle: Nw + Position Vereinzelungstakte { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : DInt; // Anzahl der getätigten Vereinzelungstakte TrolleyID_ausgefahren { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : DInt; // TrolleyID des ausgefahrenen Trolleys Res200 { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Array[1..38] of Int; Reservierungs_DL { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Struct // AB DW200: Liste der resevierter Trolleys Datenlistenkopf { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Struct KOPF { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Word := WORD#16#DA02; // Datenliste-Kennnung (DA) / Datensatzlänge in Word (1 - 128) LAENGE { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Int := 24; // Länge der Datenliste (maximale Anzahl der Datensätze) STAMMDATEN { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Int := 2; // Stammdatenlänge in Word (1 - 9) INDDB { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Int; // Indizierter DB (nur bei Stammdaten = 1 erlaubt !!!) LAENGEINDDB { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Int; // Länge des indizierten DB in Word (nur bei Stammdaten = 1 erlaubt !!!) INDDATEN_WANDEL_FC { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Int; // FC zum Wandeln der indizierte Daten (nur bei Stammdaten = 1 erlaubt !!!) LETZTERZUGRIFF { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Int; // Speicherung des letzten Zugriffs Belegt14 { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Int; // reserviert von Sort-Datenliste AnzahlEintraege { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Int; // Anzahl der eingetragenen Datensätze (nicht bei ind.Zugriff!) Reserve18 { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Int; // Reserve END_STRUCT; Res_Trolley { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Array[1..24] of Struct // Reservierter Trolley für Leerpuffer Trolley_ID { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : DInt; // Trolley_ID END_STRUCT; Endekennung { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Word := WORD#16#DAEE; // Datensort-Ende-Kennung (DBEE) END_STRUCT; Res350 { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Array[1..16] of Int; Anzahl_LeerTrolleys { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Int; // AB DW350: Liste der Trolleys im Leerpuffer Res500 { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Array[1..74] of Int; END_STRUCT; END_VAR VAR_TEMP Quelle : Any; // Zeiger, wo Rein-Daten sind Ziel : Any; // Zeiger, FIFO-Stelle Ueb_akt : Bool; // Überwachungszeit aktivieren Weiter : Bool; // Weiterschaltbedingung ist erfüllt Warte_neu : Bool; // Wartezeit neu triggern Warte_stop : Bool; // Wartezeit stoppen Neu_Trolley_in_Puffer : Bool; // Neuer Trolley in Puffer eingefahren Inks_Ok : Bool; // Starten aufgrund der Inks erlaubt GesamtAnzahl : Int; SSDW : Int; END_VAR BEGIN NETWORK TITLE = Parameter-Übergabe L #LeerPuffer_Nr; L 275 ;//Einsprung Puffer-DL T #Para.Leerpuffer_DL_DB;//vor Aufruf übergeben! L 0; T #Para.Leerpuffer_DL_DW; NETWORK TITLE = Anzeige OP L 252;//Bereichsstop aktiv UN #Dyn.Sk.Bereich_ok;//Also: Bereichsstop / Not-Aus SPB w010; L 253; UN #Dyn.Sk.Auto_akt;//Keine Betriebsart UN #Dyn.Sk.Hand_akt; SPB w010; L 255;//Handbetrieb aktiv U #Dyn.Sk.Hand_akt; SPB w010; L #Dyn.Sk.Akt_Schritt;//Aktiver Schritt T #Dyn.Sk.OP_Schritt; SPA OP_Ok; w010: T #Dyn.Sk.OP_Schritt; OP_Ok: NOP 0; NETWORK TITLE = Out-Bits zum Zurücksetzen / Antrieb plus starten SET ;//Jeden Zyklus neu R #Y_Schleuse_Auf; R #Neu_Trolley_in_Puffer; R #Dyn.Status."Trolley_wartet_Bereich+1"; R #Dyn.Status.Trolley_fährt_aus; R #Dyn.Status.Trolley_draussen; U #Dyn.Sk.Reset; O #Dyn.Sk.Reset_Akt; = #Dyn.Status.Reset_aktiv; SET; R #Inks_Ok; //Antrieb zusätlich starten: U #ErrQuit ;//Überwachungszeit abgelaufen quittieren S #Antrieb_plus_vor;//Kreisel-Antrieb plus starten NETWORK TITLE = HMI-Zeug //Von HMI: U #Dyn.HMI.Schleuse_resetten_Leerpuffer; R #Dyn.HMI.Schleuse_resetten_Leerpuffer; S #Dyn.Sk.Reset ;//SK zurücksetzen U #Dyn.HMI.LeerPuffer_initialisieren; S #Dyn.Status.Leerpuffer_initialisieren; R #Dyn.HMI.LeerPuffer_initialisieren; U #Dyn.HMI.Einlagern_gesperrt;//Wird unten direkt verarbeitet U #Dyn.HMI.AusLagern_gesperrt;//Wird unten direkt verarbeitet CLR; //An HMI: L #Dyn.Anzahl_LeerTrolleys; T #Dyn.HMI.Trolleys_LeerPuffer; L #Dyn.Reservierungs_DL.Datenlistenkopf.AnzahlEintraege; T #Dyn.HMI.Res_Trolleys_LeerPuffer; L #Puffer.MaxAnzahl_LeerPuffer; L #Dyn.Reservierungs_DL.Datenlistenkopf.AnzahlEintraege; -I; L #Dyn.Anzahl_LeerTrolleys; -I; T #Dyn.HMI.Frei_Plätze_LeerPuffer; NETWORK TITLE = Schrittkette OUT zurücksetzen UN #Dyn.Sk.Reset;//SK zurücksetzen SPB en04; //Schrittkette zurücksetzen: L 0;//Schritt 0: Warten T #Dyn.Sk.Akt_Schritt; L 0;//Zeitwert löschen T #Dyn.Sk.Terr_Zelle; T #Dyn.Sk.Tok_Zelle; T #Dyn.Leer_Zeit ;//Zeit für LeerCheck [1s] SET; R #Dyn.Status.Einen_LeerTrolley_ausfahren; R #Dyn.Error.Err_BLKMov;//Error bei Block kopieren R #Dyn.Sk.Reset;//SK zurücksetzen R #Dyn.Sk.Err_Schritt;//Undefinierter Schritt R #Dyn.Sk.Err_Uebzeit;//Sofort weiter ! S #Dyn.Sk.Reset_Akt;//Reset ist aktiv SET; R #Dyn.Error.Leerpuffer_DL;//Leerpuffer-Datenliste fehlerhaft R #Dyn.Error.Undef_Leerpuffer;//undefiniertes Leerpuffer R #Dyn.Error.Err_Uebzeit;//Überwachungzeit ist abgelaufen R #Dyn.Error.Err_Schritt;//Schritt-Nummer ist nicht definiert R #Dyn.Error.Err_Stau_Einfahrt;//Stau am Leerpuffer-Eingang R #Dyn.Error.Err_BLKMov; R #Dyn.Error.Err_Trolley_raus;//Trolley fährt nicht aus L 0; T #Dyn.Stau_Zeit ;//Sensor B_VorSep ist belegt [1s] T #Dyn.Mindest_Zeit ;//Sensor B_VorSep ist frei [1s] T #SAVE.Weichen_DB; T #SAVE.Weichen_DW; //Defaultwerte übergeben: L 0 ;//Damit statische Werte neu aus Datenbank geholt werden ! T #Puffer.LeerPuffer_Nr;//Nummer des Leerpuffers BEA; en04: NOP 0; NETWORK TITLE = Störungen nach Außen übergeben L 0; T "MW200"; U #Dyn.Error.Leerpuffer_DL;//Leerpuffer-Datenliste fehlerhaft = "M200.0"; U #Dyn.Error.Undef_Leerpuffer;//undefinierter Leerpuffer = "M200.1"; U #Dyn.Error.Err_Trolley_nicht_in_Schleuse;//Trolley fährt nicht in Schleuse UN #Dyn.Status.Leerpuffer_initialisieren; = "M200.2"; U #Dyn.Sk.Err_Uebzeit; UN #Dyn.Error.Err_Trolley_nicht_in_Schleuse;//Trolley fährt nicht in Schleuse UN #Dyn.Error.Err_Trolley_raus;//Trolley fährt nicht aus = #Dyn.Error.Err_Uebzeit;//Überwachungzeit ist abgelaufen = "M200.3"; NOT; R #Dyn.Sk.Err_Uebzeit_AnzOk; U #Dyn.Sk.Err_Schritt; = #Dyn.Error.Err_Schritt;//Schritt-Nummer ist nicht definiert = "M200.4"; U #Dyn.Error.Err_Stau_Einfahrt;//Stau am Leerpuffer-Eingang = "M200.5"; U #Dyn.Error.Err_BLKMov;//Error bei Block kopieren = "M200.6"; U #Dyn.Error.Err_Trolley_raus;//Trolley fährt nicht aus = "M200.7"; U #Dyn.Error.Err_Leerpuffer_nicht_leer; UN #Dyn.Status.Leerpuffer_initialisieren; = "M201.0"; CLR; = "M201.1"; = "M201.2"; = "M201.3"; = "M201.4"; U #Dyn.Error.Err_Raus_Sensor; = "M201.5"; CLR; = "M201.6"; U #Dyn.Sk.Reset_Akt;//Reset ist aktiv = #Dyn.Error.Reset_aktiv; = "M201.7"; //Andere Meldung als Überwachungszeit aktiv ?: L "MW200"; L 2#1111_0111_1111_1111; UW; L 2#0000_0000_0000_0000;//Andere Meldung als Üb.zeit aktiv ? <>I;//Ja ! ON #Dyn.Sk.Err_Uebzeit_AnzOk;//Störung anzeigen ok, da 2.Zyklus aktiv ! R "M200.3";//Üb.Zeit-Meldung nicht an PC senden U #Dyn.Sk.Err_Uebzeit; S #Dyn.Sk.Err_Uebzeit_AnzOk;//Störung anzeigen ok, da 2.Zyklus aktiv ! L "MW200"; T #Error;//Schnittstelle nach Außen //Störung vorhanden: L 0; <>I;//Ja ! = #Dyn.Status.Error_aktiv; CLR;//Es gibt keine Quittier-Störung! U #Dyn.Sk.Err_Uebzeit; S #hStOk; //Störungen pro Zyklus neu erzeugen: SET; R #Dyn.Error.Leerpuffer_DL;//Leerpuffer-Datenliste fehlerhaft R #Dyn.Error.Undef_Leerpuffer;//undefiniertes Leerpuffer /// R #Dyn.Error.Err_Trolley_nicht_in_Schleuse//Trolley fährt nicht in Schleuse /// R #Dyn.Error.Err_Uebzeit //Überwachungzeit ist abgelaufen R #Dyn.Error.Err_Schritt;//Schritt-Nummer ist nicht definiert /// R #Dyn.Error.Err_Stau_Einfahrt//Stau am Leerpuffer-Eingang R #Dyn.Error.Err_BLKMov; /// R #Dyn.Error.Err_Trolley_raus//Trolley fährt nicht aus /// R #Dyn.Error.Err_Leerpuffer_nicht_leer//Trolley ohne Daten vorhanden R #Dyn.Error.Err_Raus_Sensor; UN #Dyn.Sk.Err_Uebzeit; R #Dyn.Error.Err_Trolley_nicht_in_Schleuse;//Trolley fährt nicht in Schleuse R #Dyn.Error.Err_Trolley_raus;//Trolley fährt nicht aus NETWORK TITLE = Statische Leerpuffer-Parameter holen L #Puffer.LeerPuffer_Nr;//Nummer des Leerpuffers L #LeerPuffer_Nr;//Aufruf-Parameter ==I;//Identisch ? R #Dyn.Error.Leerpuffer_DL;//Leerpufferdatenbank fehlerhaft R #Dyn.Error.Undef_Leerpuffer;//undefiniertes Leerpuffer SPB en06;//Ja ! T "MW200";//Search-Daten CALL "DatenOut" ( SSDB := #Para.Leerpuffer_DL_DB , SSDW := #Para.Leerpuffer_DL_DW , PARA := WORD#16#0000 , SEARCHDATEN := P#M200.0 , RE_VAL := #Dyn.Rueckmld.RET_VAL_DL_Leerpuffer , OUTDATEN := P#M220.0 , Position := "MW196" ); SPBI G_Ok; U "M199.0"; SPBN w060; SET; = #Dyn.Error.Leerpuffer_DL;//Leerpufferdatenbank fehlerhaft L 16#A071; T #Dyn.Stop_Ursache; BEA; w060: SET; S #Dyn.Error.Undef_Leerpuffer;//undefinierter Leerpuffer L 16#0072; T #Dyn.Stop_Ursache; BEA; //Kennung + Datenbytes G_Ok: SET; R #Dyn.Error.Leerpuffer_DL;//Gefälledatenbank fehlerhaft R #Dyn.Error.Undef_Leerpuffer;//undefinierte Gefällestrecke L 16#1004;//Kennung 10 + Word=04 T %LW0;//Any-Kennung, Datentyp L 20;//Datenwords speichern T %LW2;//Wiederholungen //Quelle-Pointer erzeugen: L 0;//Bei Merker = 0 ! T %LW4;//DB_Nummer L 220;//Adresse SLD 3; L 16#8300_0000;//Kennung: Merker OD; T %LD6;//Kennung, Adresse CALL BLKMOV//Datenliste-Daten speichern {blk_type := 'Variant'} ( SRCBLK := #Quelle , RET_VAL := #Dyn.Rueckmld.RET_VAL_BLKMOV_Leerpuffer , DSTBLK := #Puffer //#Ziel ); L 16#0073; T #Dyn.Stop_Ursache; L #Dyn.Rueckmld.RET_VAL_BLKMOV_Leerpuffer;//Rückmeldung L 0;//Fehler vorhanden ? <>I;//Ja ! = #Dyn.Error.Err_BLKMov ;//Error bei Block kopieren BEB; L #Puffer.Puffer_Typ ;//Puffertyp = 1277 (Leerpuffer) L 1277 ;//Dieser Aufruf-FB ? ==I;//Ja ! SPB w061; SET; S #Dyn.Error.Undef_Leerpuffer;//undefinierter Leerpuffer L 0 ;//Leerpuffer ungültig ! T #Puffer.LeerPuffer_Nr;//Nummer des Leerpuffers L 16#0074; T #Dyn.Stop_Ursache; BEA; //Defaultwerte übergeben: w061: NOP 0; BEA; en06: NOP 0; NETWORK TITLE = Störungen quittieren U #ErrQuit ;//Überwachungszeit abgelaufen quittieren R #Dyn.Sk.Err_Uebzeit; NETWORK TITLE = Einfahrenden Trolley in Puffer eintragen L #Dyn.TrolleyID_Einfahrt; T "MD220"; L DINT#0; ==I; SPB NoNewT; SET; S #Neu_Trolley_in_Puffer; //Neue Position an Gesamt-Trolley-DL übergeben: CALL "Trolley_DL_Neue_Pos" ( Gesamt_Trolley_DL := #Puffer.Gesamt_Trolley_DL , TrolleyID := #Dyn.TrolleyID_Einfahrt , Position := #Puffer.Puffer_Position , ShopGroup := Dint#0 , Err := "M199.0" ); //Daten Puffer eintragen checken: L #Dyn.Anzahl_LeerTrolleys; + 1; T #Dyn.Anzahl_LeerTrolleys; //Austrag aus Trolley-Reservierungsliste L #Dyn.TrolleyID_Einfahrt;//Eintrag ist erfolgt T "MD220"; ResOut: L #Puffer.Puffer_Dyn_DW; L #Puffer.PufferReservierungsliste_DW; +I; T #SSDW; CALL "DatenOut" ( SSDB := #Puffer.Puffer_Dyn_DB , SSDW := #SSDW , PARA := 16#E100 , //Eintrag löschen SEARCHDATEN := P#M220.0 , RE_VAL := #Dyn.Rueckmld.RET_VAL_DL_Res , OUTDATEN := P#M220.0 , //Nicht relevant Position := "MW196" ); L DINT#0; T #Dyn.TrolleyID_Einfahrt; NoNewT: NOP 0; NETWORK TITLE = Error: Stau Bereich-Eingang //Sensor bei Bereichs-Einfahrt bleibt belegt?: UN #B_LeerpufferEinfahrt ;//Sensor Trolley fährt in Bereich (kein Stau !) R #Dyn.Error.Err_Stau_Einfahrt;//Stau bei Einfahrt SPB X090 ;//StauZeit neu aufziehen UN "1s-Impuls"; O #Dyn.Error.Err_Stau_Einfahrt;//Zeit bereits abgelaufen SPB Xn09; L #Dyn.Stau_Zeit ;//Sensor B_VorSep ist belegt [1s] + +1; T #Dyn.Stau_Zeit ;//Sensor B_VorSep ist belegt [1s] L 25 ;//Stau-Zeit erreicht ? >=I;//Ja ! S #Dyn.Error.Err_Stau_Einfahrt;//Stau bei Einfahrt (Quittierung oder Sensor=0, wegen Bürstenantrieb SPBN Xn09; X090: L 0 ;//Zeiten löschen T #Dyn.Stau_Zeit ;//Sensor B_VorSep ist belegt [1s] Xn09: NOP 0; NETWORK TITLE = Schleuse: Mindestzeit geöffnet/frei, Position-Inks übergeben L #Dyn.Sk.Akt_Schritt; L 6 ;//Mindestzeit ok? <>I;//Nein! O #B_InSchleuse ;//Sensor Trolley in Schleuse vorhanden ON #Schleuse_geöffnet;//Schleuse hat geöffnet R #Dyn.Status.MindestZeit_ok; SPB X100 ;//FreiZeit neu aufziehen UN "1s-Impuls"; O; U #Puffer.Parameter_allg.Antrieb_Plus_vorhanden; UN #Antrieb_plus_aktiv; O #Dyn.Status.MindestZeit_ok;//Zeit bereits abgelaufen SPB Xn10; L #Dyn.Mindest_Zeit ;//Sensor B_im_Sep ist frei [1s] + +1; T #Dyn.Mindest_Zeit ;//Sensor B_im_Sep ist frei [1s] L #Puffer.Mindeszeit_Schleuse_geoeffnet ;//Mindest-Zeit erreicht ? >=I;//Ja ! S #Dyn.Status.MindestZeit_ok; SPBN Xn10; X100: L 0 ;//Zeiten löschen T #Dyn.Mindest_Zeit ;//Sensor B_im_Sep ist frei [1s] //Schleuse geöffnet: (Position-Inks übergeben) Xn10: UN #Schleuse_geöffnet ;//Schleuse hat geöffnet SPB X10E; L #Ausfahr_Inks; L #Puffer.Puffer_Position_Inks; >I;//Rest-Inks-Wert ist größer! SPB X10E; L #Puffer.Puffer_Position_Inks; T #Ausfahr_Inks; X10E: NOP 0; NETWORK TITLE = Keine neue Trolley-Einfahrt ? //Neu-Trolley ist im Puffer: U #Neu_Trolley_in_Puffer;//s.o. O #B_LeerpufferEinfahrt;//Stauklappe SPB X110; UN "1s-Impuls"; O #Dyn.Status.Kein_neuer_Trolley_kommt; SPB Xn11; L #Dyn.Leer_Zeit ;//Zeit für LeerCheck [1s] + +1; T #Dyn.Leer_Zeit ;//Zeit für LeerCheck [1s] L #Puffer.Wartezeit_bis_Puffer_leer;//Leer-Zeit erreicht ? >=I;//Ja ! SPBN Xn11; T #Dyn.Leer_Zeit ;//Zeit für LeerCheck einfrieren SET; S #Dyn.Status.Kein_neuer_Trolley_kommt; SPA Xn11; X110: L 0 ;//Zeiten löschen T #Dyn.Leer_Zeit; SET; R #Dyn.Status.Kein_neuer_Trolley_kommt; Xn11: NOP 0; NETWORK TITLE = Reservierungs-Check L #Dyn.Reservierungs_DL.Datenlistenkopf.AnzahlEintraege; L 0; ==I; O "MB3305";//Trolley wird gerade vereinzelt O "BG3306";//Synchron-Sensor aktiv SPB NoResCheck ;//Später -> Hauptstrangdaten checken! //Trolleys noch unterwegs ? L "LP_TravelFIFO".Travel_FIFO_BG3306.FIFO.ANZAHL; L "LP_HS_oF".Datensortkopf.AnzahlEintraege; +I; L "LP_HS_mF".Datensortkopf.AnzahlEintraege; +I; L 0;//Es sind noch Trolleys unterwegs <>I; SPB NoResCheck; L #Dyn.Reservierungs_DL.Res_Trolley[1].Trolley_ID; T "MD220"; SPA ResOut; NoResCheck: NOP 0; NETWORK TITLE = Leer-Check aktiv //Falls Inilauf aktiv: U #Dyn.Status.Leerpuffer_initialisieren; UN #Dyn.Status.Leer_Check_aktiv; S #Dyn.Status.Leer_Check_aktiv; SPBN Check;//Negierter Sprung L 0 ;//Zeiten neu aufziehen T #Dyn.Leer_Zeit; SET; R #Dyn.Status.Kein_neuer_Trolley_kommt; Check: NOP 0; //Inilauf, kein Daten aber Trolley ist in Schleuse: U #Dyn.Status.Leerpuffer_initialisieren; U #B_InSchleuse; U(; L #Dyn.Anzahl_LeerTrolleys; L 0; ==I; ); UN #Dyn.Status.Einen_LeerTrolley_ausfahren; S #Dyn.Status.Einen_LeerTrolley_ausfahren ;//Trolley zwingend ausfahren //Abbruch, da Trolley ist doch noch in Schleuse gefahren: U #Dyn.Status.Leerpuffer_initialisieren; U #B_InSchleuse; U(; L #Dyn.Anzahl_LeerTrolleys;//Anzahl wurde eingetragen L 0; >I; O #Dyn.Status.Trolley_nicht_in_Schleuse; ); R #Dyn.Status.Leerpuffer_initialisieren; R #Dyn.Status.Trolley_nicht_in_Schleuse; R #Dyn.Status.Leer_Check_aktiv; UN #Dyn.Status.Leer_Check_aktiv; SPB Xn12; //Trolley während Check erkannt: UN #Dyn.Status.Kein_neuer_Trolley_kommt;//nichts mehr eingefahren, SPB Xn12; //Aber: U #Schleuse_geöffnet ;//aber Schleuse noch geöffnet O #B_InSchleuse;//aber Trolley noch in Schleuse SPBN Fertig ;//Negierter Sprung L 0 ;//Zeit neu aufziehen T #Dyn.Leer_Zeit; SET; R #Dyn.Status.Kein_neuer_Trolley_kommt; SPA Xn12; Fertig: SET; R #Dyn.Status.Leer_Check_aktiv; R #Dyn.Status.Trolley_nicht_in_Schleuse; U #Dyn.Status.Leerpuffer_initialisieren; R #Dyn.Status.Leerpuffer_initialisieren; SPBN Reset ;//Negierter Sprung L 0; T #Dyn.Anzahl_LeerTrolleys;//Minimum übergeben SPA Xn12 ;//Nicht mehr wegen Gefahr der Überfüllung, besser Reservierungen checken //Reservierungs-Liste löschen: L #Puffer.Puffer_Dyn_DW; L #Puffer.PufferReservierungsliste_DW; +I; T #SSDW; CALL "DatenReset" ( SSDB := #Puffer.Puffer_Dyn_DB , SSDW := #SSDW , RE_VAL := "MB198" ); SPA Reset; Xn12: NOP 0; NETWORK TITLE = Reset aktiv SPA En14; Reset: SET; R #Dyn.HMI.LeerPuffer_initialisieren;//Button-Anzeige wieder normal R #Dyn.Status.Trolley_nicht_in_Schleuse; R #Dyn.Status.Puffer_nicht_leer; R #Status2.Eintrag_DL_Leerliste_erfolgt; R #Status2.Eintrag_DL_Reinliste_erfolgt; R #Status2.Eintrag_Abrufliste_erfolgt; R #Dyn.Error.Err_Raus_Sensor; L 0; T #Dyn.Leer_Zeit; T #Puffer.LeerPuffer_Nr;//Nummer des Leerpuffers (damit Leerpufferdaten neu geholt werden!) En14: NOP 0; NETWORK TITLE = Puffer hat Platz / ist frei / Einlagern aktiv //Puffer hat Platz: L #Dyn.Reservierungs_DL.Datenlistenkopf.AnzahlEintraege; L #Dyn.Anzahl_LeerTrolleys; +I; T #GesamtAnzahl; L #Puffer.MaxAnzahl_LeerPuffer; I; U #Dyn.Status."Puffer_hat Platz"; UN #Status2.Auslagern_ist_aktiv; S #Status2.Einlagern_ist_aktiv; U #Status2.Auslagern_ist_aktiv;//Wegen FIFO O #Dyn.HMI.Einlagern_gesperrt; R #Status2.Einlagern_ist_aktiv; NETWORK TITLE = Starten aus Leerpuffer aufgrund von Ausfahrsituation ok L #Puffer.Puffer_Position_Inks; L 0;//Undefiniert ? ==I;//Ja! SPB X14E; L #Ausfahr_Inks ;//Trolles auf Förderer vorbei? L 0;//Undefiniert ? ==I;//Ja! SPB X14E; L #Puffer.Puffer_Position_Inks; L 20;//damit vorbeifahrender Trolley größeren Abstand bekommt -I; L #Ausfahr_Inks ;//Trolleys auf Förderer vorbei? >I;//Ja! O(; L 1;//Minimalwert ? ==I;//Ja ! ); = #Inks_Ok; X14E: NOP 0; NETWORK TITLE = DLPuffer_leer: Ein-/Austrag UN #Dyn.Status.Puffer_leer;//Kann mit neuen Leertrolleys bestückt werden! O #Dyn.HMI.Einlagern_gesperrt; O #Dyn.Status.Leerpuffer_initialisieren; SPB Austrag_Leerliste; //Eintrag aus Leerliste: L #LeerPuffer_Nr; T "MW220" ;//Puffer, der leer ist CALL "DatenIn"//Anforderung in Datenliste eintragen ( SSDB := 500 , SSDW := 0 , INDATEN := P#M220.0 , RE_VAL := "MB219" ); UN "M219.6";//Daten wurden überschrieben UN "M219.7";//Eintrag ist richtig erfolgt SPB NoChange_Leerliste; SET; S #Status2.Eintrag_DL_Leerliste_erfolgt; SPA NoChange_Leerliste; Austrag_Leerliste: NOP 0; //Austrag aus Leerliste: L #LeerPuffer_Nr; T "MW220" ;//Puffer, der leer ist CALL "DatenOut"//Anforderung aus Datenliste löschen ( SSDB := 500 , SSDW := 0 , PARA := WORD#16#E100 , SEARCHDATEN := P#M220.0 , RE_VAL := "MB219" , OUTDATEN := P#M230.0 , Position := "MW196" ); SET; R #Status2.Eintrag_DL_Leerliste_erfolgt; NoChange_Leerliste: NOP 0; NETWORK TITLE = DLPuffer_einfahren: Ein-/Austrag UN #Dyn.Status."Puffer_hat Platz";//Puffer hat kein Platz mehr ON #Status2.Einlagern_ist_aktiv; O #Dyn.HMI.Einlagern_gesperrt; O #Dyn.Status.Leerpuffer_initialisieren; R #Status2.Einlagern_ist_aktiv; SPB Austrag_Reinliste; //Eintrag in Reinliste: U(; L #Dyn.Reservierungs_DL.Datenlistenkopf.AnzahlEintraege; L 0;//Reservierung schon erfolgt ? >I;//Ja! O #Status2.Einlagern_ist_aktiv; ); SPBN NoChange_Reinliste ;//Negierter Sprung L #LeerPuffer_Nr ;//angefahrener Puffer T "MW220"; CALL "DatenIn"//Anforderung in Datenliste eintragen ( SSDB := 501 , SSDW := 0 , INDATEN := P#M220.0 , RE_VAL := "MB219" ); UN "M219.6";//Daten wurden überschrieben UN "M219.7";//Eintrag ist richtig erfolgt SPB NoChange_Reinliste; SET; S #Status2.Eintrag_DL_Reinliste_erfolgt; SPA NoChange_Reinliste; Austrag_Reinliste: NOP 0; //Austrag aus Reinliste: L #LeerPuffer_Nr; T "MW220"; CALL "DatenOut"//Anforderung aus Datenliste löschen ( SSDB := 501 , SSDW := 0 , PARA := WORD#16#E100 , SEARCHDATEN := P#M220.0 , RE_VAL := "MB219" , OUTDATEN := P#M230.0 , Position := "MW196" ); SET; R #Status2.Eintrag_DL_Reinliste_erfolgt; NoChange_Reinliste: NOP 0; NETWORK TITLE = DLPuffer_ausfahren: Ein-/Austrag U #Dyn.Status.Puffer_leer;//Kann mit neuen Leertrolleys bestückt werden! UN #Dyn.Error.Err_Leerpuffer_nicht_leer;//Damit Trolley ausgefahren werden kann! O #Dyn.HMI.AusLagern_gesperrt; R #Dyn.Status.Einen_LeerTrolley_ausfahren; SPB Austrag_Abrufliste; //Eintrag aus Abrufliste: U #B_InSchleuse ;//Sobald Trolley in Ausfahrschleuse SPBN NoChange_Abrufliste;//Negierter Sprung L #LeerPuffer_Nr ;//angefahrener Puffer T "MW220"; CALL "DatenIn"//Anforderung in Datenliste eintragen ( SSDB := 502 , SSDW := 0 , INDATEN := P#M220.0 , RE_VAL := "MB219" ); UN "M219.6";//Daten wurden überschrieben UN "M219.7";//Eintrag ist richtig erfolgt SPB NoChange_Abrufliste; SET; S #Status2.Eintrag_Abrufliste_erfolgt; SPA NoChange_Abrufliste; Austrag_Abrufliste: NOP 0; //Austrag aus Abrufliste: Austrag: L #LeerPuffer_Nr ;//angefahrener Puffer T "MW220"; CALL "DatenOut"//Anforderung aus Datenliste löschen ( SSDB := 502 , SSDW := 0 , PARA := WORD#16#E100 , SEARCHDATEN := P#M220.0 , RE_VAL := "MB219" , OUTDATEN := P#M230.0 , Position := "MW196" ); SET; R #Status2.Eintrag_Abrufliste_erfolgt; NoChange_Abrufliste: NOP 0; NETWORK TITLE = Schrittkette anhalten U #Dyn.Sk.Auto_akt;//Automatik ist aktiv U #Dyn.Sk.Bereich_ok; SPA en08_Mig;//Schrittkette nicht anhalten ! SET;//Störungen löschen R #Dyn.Sk.Err_Uebzeit; R #Dyn.Sk.Err_Schritt; L 0;//Zeitwerte löschen T #Dyn.Sk.Terr_Zelle; T #Dyn.Sk.Tok_Zelle; BEA; en08_Mig: NOP 0; NETWORK TITLE = Sprungverteiler OUT_Sk: L #Dyn.Sk.Neu_Schritt;//Schritt, der im nächsten Zyklus aktiv werden soll L -1;//angegeben ? ==I;//Nein ! SPB NEU; TAK;//Neuen Schritt übergeben T #Dyn.Sk.Akt_Schritt; L -1;//Urzustand T #Dyn.Sk.Neu_Schritt;//Schritt, der im nächsten Zyklus aktiv werden soll NEU: SET; R #Ueb_akt ;//Überwachungszeit aktivieren R #Warte_neu;//Wartezeit neutriggern R #Warte_stop;//Wartezeit stoppen L #Dyn.Sk.Akt_Schritt; SPL Ende; SPA s000;//Schritt 0 SPA s001;//Schritt 1 SPA s002;//Schritt 2 SPA s003;//Schritt 3 SPA s004;//Schritt 4 SPA s005;//Schritt 5 SPA s006;//Schritt 6 SPA s007;//Schritt 7 SPA s008;//Schritt 8 SPA s009;//Schritt 9 SPA s010;//Schritt 10 SPA s011;//Schritt 11 SPA s012;//Schritt 12 SPA s013;//Schritt 13 SPA s014;//Schritt 14 SPA s015;//Schritt 15 SPA s016;//Schritt 16 SPA s017;//Schritt 17 SPA s018;//Schritt 18 SPA s019;//Schritt 19 SPA s020;//Schritt 20 SPA s021;//Schritt 21 SPA s022;//Schritt 22 SPA s023;//Schritt 23 SPA s024;//Schritt 24 SPA s025;//Schritt 25 SPA s026;//Schritt 26 SPA s027;//Schritt 27 SPA s028;//Schritt 28 SPA s029;//Schritt 29 SPA s030;//Schritt 30 Ende: S #Dyn.Sk.Err_Schritt;//Undefinierter Schritt L 16#A231; T #Dyn.Stop_Ursache; BEA; Neu_Mig: U #Dyn.Sk.Err_Uebzeit; SPBN Sk; L 16#A232; T #Dyn.Stop_Ursache; BEA; Sk: T #Dyn.Sk.Akt_Schritt; L 0;//Zeitwerte löschen T #Dyn.Sk.Terr_Zelle; T #Dyn.Sk.Tok_Zelle; SPA NEU; //Nicht programmierte Schritte: //s000: SPA Ende //s001: SPA Ende //s002: SPA Ende s003: SPA Ende; s004: SPA Ende; //s005: SPA Ende //s006: SPA Ende //s007: SPA Ende s008: SPA Ende; s009: SPA Ende; s010: SPA Ende; s011: SPA Ende; s012: SPA Ende; s013: SPA Ende; s014: SPA Ende; s015: SPA Ende; s016: SPA Ende; s017: SPA Ende; s018: SPA Ende; s019: SPA Ende; //s020: SPA Ende //s021: SPA Ende s022: SPA Ende; s023: SPA Ende; s024: SPA Ende; s025: SPA Ende; s026: SPA Ende; s027: SPA Ende; s028: SPA Ende; s029: SPA Ende; s030: SPA Ende; NETWORK TITLE = Schritt X: Reserve SET;//Weiterschaltbedingung = #Weiter; //Schrittaktionen: SET; L 16#B001; T #Dyn.Stop_Ursache; U #Dyn.Sk.Reset_Akt;//Reset ist aktiv L 20;//Weiter mit Schritt 20 SPB Neu_Mig;//Bei diesem Schritt weiter U #Weiter;//Weiterschaltbedingung ist erfüllt R #Dyn.Sk.Err_Uebzeit;//Sofort weiter ! L 0 ;//Angabe der Wartezeit (*10ms) SPB Plus;//Nächsten Schritt starten L 1;//Weiter mit Schritt 1 SPB Neu_Mig;//Bei diesem Schritt weiter T #Dyn.Sk.Neu_Schritt;//Schritt, der im nächsten Zyklus aktiv werden soll SET; U #Dyn.Sk.Auto_akt;//Automatik ist aktiv U #Dyn.Sk.Bereich_ok; = #Ueb_akt;//Überwachungszeit aktivieren L 50 ;//Angabe der Überwachungszeit (*1s) SPA tueb;//Überwachungszeit BEA; NETWORK TITLE = Schritt 0: Warten auf Trolley s000: SET;//Weiterschaltbedingung U #B_InSchleuse ;//Trolley im Schleuse erkannt U #Dyn.Sk.Auto_akt ;//Automatik ist aktiv U #Dyn.Sk.Bereich_ok; = #Weiter; //Schrittaktionen: SET; R #Dyn.Error.Err_Leerpuffer_nicht_leer; U #Dyn.Sk.Reset_Akt;//Reset ist aktiv L 20;//Weiter mit Schritt 20 SPB Neu_Mig;//Bei diesem Schritt weiter U #Weiter;//Weiterschaltbedingung ist erfüllt R #Dyn.Sk.Err_Uebzeit;//Sofort weiter ! L 100 ;//Angabe der Wartezeit (*10ms) SPB Plus;//Nächsten Schritt starten L 16#B001; T #Dyn.Stop_Ursache; //Trolley soll gestartet werden: U #Dyn.Status.Einen_LeerTrolley_ausfahren;//Von FB5429/2 U(; U #Dyn.Sk.Err_Uebzeit; UN #B_InSchleuse ;//Trolley im Schleuse erkannt O #Dyn.Status.Leerpuffer_initialisieren;//Damit Einfahren blockiert wird ); R #Dyn.Status.Einen_LeerTrolley_ausfahren;//Von FB5429/2 SPBN ÜbStart; L "DLP_Auslagern".Auslagern.Auslager_Puffer; L #LeerPuffer_Nr; <>I; SPB ENDE_Mig; L 0; T "DLP_Auslagern".Auslagern.Auslager_Puffer; SPA Austrag;//Puffer aus Ausfahr-Liste löschen //Überwachungszeit starten: ÜbStart: UN #B_InSchleuse ;//Trolley im Schleuse erkannt U #Dyn.Status.Einen_LeerTrolley_ausfahren;//Von FB5429/2 = #Ueb_akt ;//Überwachungszeit aktivieren //Trolley kommt nicht!: L #Dyn.Anzahl_LeerTrolleys; L 0;//Trolleydaten vorhanden ? >I ;//Ja ! U #Dyn.Sk.Err_Uebzeit; UN #B_InSchleuse ;//Trolley im Schleuse erkannt UN #Dyn.Status.Trolley_nicht_in_Schleuse; S #Dyn.Status.Trolley_nicht_in_Schleuse; S #Dyn.Status.Leerpuffer_initialisieren;//Damit Einfahren blockiert wird L 15 ;//15s U #Dyn.Status.Einen_LeerTrolley_ausfahren;//Bei Ausfahrwunsch -> Kurze Zeit SPB tueb ;//Überwachungszeit L #Puffer.Übzeit_in_Schleuse; SPA tueb;//Überwachungszeit NETWORK TITLE = Schritt 1: Trolley ist in Schleuse / Warten auf Bit "Einen Trolley ausfahren" s001: NOP 0; //Schrittaktionen: UN #B_InSchleuse ;//Trolley im Schleuse erkannt L 0 ;//Weiter mit Schritt 0 SPB Neu_Mig;//Bei diesem Schritt weiter SET; R #Dyn.Error.Err_Trolley_nicht_in_Schleuse; //Puffer leer ?: U #Dyn.Status.Puffer_leer; UN #Dyn.Status.Puffer_nicht_leer; S #Dyn.Status.Puffer_nicht_leer; S #Dyn.Status.Leerpuffer_initialisieren;//Damit Einfahren blockiert wird //Spezial-Betriebsarten: U #Dyn.Status.Einen_LeerTrolley_ausfahren; L 2 ;//Weiter mit Schritt 2 SPB Neu_Mig ;//Bei diesem Schritt weiter L 16#B011; T #Dyn.Stop_Ursache; BEA; NETWORK TITLE = Schritt 2: Ausfahren ok ? s002: NOP 0; //Schrittaktionen: UN #B_InSchleuse ;//Trolley im Schleuse erkannt L 0 ;//Weiter mit Schritt 0 SPB Neu_Mig;//Bei diesem Schritt weiter SET; S #Dyn.Status."Trolley_wartet_Bereich+1"; //Anlage aus oder Störung: L 16#B020; T #Dyn.Stop_Ursache; UN #Dyn.Sk.Auto_akt ;//Automatik ist aktiv ON #Dyn.Sk.Bereich_ok;//Bereich ist gestört SPB X002; //Trolley starten erlaubt ?: L 16#B021; T #Dyn.Stop_Ursache; UN #Start_Ok ;//Starten ist erlaubt SPB X002; //Stau im Bereich +1: L 16#B022; T #Dyn.Stop_Ursache; U #B_Stau_raus_Out; SPB X002 ;//Stau //B_Aus_Schleuse aktiv: L 16#B023; T #Dyn.Stop_Ursache; U #Puffer.Parameter_allg.B_AusSep_vorhanden; U #B_AusSchleuse; = #Dyn.Error.Err_Raus_Sensor;//Raus-Sensor wird nicht erreicht (oder dauernd aktiv)! SPB X002; //Inks ok ?: L 16#B024; T #Dyn.Stop_Ursache; SET; S #Antrieb_plus_vor; UN #Inks_Ok ;//Starten ist erlaubt SPB X002; //Antriebe aktivieren / aktiv ?: U #Puffer.Parameter_allg.Antrieb_Plus_vorhanden;//Schleuse an weiterem Antrieb (Weiche) S #Antrieb_plus_vor;//Kreisel-Antrieb plus starten L 16#B025; T #Dyn.Stop_Ursache; UN #Antrieb_plus_aktiv;//Kreisel-Antrieb plus aktiv U #Puffer.Parameter_allg.Antrieb_Plus_vorhanden;//Schleuse an weiterem Antrieb (Weiche) BEB; L 5 ;//Nur 1 langes Signal! SPA Neu_Mig ;//Bei diesem Schritt weiter X002: L 1 ;//Auftrag checken T #Dyn.Sk.Neu_Schritt;//Schritt, der im nächsten Zyklus aktiv werden soll BEA; NETWORK TITLE = Schritt 5: Trolley fährt aus/ausgefahren ? s005: SET ;//Weiterschaltbedingung UN #B_InSchleuse ;//Sensor Trolley ist in Schleuse U #Schleuse_geöffnet; U #Antrieb_plus_aktiv; = #Weiter; //Schrittaktionen: SET; S #Y_Schleuse_Auf ;//Schleuse öffnen R #Start_Ok;//Damit kein weiterer Puffer ausfährt S #Dyn.Status.Trolley_fährt_aus; S #Antrieb_plus_vor;//Kreisel-Antrieb plus starten S #Status2.Auslagern_ist_aktiv; //Trolley ist draussen: U(; O #B_AusSchleuse ;//Sensor Trolley aus Schleuse gefahren ON #Puffer.Parameter_allg.B_AusSep_vorhanden; ); UN #B_InSchleuse ;//Sensor Trolley ist in Schleuse R #Dyn.Error.Err_Trolley_raus;//Trolley fährt nicht aus L 0; SPB Plus ;//Nächsten Schritt starten U #Weiter;//Weiterschaltbedingung ist erfüllt R #Dyn.Error.Err_Trolley_raus;//Trolley fährt nicht aus L 50;//Falls nur mit Sensor gefahren wird, dann Wartezeit! SPB Plus ;//Nächsten Schritt starten //Trolley fährt nicht raus!: U #Weiter;//Weiterschaltbedingung ist erfüllt R #Dyn.Sk.Err_Uebzeit;//Sofort weiter ! R #Dyn.Error.Err_Trolley_raus;//Trolley fährt nicht aus L 0; SPB Plus ;//Nächsten Schritt starten U #Dyn.Sk.Err_Uebzeit; O #B_QuerTrolley_Out;//QuerTrolley auf Crashkurs S #Dyn.Error.Err_Trolley_raus;//Trolley fährt nicht aus L 16#B051; T #Dyn.Stop_Ursache; UN #B_AusSchleuse ;//Sensor Trolley aus Schleuse gefahren SPB x052; L 16#B052; T #Dyn.Stop_Ursache; x052: U #Antrieb_plus_aktiv; = #Ueb_akt;//Überwachungszeit aktivieren L #Puffer.Übzeit_aus_Schleuse;//Angabe der Überwachungszeit (*1s) SPA tueb ;//Überwachungszeit NETWORK TITLE = Schritt 6: Schleuse Mindestzeit geöffnet ? s006: SET ;//Weiterschaltbedingung U #Dyn.Status.MindestZeit_ok; O; U #Puffer.Parameter_allg.B_AusSep_vorhanden; U #B_AusSchleuse ;//Sensor Trolley aus Schleuse gefahren = #Weiter; //Schrittaktionen: U #B_QuerTrolley_Out ;//QuerTrolley auf Crashkurs S #Dyn.Error.Err_Trolley_raus;//Trolley fährt nicht aus SET; R #Start_Ok;//Damit kein weiterer Puffer ausfährt S #Y_Schleuse_Auf ;//Schleuse öffnen S #Antrieb_plus_vor;//Kreisel-Antrieb plus starten S #Dyn.Status.Trolley_fährt_aus; U #B_InSchleuse;//Trolley wieder erkannt L 5 ;//Weiter mit Schritt 5 SPB Neu_Mig;//Bei diesem Schritt weiter U #Weiter; L 0; SPB Plus ;//Nächsten Schritt starten L 16#B061; T #Dyn.Stop_Ursache; BEA; NETWORK TITLE = Schritt 7: Trolleydaten ändern s007: SET ;//Weiterschaltbedingung = #Weiter; //Schrittaktionen: SET; S #Dyn.Status.Trolley_draussen;//1 Zyklus R #Dyn.Status.Einen_LeerTrolley_ausfahren; L #Dyn.Vereinzelungstakte; + DINT#1;//Vereinzelungen +1 T #Dyn.Vereinzelungstakte; L #Dyn.Anzahl_LeerTrolleys; + -1; T #Dyn.Anzahl_LeerTrolleys; L 0;//sinnvoller Wert? >I;//Ja! SPB ENDE_Mig; T #Dyn.Anzahl_LeerTrolleys;//Minimum übergeben SPA ENDE_Mig; NETWORK TITLE = Schritt 20: Schleuse resetten s020: SET;//Weiterschaltbedingung = #Weiter;//Weiterschaltbedingung ist erfüllt //Schrittaktionen: U #Schleuse_geöffnet; R #Start_Ok;//Damit kein weiterer Puffer ausfährt L 16#B201; T #Dyn.Stop_Ursache; U #Weiter;//Weiterschaltbedingung ist erfüllt L 300;//Angabe der Wartezeit (*10ms) SPB Plus;//Nächsten Schritt starten SET; = #Ueb_akt;//Überwachungszeit aktivieren L 30;//Angabe der Überwachungszeit (*100ms) SPA tueb;//Überwachungszeit NETWORK TITLE = Schritt 21: Reset ist zu Ende s021: SET; R #Dyn.Sk.Reset_Akt;//Reset ist aktiv R #Dyn.HMI.Schleuse_resetten_Leerpuffer; R #Dyn.Status.Einen_LeerTrolley_ausfahren; SPA ENDE_Mig;//Neubeginn NETWORK TITLE = Schrittkette beenden ENDE_Mig: L 0;//Schritt 0: Warten T #Dyn.Sk.Akt_Schritt; L 0;//Zeitwert löschen T #Dyn.Sk.Terr_Zelle; T #Dyn.Sk.Tok_Zelle; SET; R #Dyn.Sk.Err_Uebzeit; BEA; NETWORK TITLE = Nächsten Schritt aktivieren Plus: T #Dyn.Sk.T_ok;//Wartezeit übergeben U #Dyn.Sk.Err_Uebzeit ;//Störung noch nicht quittiert BEB; L 0;//keine Wartezeit ? ==I;//Ja ! -> sofort weiter SPB w220; UN #Warte_neu;//Wartezeit neutriggern SPB W220_Mig; L 0; T #Dyn.Sk.Tok_Zelle;//Wartezeit W220_Mig: U #Warte_stop;//Wartezeit stoppen BEB; L #Dyn.Sk.Tok_Zelle; L "MW4";//Wartezeit +10ms +I; T #Dyn.Sk.Tok_Zelle;//Wartezeit L #Dyn.Sk.T_ok;//abgelaufen ? I;//abgelaufen ? UN #Dyn.Sk.Err_Uebzeit; SPB en24;//Nein ! U #Ueb_akt;//Überwachungszeit aktivieren S #Dyn.Sk.Err_Uebzeit; L 0;//Zeitwert löschen T #Dyn.Sk.Terr_Zelle; BEA; en24: NOP 0; NETWORK TITLE = Überwachungszeit +1 UN #Dyn.Sk.Ueb_akt;//Schrittaktion ist aktiv ON "1s-Impuls"; BEB; L #Dyn.Sk.Terr_Zelle; + 1 ;//Üb.zeit +1s T #Dyn.Sk.Terr_Zelle; BEA; NETWORK TITLE = Ende BE; END_FUNCTION_BLOCK