=== FB 1277: MHMLeerpuffer  [STL] ===
INTERFACE:
  Input:
    LeerPuffer_Nr : Int                                 // Aufruf für Leer-Puffer
    ErrQuit : Bool                                      // Ablaufstörung quittieren
    B_LeerpufferEinfahrt : Bool                         // Sensor Trolley fährt in Leerpuffer
    B_InSchleuse : Bool                                 // Sensor Trolley ist in Schleuse unten
    B_AusSchleuse : Bool                                // Sensor Trolley hat Schleuse unten verlassen
    B_Stau_raus_Out : Bool                              // Sensor Stau im Bereich unten rausfahren
    B_QuerTrolley_Out : Bool                            // Crash-Trolley auf Crashkurs erkannt
    Antrieb_plus_aktiv : Bool                           // Kreisel-Antrieb plus aktiv
    Schleuse_geöffnet : Bool                            // Schleuse unten hat geöffnet
  Output:
    Y_Schleuse_Auf : Bool                               // Schleuse unten öffnen
    Error : Word                                        // Störungen übergeben
  InOut:
    Start_Ok : Bool                                     // Starten von ausserhalb ist erlaubt
    Antrieb_plus_vor : 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
  Static:
    Res16 : Array[1..2] of Int                          // Reserve
    SAVE : Struct
      Weichen_DB : Int                                  // Weichen-FIFO-DB
      Weichen_DW : Int                                  // Weichen-FIFO-DW
    Para : Struct                                       // Parameter
      Leerpuffer_DL_DB : Int                            // Einsprung Leerpuffer-Datenliste-DB
      Leerpuffer_DL_DW : Int                            // Einsprung Leerpuffer-Datenliste-DW
      Res1 : Array[1..2] of Int                         // Reserve
    Status2 : Struct
      Einlagern_ist_aktiv : Bool                        // Puffer mit Einlagern aktiv
      Auslagern_ist_aktiv : Bool                        // Puffer mit Auslagern aktiv
      Eintrag_DL_Leerliste_erfolgt : Bool               // Eintrag in DLLPPuffer_leer (DB500) erfolgt
      Eintrag_DL_Reinliste_erfolgt : Bool               // Eintrag in DLLPPuffer_Einfahren (DB501) erfolgt
      Eintrag_Abrufliste_erfolgt : Bool                 // Eintrag in DLLPPuffer_Ausfahren (DB502) erfolgt
    Puffer : "UDLHMLeerPuffer"                          // Statische Leerpufferdaten (aus DL)
    Dyn : Struct                                        // Dynamische Daten
      Status : Struct
        Puffer_leer : Bool                              // Puffer ist leer
        Puffer_hat Platz : Bool                         // Puffer hat noch Kapazität
        Kein_neuer_Trolley_kommt : Bool                 // Leerpuffer zeitlang ohne neuen Trolley
        Leer_Check_aktiv : Bool                         // Leerpuffer wird auf leer gecheckt
        Reset_aktiv : Bool                              // Reset aktiv
        Trolley_nicht_in_Schleuse : Bool                // Trolley fährt nicht in Schleuse > Inilauf gestartet
        Puffer_nicht_leer : Bool                        // Puffer nicht leer > Inilauf gestartet
        Leerpuffer_initialisieren : Bool                // Leerpuffer initialisieren 
        MindestZeit_ok : Bool                           // Schleuse ist MindestZeit geöffnet
        Res711 : Bool
        Res712 : Bool
        Trolley_wartet_Bereich+1 : Bool                 // Auslagerstrecke noch belegt
        Einen_LeerTrolley_ausfahren : Bool              // Einen Leer-Trolley ausfahren
        Trolley_fährt_aus : Bool                        // Trolley fährt aus Puffer
        Trolley_draussen : Bool                         // Trolley ist ausgefahren (1 Zyklus)
        Error_aktiv : Bool                              // Störung vorhanden
      TrolleyID_Einfahrt : DInt                         // Trolley-Nr ist eingefahren
      HMI : Struct
        Trolleys_LeerPuffer : Int                       // Anzahl Trolleys unten (IN:PLC, OUT:PLC)
        Res_Trolleys_LeerPuffer : Int                   // Anzahl reservierte Trolleys oben (IN:PLC, OUT:PLC)
        Frei_Plätze_LeerPuffer : 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)
      Sk : "USk_Omni"                                   // Status der Schrittkette Schleuse OUT (unten)
      Rueckmld : Struct
        RET_VAL_BLKMOV_Leerpuffer : Int                 // Rückmeldung nach BLKMOV-Aufruf
        RET_VAL_DL_Leerpuffer : Byte                    // Rückmeldung nach DatenOut-Aufruf
        RET_VAL_DL_Res : Byte                           // Rückmeldung nach DatenOut-Aufruf
        RET_VAL_DL_LeerpufferTrolley_IN : Byte          // Rückmeldung nach DatenIN-Aufruf
        RET_VAL_DL_LeerpufferTrolley : Byte             // Rückmeldung nach DatenOut-Aufruf
      Error : "UErrHMLeerPuffer"
      Stau_Zeit : Int                                   // Sensor B_Einfahrt ist belegt [1s]
      Mindest_Zeit : Int                                // Sensor B_in_Schleuse unten ist frei [1s]
      Leer_Zeit : Int                                   // Puffer unten ist frei [1s]
      Stop_Ursache : Word                               // Stop-Stelle: Nw + Position
      Vereinzelungstakte : DInt                         // Anzahl der getätigten Vereinzelungstakte
      TrolleyID_ausgefahren : DInt                      // TrolleyID des ausgefahrenen Trolleys
      Res200 : Array[1..38] of Int
      Reservierungs_DL : Struct                         // AB DW200: Liste der resevierter Trolleys
        Datenlistenkopf : Struct
          KOPF : Word := WORD#16#DA02                   // Datenliste-Kennnung (DA) / Datensatzlänge in Word (1 - 128)
          LAENGE : Int := 24                            // Länge der Datenliste (maximale Anzahl der Datensätze)
          STAMMDATEN : Int := 2                         // Stammdatenlänge in Word (1 - 9)
          INDDB : Int                                   // Indizierter DB (nur bei Stammdaten = 1 erlaubt !!!)
          LAENGEINDDB : Int                             // Länge des indizierten DB in Word (nur bei Stammdaten = 1 erlaubt !!!)
          INDDATEN_WANDEL_FC : Int                      // FC zum Wandeln der indizierte Daten (nur bei Stammdaten = 1 erlaubt !!!)
          LETZTERZUGRIFF : Int                          // Speicherung des letzten Zugriffs
          Belegt14 : Int                                // reserviert von Sort-Datenliste
          AnzahlEintraege : Int                         // Anzahl der eingetragenen Datensätze (nicht bei ind.Zugriff!)
          Reserve18 : Int                               // Reserve
        Res_Trolley : Array[1..24] of Struct            // Reservierter Trolley für Leerpuffer
          Trolley_ID : DInt                             // Trolley_ID
        Endekennung : Word := WORD#16#DAEE              // Datensort-Ende-Kennung (DBEE)
      Res350 : Array[1..16] of Int
      Anzahl_LeerTrolleys : Int                         // AB DW350: Liste der Trolleys im Leerpuffer
      Res500 : Array[1..74] of Int
  None:
    Reset : Bool := 1
  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
  Constant:

--- NW 1: 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


--- NW 2: Anzeige OP ---
      L      252                                             // Bereichsstop aktiv
      AN     Dyn.Sk.Bereich_ok                               // Also: Bereichsstop / Not-Aus
      JC     w010

      L      253
      AN     Dyn.Sk.Auto_akt                                 // Keine Betriebsart
      AN     Dyn.Sk.Hand_akt
      JC     w010

      L      255                                             // Handbetrieb aktiv
      A      Dyn.Sk.Hand_akt
      JC     w010

      L      Dyn.Sk.Akt_Schritt                              // Aktiver Schritt
      T      Dyn.Sk.OP_Schritt

      JU     OP_Ok

w010: T      Dyn.Sk.OP_Schritt

OP_Ok: NOP 0


--- NW 3: 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

      A      Dyn.Sk.Reset
      O      Dyn.Sk.Reset_Akt
      =      Dyn.Status.Reset_aktiv

      SET
      R      Inks_Ok

// Antrieb zusätlich starten:
      A      ErrQuit                                         // Überwachungszeit abgelaufen quittieren
      S      Antrieb_plus_vor                                // Kreisel-Antrieb plus starten


--- NW 4: HMI-Zeug ---
// Von HMI:
      A      Dyn.HMI.Schleuse_resetten_Leerpuffer
      R      Dyn.HMI.Schleuse_resetten_Leerpuffer
      S      Dyn.Sk.Reset                                    // SK zurücksetzen

      A      Dyn.HMI.LeerPuffer_initialisieren
      S      Dyn.Status.Leerpuffer_initialisieren
      R      Dyn.HMI.LeerPuffer_initialisieren

      A      Dyn.HMI.Einlagern_gesperrt                      // Wird unten direkt verarbeitet

      A      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"


--- NW 5: Schrittkette OUT zurücksetzen ---
      AN     Dyn.Sk.Reset                                    // SK zurücksetzen
      JC     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

      BEU

en04: NOP 0


--- NW 6: Störungen nach Außen übergeben ---
      L      0
      T      "MW200"

      A      Dyn.Error.Leerpuffer_DL                         // Leerpuffer-Datenliste fehlerhaft
      =      "M200.0"
      A      Dyn.Error.Undef_Leerpuffer                      // undefinierter Leerpuffer
      =      "M200.1"
      A      Dyn.Error.Err_Trolley_nicht_in_Schleuse         // Trolley fährt nicht in Schleuse
      AN     Dyn.Status.Leerpuffer_initialisieren
      =      "M200.2"
      A      Dyn.Sk.Err_Uebzeit
      AN     Dyn.Error.Err_Trolley_nicht_in_Schleuse         // Trolley fährt nicht in Schleuse
      AN     Dyn.Error.Err_Trolley_raus                      // Trolley fährt nicht aus
      =      Dyn.Error.Err_Uebzeit                           // Überwachungzeit ist abgelaufen
      =      "M200.3"
      NEG
      R      Dyn.Sk.Err_Uebzeit_AnzOk
      A      Dyn.Sk.Err_Schritt
      =      Dyn.Error.Err_Schritt                           // Schritt-Nummer ist nicht definiert
      =      "M200.4"
      A      Dyn.Error.Err_Stau_Einfahrt                     // Stau am Leerpuffer-Eingang
      =      "M200.5"
      A      Dyn.Error.Err_BLKMov                            // Error bei Block kopieren
      =      "M200.6"
      A      Dyn.Error.Err_Trolley_raus                      // Trolley fährt nicht aus
      =      "M200.7"
      A      Dyn.Error.Err_Leerpuffer_nicht_leer
      AN     Dyn.Status.Leerpuffer_initialisieren
      =      "M201.0"
      CLR
      =      "M201.1"
      =      "M201.2"
      =      "M201.3"
      =      "M201.4"
      A      Dyn.Error.Err_Raus_Sensor
      =      "M201.5"
      CLR
      =      "M201.6"
      A      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
      AW
      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

      A      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!
      A      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

      AN     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


--- NW 7: 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
      JC     en06                                            // Ja !

      T      "MW200"                                         // Search-Daten

CALL FC "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")

      JBI    G_Ok

      A      "M199.0"
      JCN    w060

      SET
      =      Dyn.Error.Leerpuffer_DL                         // Leerpufferdatenbank fehlerhaft

      L      16#A071
      T      Dyn.Stop_Ursache

      BEU

w060: SET
      S      Dyn.Error.Undef_Leerpuffer                      // undefinierter Leerpuffer

      L      16#0072
      T      Dyn.Stop_Ursache

      BEU

// 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 SYS "BLKMOV" (SRCBLK:=Quelle, RET_VAL:=Dyn.Rueckmld.RET_VAL_BLKMOV_Leerpuffer, DSTBLK:=Puffer)   // Datenliste-Daten speichern | #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
      BEC

      L      Puffer.Puffer_Typ                               // Puffertyp = 1277 (Leerpuffer)
      L      1277                                            // Dieser Aufruf-FB ?
      ==I                                                    // Ja !
      JC     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

      BEU

// Defaultwerte übergeben:
w061: NOP 0

      BEU

en06: NOP 0


--- NW 8: Störungen quittieren ---
      A      ErrQuit                                         // Überwachungszeit abgelaufen quittieren
      R      Dyn.Sk.Err_Uebzeit


--- NW 9: Einfahrenden Trolley in Puffer eintragen ---
      L      Dyn.TrolleyID_Einfahrt
      T      "MD220"
      L      DINT#0
      ==I
      JC     NoNewT

      SET
      S      Neu_Trolley_in_Puffer

// Neue Position an Gesamt-Trolley-DL übergeben:
CALL FC "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 FC "DatenOut" (SSDB:=Puffer.Puffer_Dyn_DB, SSDW:=SSDW, PARA:=16#E100, SEARCHDATEN:=P#M220.0, RE_VAL:=Dyn.Rueckmld.RET_VAL_DL_Res, OUTDATEN:=P#M220.0, Position:="MW196")   // Eintrag löschen | Nicht relevant

      L      DINT#0
      T      Dyn.TrolleyID_Einfahrt

NoNewT: NOP 0


--- NW 10: Error: Stau Bereich-Eingang ---
// Sensor bei Bereichs-Einfahrt bleibt belegt?:
      AN     B_LeerpufferEinfahrt                            // Sensor Trolley fährt in Bereich (kein Stau !)
      R      Dyn.Error.Err_Stau_Einfahrt                     // Stau bei Einfahrt
      JC     X090                                            // StauZeit neu aufziehen

      AN     "1s-Impuls"
      O      Dyn.Error.Err_Stau_Einfahrt                     // Zeit bereits abgelaufen
      JC     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
      JCN    Xn09

X090: L      0                                               // Zeiten löschen
      T      Dyn.Stau_Zeit                                   // Sensor B_VorSep ist belegt [1s]

Xn09: NOP 0


--- NW 11: 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
      JC     X100                                            // FreiZeit neu aufziehen

      AN     "1s-Impuls"
      O
      A      Puffer.Parameter_allg.Antrieb_Plus_vorhanden
      AN     Antrieb_plus_aktiv
      O      Dyn.Status.MindestZeit_ok                       // Zeit bereits abgelaufen
      JC     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
      JCN    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: AN     "Schleuse_geöffnet"                             // Schleuse hat geöffnet
      JC     X10E

      L      Ausfahr_Inks
      L      Puffer.Puffer_Position_Inks
      >I                                                     // Rest-Inks-Wert ist größer!
      JC     X10E

      L      Puffer.Puffer_Position_Inks
      T      Ausfahr_Inks

X10E: NOP 0


--- NW 12: Keine neue Trolley-Einfahrt ? ---
// Neu-Trolley ist im Puffer:
      A      Neu_Trolley_in_Puffer                           // s.o.
      O      B_LeerpufferEinfahrt                            // Stauklappe
      JC     X110

      AN     "1s-Impuls"
      O      Dyn.Status.Kein_neuer_Trolley_kommt
      JC     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 !
      JCN    Xn11

      T      Dyn.Leer_Zeit                                   // Zeit für LeerCheck einfrieren

      SET
      S      Dyn.Status.Kein_neuer_Trolley_kommt

      JU     Xn11

X110: L      0                                               // Zeiten löschen
      T      Dyn.Leer_Zeit

      SET
      R      Dyn.Status.Kein_neuer_Trolley_kommt

Xn11: NOP 0


--- NW 13: Reservierungs-Check ---
      L      Dyn.Reservierungs_DL.Datenlistenkopf.AnzahlEintraege
      L      0
      ==I
      O      "MB3305"                                        // Trolley wird gerade vereinzelt
      O      "BG3306"                                        // Synchron-Sensor aktiv
      JC     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
      JC     NoResCheck

      L      Dyn.Reservierungs_DL.Res_Trolley[1].Trolley_ID
      T      "MD220"

      JU     ResOut

NoResCheck: NOP 0


--- NW 14: Leer-Check aktiv ---
// Falls Inilauf aktiv:
      A      Dyn.Status.Leerpuffer_initialisieren
      AN     Dyn.Status.Leer_Check_aktiv
      S      Dyn.Status.Leer_Check_aktiv
      JCN    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:
      A      Dyn.Status.Leerpuffer_initialisieren
      A      B_InSchleuse
      A(
      L      Dyn.Anzahl_LeerTrolleys
      L      0
      ==I
      )
      AN     Dyn.Status.Einen_LeerTrolley_ausfahren
      S      Dyn.Status.Einen_LeerTrolley_ausfahren          // Trolley zwingend ausfahren

// Abbruch, da Trolley ist doch noch in Schleuse gefahren:
      A      Dyn.Status.Leerpuffer_initialisieren
      A      B_InSchleuse
      A(
      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

      AN     Dyn.Status.Leer_Check_aktiv
      JC     Xn12

// Trolley während Check erkannt:
      AN     Dyn.Status.Kein_neuer_Trolley_kommt             // nichts mehr eingefahren,
      JC     Xn12

// Aber:
      A      "Schleuse_geöffnet"                             // aber Schleuse noch geöffnet
      O      B_InSchleuse                                    // aber Trolley noch in Schleuse
      JCN    Fertig                                          // Negierter Sprung

      L      0                                               // Zeit neu aufziehen
      T      Dyn.Leer_Zeit

      SET
      R      Dyn.Status.Kein_neuer_Trolley_kommt

      JU     Xn12

Fertig: SET
      R      Dyn.Status.Leer_Check_aktiv
      R      Dyn.Status.Trolley_nicht_in_Schleuse

      A      Dyn.Status.Leerpuffer_initialisieren
      R      Dyn.Status.Leerpuffer_initialisieren
      JCN    Reset                                           // Negierter Sprung

      L      0
      T      Dyn.Anzahl_LeerTrolleys                         // Minimum übergeben

      JU     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 FC "DatenReset" (SSDB:=Puffer.Puffer_Dyn_DB, SSDW:=SSDW, RE_VAL:="MB198")

      JU     Reset

Xn12: NOP 0


--- NW 15: Reset aktiv ---
      JU     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


--- NW 16: 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
      AN     Dyn.Error.Err_Stau_Einfahrt
      AN     Dyn.Error.Err_Leerpuffer_nicht_leer
      AN     Dyn.Error.Err_Trolley_nicht_in_Schleuse
      AN     Dyn.Status.Leerpuffer_initialisieren
      AN     Dyn.Status.Leer_Check_aktiv
      AN     Dyn.Status.Reset_aktiv
      =      Dyn.Status."Puffer_hat Platz"

      CAC
      L      0                                               // Trolley im Puffer ?
      ==I                                                    // Nein!
      A      Dyn.Status."Puffer_hat Platz"
      A      Dyn.Status.Kein_neuer_Trolley_kommt
      AN     B_InSchleuse
      =      Dyn.Status.Puffer_leer
      R      Status2.Einlagern_ist_aktiv
      R      Status2.Auslagern_ist_aktiv

// Einlagern ist aktiv:
      L      GesamtAnzahl
      L      0
      >I
      A      Dyn.Status."Puffer_hat Platz"
      AN     Status2.Auslagern_ist_aktiv
      S      Status2.Einlagern_ist_aktiv

      A      Status2.Auslagern_ist_aktiv                     // Wegen FIFO
      O      Dyn.HMI.Einlagern_gesperrt
      R      Status2.Einlagern_ist_aktiv


--- NW 17: Starten aus Leerpuffer aufgrund von Ausfahrsituation ok ---
      L      Puffer.Puffer_Position_Inks
      L      0                                               // Undefiniert ?
      ==I                                                    // Ja!
      JC     X14E

      L      Ausfahr_Inks                                    // Trolles auf Förderer vorbei?
      L      0                                               // Undefiniert ?
      ==I                                                    // Ja!
      JC     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


--- NW 18: DLPuffer_leer: Ein-/Austrag ---
      AN     Dyn.Status.Puffer_leer                          // Kann mit neuen Leertrolleys bestückt werden!
      O      Dyn.HMI.Einlagern_gesperrt
      O      Dyn.Status.Leerpuffer_initialisieren
      JC     Austrag_Leerliste

// Eintrag aus Leerliste:
      L      LeerPuffer_Nr
      T      "MW220"                                         // Puffer, der leer ist

CALL FC "DatenIn" (SSDB:=500, SSDW:=0, INDATEN:=P#M220.0, RE_VAL:="MB219")   // Anforderung in Datenliste eintragen

      AN     "M219.6"                                        // Daten wurden überschrieben
      AN     "M219.7"                                        // Eintrag ist richtig erfolgt
      JC     NoChange_Leerliste

      SET
      S      Status2.Eintrag_DL_Leerliste_erfolgt

      JU     NoChange_Leerliste

Austrag_Leerliste: NOP 0
// Austrag aus Leerliste:
      L      LeerPuffer_Nr
      T      "MW220"                                         // Puffer, der leer ist

CALL FC "DatenOut" (SSDB:=500, SSDW:=0, PARA:=WORD#16#E100, SEARCHDATEN:=P#M220.0, RE_VAL:="MB219", OUTDATEN:=P#M230.0, Position:="MW196")   // Anforderung aus Datenliste löschen

      SET
      R      Status2.Eintrag_DL_Leerliste_erfolgt

NoChange_Leerliste: NOP 0


--- NW 19: DLPuffer_einfahren: Ein-/Austrag ---
      AN     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
      JC     Austrag_Reinliste

// Eintrag in Reinliste:
      A(
      L      Dyn.Reservierungs_DL.Datenlistenkopf.AnzahlEintraege
      L      0                                               // Reservierung schon erfolgt ?
      >I                                                     // Ja!
      O      Status2.Einlagern_ist_aktiv
      )
      JCN    NoChange_Reinliste                              // Negierter Sprung

      L      LeerPuffer_Nr                                   // angefahrener Puffer
      T      "MW220"

CALL FC "DatenIn" (SSDB:=501, SSDW:=0, INDATEN:=P#M220.0, RE_VAL:="MB219")   // Anforderung in Datenliste eintragen

      AN     "M219.6"                                        // Daten wurden überschrieben
      AN     "M219.7"                                        // Eintrag ist richtig erfolgt
      JC     NoChange_Reinliste

      SET
      S      Status2.Eintrag_DL_Reinliste_erfolgt

      JU     NoChange_Reinliste

Austrag_Reinliste: NOP 0
// Austrag aus Reinliste:
      L      LeerPuffer_Nr
      T      "MW220"

CALL FC "DatenOut" (SSDB:=501, SSDW:=0, PARA:=WORD#16#E100, SEARCHDATEN:=P#M220.0, RE_VAL:="MB219", OUTDATEN:=P#M230.0, Position:="MW196")   // Anforderung aus Datenliste löschen

      SET
      R      Status2.Eintrag_DL_Reinliste_erfolgt

NoChange_Reinliste: NOP 0


--- NW 20: DLPuffer_ausfahren: Ein-/Austrag ---
      A      Dyn.Status.Puffer_leer                          // Kann mit neuen Leertrolleys bestückt werden!
      AN     Dyn.Error.Err_Leerpuffer_nicht_leer             // Damit Trolley ausgefahren werden kann!
      O      Dyn.HMI.AusLagern_gesperrt
      R      Dyn.Status.Einen_LeerTrolley_ausfahren
      JC     Austrag_Abrufliste

// Eintrag aus Abrufliste:
      A      B_InSchleuse                                    // Sobald Trolley in Ausfahrschleuse
      JCN    NoChange_Abrufliste                             // Negierter Sprung

      L      LeerPuffer_Nr                                   // angefahrener Puffer
      T      "MW220"

CALL FC "DatenIn" (SSDB:=502, SSDW:=0, INDATEN:=P#M220.0, RE_VAL:="MB219")   // Anforderung in Datenliste eintragen

      AN     "M219.6"                                        // Daten wurden überschrieben
      AN     "M219.7"                                        // Eintrag ist richtig erfolgt
      JC     NoChange_Abrufliste

      SET
      S      Status2.Eintrag_Abrufliste_erfolgt

      JU     NoChange_Abrufliste

Austrag_Abrufliste: NOP 0
// Austrag aus Abrufliste:
Austrag: L      LeerPuffer_Nr                                // angefahrener Puffer
      T      "MW220"

CALL FC "DatenOut" (SSDB:=502, SSDW:=0, PARA:=WORD#16#E100, SEARCHDATEN:=P#M220.0, RE_VAL:="MB219", OUTDATEN:=P#M230.0, Position:="MW196")   // Anforderung aus Datenliste löschen

      SET
      R      Status2.Eintrag_Abrufliste_erfolgt

NoChange_Abrufliste: NOP 0


--- NW 21: Schrittkette anhalten ---
      A      Dyn.Sk.Auto_akt                                 // Automatik ist aktiv
      A      Dyn.Sk.Bereich_ok
      JU     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

      BEU

en08_Mig: NOP 0


--- NW 22: Sprungverteiler  ---
OUT_Sk: L      Dyn.Sk.Neu_Schritt                            // Schritt, der im nächsten Zyklus aktiv werden soll
      L      -1                                              // angegeben ?
      ==I                                                    // Nein !
      JC     NEU

      CAC                                                    // 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
      JL     Ende
      JU     s000                                            // Schritt 0
      JU     s001                                            // Schritt 1
      JU     s002                                            // Schritt 2
      JU     s003                                            // Schritt 3
      JU     s004                                            // Schritt 4
      JU     s005                                            // Schritt 5
      JU     s006                                            // Schritt 6
      JU     s007                                            // Schritt 7
      JU     s008                                            // Schritt 8
      JU     s009                                            // Schritt 9
      JU     s010                                            // Schritt 10
      JU     s011                                            // Schritt 11
      JU     s012                                            // Schritt 12
      JU     s013                                            // Schritt 13
      JU     s014                                            // Schritt 14
      JU     s015                                            // Schritt 15
      JU     s016                                            // Schritt 16
      JU     s017                                            // Schritt 17
      JU     s018                                            // Schritt 18
      JU     s019                                            // Schritt 19
      JU     s020                                            // Schritt 20
      JU     s021                                            // Schritt 21
      JU     s022                                            // Schritt 22
      JU     s023                                            // Schritt 23
      JU     s024                                            // Schritt 24
      JU     s025                                            // Schritt 25
      JU     s026                                            // Schritt 26
      JU     s027                                            // Schritt 27
      JU     s028                                            // Schritt 28
      JU     s029                                            // Schritt 29
      JU     s030                                            // Schritt 30
Ende: S      Dyn.Sk.Err_Schritt                              // Undefinierter Schritt

      L      16#A231
      T      Dyn.Stop_Ursache

      BEU

Neu_Mig: A      Dyn.Sk.Err_Uebzeit
      JCN    Sk

      L      16#A232
      T      Dyn.Stop_Ursache

      BEU

Sk:   T      Dyn.Sk.Akt_Schritt

      L      0                                               // Zeitwerte löschen
      T      Dyn.Sk.Terr_Zelle
      T      Dyn.Sk.Tok_Zelle

      JU     NEU

// Nicht programmierte Schritte:
// s000: SPA   Ende
// s001: SPA   Ende
// s002: SPA   Ende
s003: JU     Ende
s004: JU     Ende
// s005: SPA   Ende
// s006: SPA   Ende
// s007: SPA   Ende
s008: JU     Ende
s009: JU     Ende
s010: JU     Ende
s011: JU     Ende
s012: JU     Ende
s013: JU     Ende
s014: JU     Ende
s015: JU     Ende
s016: JU     Ende
s017: JU     Ende
s018: JU     Ende
s019: JU     Ende
// s020: SPA   Ende
// s021: SPA   Ende
s022: JU     Ende
s023: JU     Ende
s024: JU     Ende
s025: JU     Ende
s026: JU     Ende
s027: JU     Ende
s028: JU     Ende
s029: JU     Ende
s030: JU     Ende


--- NW 23: Schritt X: Reserve            ---
      SET                                                    // Weiterschaltbedingung
      =      Weiter

// Schrittaktionen:
      SET

      L      16#B001
      T      Dyn.Stop_Ursache

      A      Dyn.Sk.Reset_Akt                                // Reset ist aktiv
      L      20                                              // Weiter mit Schritt 20
      JC     Neu_Mig                                         // Bei diesem Schritt weiter

      A      Weiter                                          // Weiterschaltbedingung ist erfüllt
      R      Dyn.Sk.Err_Uebzeit                              // Sofort weiter !
      L      0                                               // Angabe der Wartezeit (*10ms)
      JC     Plus                                            // Nächsten Schritt starten

      L      1                                               // Weiter mit Schritt 1
      JC     Neu_Mig                                         // Bei diesem Schritt weiter

      T      Dyn.Sk.Neu_Schritt                              // Schritt, der im nächsten Zyklus aktiv werden soll

      SET
      A      Dyn.Sk.Auto_akt                                 // Automatik ist aktiv
      A      Dyn.Sk.Bereich_ok
      =      Ueb_akt                                         // Überwachungszeit aktivieren
      L      50                                              // Angabe der Überwachungszeit (*1s)
      JU     tueb                                            // Überwachungszeit

      BEU


--- NW 24: Schritt 0: Warten auf Trolley ---
s000: SET                                                    // Weiterschaltbedingung
      A      B_InSchleuse                                    // Trolley im Schleuse erkannt
      A      Dyn.Sk.Auto_akt                                 // Automatik ist aktiv
      A      Dyn.Sk.Bereich_ok
      =      Weiter

// Schrittaktionen:
      SET
      R      Dyn.Error.Err_Leerpuffer_nicht_leer

      A      Dyn.Sk.Reset_Akt                                // Reset ist aktiv
      L      20                                              // Weiter mit Schritt 20
      JC     Neu_Mig                                         // Bei diesem Schritt weiter

      A      Weiter                                          // Weiterschaltbedingung ist erfüllt
      R      Dyn.Sk.Err_Uebzeit                              // Sofort weiter !
      L      100                                             // Angabe der Wartezeit (*10ms)
      JC     Plus                                            // Nächsten Schritt starten

      L      16#B001
      T      Dyn.Stop_Ursache

// Trolley soll gestartet werden:
      A      Dyn.Status.Einen_LeerTrolley_ausfahren          // Von FB5429/2
      A(
      A      Dyn.Sk.Err_Uebzeit
      AN     B_InSchleuse                                    // Trolley im Schleuse erkannt
      O      Dyn.Status.Leerpuffer_initialisieren            // Damit Einfahren blockiert wird
      )
      R      Dyn.Status.Einen_LeerTrolley_ausfahren          // Von FB5429/2
      JCN    ÜbStart

      L      "DLP_Auslagern".Auslagern.Auslager_Puffer
      L      LeerPuffer_Nr
      <>I
      JC     ENDE_Mig

      L      0
      T      "DLP_Auslagern".Auslagern.Auslager_Puffer

      JU     Austrag                                         // Puffer aus Ausfahr-Liste löschen

// Überwachungszeit starten:
ÜbStart: AN     B_InSchleuse                                 // Trolley im Schleuse erkannt
      A      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 !
      A      Dyn.Sk.Err_Uebzeit
      AN     B_InSchleuse                                    // Trolley im Schleuse erkannt
      AN     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
      A      Dyn.Status.Einen_LeerTrolley_ausfahren          // Bei Ausfahrwunsch -> Kurze Zeit
      JC     tueb                                            // Überwachungszeit

      L      Puffer."Übzeit_in_Schleuse"

      JU     tueb                                            // Überwachungszeit


--- NW 25: Schritt 1: Trolley ist in Schleuse / Warten auf  Bit "Einen Trolley ausfahren" ---
s001: NOP 0

// Schrittaktionen:
      AN     B_InSchleuse                                    // Trolley im Schleuse erkannt
      L      0                                               // Weiter mit Schritt 0
      JC     Neu_Mig                                         // Bei diesem Schritt weiter

      SET
      R      Dyn.Error.Err_Trolley_nicht_in_Schleuse

// Puffer leer ?:
      A      Dyn.Status.Puffer_leer
      AN     Dyn.Status.Puffer_nicht_leer
      S      Dyn.Status.Puffer_nicht_leer
      S      Dyn.Status.Leerpuffer_initialisieren            // Damit Einfahren blockiert wird

// Spezial-Betriebsarten:
      A      Dyn.Status.Einen_LeerTrolley_ausfahren
      L      2                                               // Weiter mit Schritt 2
      JC     Neu_Mig                                         // Bei diesem Schritt weiter

      L      16#B011
      T      Dyn.Stop_Ursache

      BEU


--- NW 26: Schritt 2: Ausfahren ok ? ---
s002: NOP 0

// Schrittaktionen:
      AN     B_InSchleuse                                    // Trolley im Schleuse erkannt
      L      0                                               // Weiter mit Schritt 0
      JC     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

      AN     Dyn.Sk.Auto_akt                                 // Automatik ist aktiv
      ON     Dyn.Sk.Bereich_ok                               // Bereich ist gestört
      JC     X002

// Trolley starten erlaubt ?:
      L      16#B021
      T      Dyn.Stop_Ursache

      AN     Start_Ok                                        // Starten ist erlaubt
      JC     X002

// Stau im Bereich +1:
      L      16#B022
      T      Dyn.Stop_Ursache

      A      B_Stau_raus_Out
      JC     X002                                            // Stau

// B_Aus_Schleuse aktiv:
      L      16#B023
      T      Dyn.Stop_Ursache

      A      Puffer.Parameter_allg.B_AusSep_vorhanden
      A      B_AusSchleuse
      =      Dyn.Error.Err_Raus_Sensor                       // Raus-Sensor wird nicht erreicht (oder dauernd aktiv)!
      JC     X002

// Inks ok ?:
      L      16#B024
      T      Dyn.Stop_Ursache

      SET
      S      Antrieb_plus_vor

      AN     Inks_Ok                                         // Starten ist erlaubt
      JC     X002

// Antriebe aktivieren / aktiv ?:
      A      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

      AN     Antrieb_plus_aktiv                              // Kreisel-Antrieb plus aktiv
      A      Puffer.Parameter_allg.Antrieb_Plus_vorhanden    // Schleuse an weiterem Antrieb (Weiche)
      BEC

      L      5                                               // Nur 1 langes Signal!
      JU     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

      BEU


--- NW 27: Schritt 5: Trolley fährt aus/ausgefahren ?     ---
s005: SET                                                    // Weiterschaltbedingung
      AN     B_InSchleuse                                    // Sensor Trolley ist in Schleuse
      A      "Schleuse_geöffnet"
      A      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:
      A(
      O      B_AusSchleuse                                   // Sensor Trolley aus Schleuse gefahren
      ON     Puffer.Parameter_allg.B_AusSep_vorhanden
      )
      AN     B_InSchleuse                                    // Sensor Trolley ist in Schleuse
      R      Dyn.Error.Err_Trolley_raus                      // Trolley fährt nicht aus
      L      0
      JC     Plus                                            // Nächsten Schritt starten

      A      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!
      JC     Plus                                            // Nächsten Schritt starten

// Trolley fährt nicht raus!:
      A      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
      JC     Plus                                            // Nächsten Schritt starten

      A      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

      AN     B_AusSchleuse                                   // Sensor Trolley aus Schleuse gefahren
      JC     x052

      L      16#B052
      T      Dyn.Stop_Ursache

x052: A      Antrieb_plus_aktiv
      =      Ueb_akt                                         // Überwachungszeit aktivieren
      L      Puffer."Übzeit_aus_Schleuse"                    // Angabe der Überwachungszeit (*1s)
      JU     tueb                                            // Überwachungszeit


--- NW 28: Schritt 6: Schleuse Mindestzeit geöffnet ?       ---
s006: SET                                                    // Weiterschaltbedingung
      A      Dyn.Status.MindestZeit_ok
      O
      A      Puffer.Parameter_allg.B_AusSep_vorhanden
      A      B_AusSchleuse                                   // Sensor Trolley aus Schleuse gefahren
      =      Weiter

// Schrittaktionen:
      A      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"

      A      B_InSchleuse                                    // Trolley wieder erkannt
      L      5                                               // Weiter mit Schritt 5
      JC     Neu_Mig                                         // Bei diesem Schritt weiter

      A      Weiter
      L      0
      JC     Plus                                            // Nächsten Schritt starten

      L      16#B061
      T      Dyn.Stop_Ursache

      BEU

--- NW 29: 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!
      JC     ENDE_Mig

      T      Dyn.Anzahl_LeerTrolleys                         // Minimum übergeben

      JU     ENDE_Mig


--- NW 30: Schritt 20: Schleuse resetten ---
s020: SET                                                    // Weiterschaltbedingung
      =      Weiter                                          // Weiterschaltbedingung ist erfüllt

// Schrittaktionen:
      A      "Schleuse_geöffnet"
      R      Start_Ok                                        // Damit kein weiterer Puffer ausfährt

      L      16#B201
      T      Dyn.Stop_Ursache

      A      Weiter                                          // Weiterschaltbedingung ist erfüllt
      L      300                                             // Angabe der Wartezeit (*10ms)
      JC     Plus                                            // Nächsten Schritt starten

      SET
      =      Ueb_akt                                         // Überwachungszeit aktivieren
      L      30                                              // Angabe der Überwachungszeit (*100ms)
      JU     tueb                                            // Überwachungszeit


--- NW 31: 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

      JU     ENDE_Mig                                        // Neubeginn


--- NW 32: 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

      BEU


--- NW 33: Nächsten Schritt aktivieren ---
Plus: T      Dyn.Sk.T_ok                                     // Wartezeit übergeben

      A      Dyn.Sk.Err_Uebzeit                              // Störung noch nicht quittiert
      BEC

      L      0                                               // keine Wartezeit ?
      ==I                                                    // Ja ! -> sofort weiter
      JC     w220

      AN     Warte_neu                                       // Wartezeit neutriggern
      JC     W220_Mig

      L      0
      T      Dyn.Sk.Tok_Zelle                                // Wartezeit

W220_Mig: A      Warte_stop                                  // Wartezeit stoppen
      BEC

      L      Dyn.Sk.Tok_Zelle
      L      "MW4"                                           // Wartezeit +10ms
      +I
      T      Dyn.Sk.Tok_Zelle                                // Wartezeit
      L      Dyn.Sk.T_ok                                     // abgelaufen ?
      <I                                                     // Nein !
      BEC

w220: L      Dyn.Sk.Akt_Schritt
      +      1                                               // Schritt +1
      T      Dyn.Sk.Akt_Schritt

      L      0                                               // Zeitwerte löschen
      T      Dyn.Sk.Terr_Zelle
      T      Dyn.Sk.Tok_Zelle

      BEU


--- NW 34: Überwachungszeit kontrollieren ---
tueb: A      Ueb_akt
      =      Dyn.Sk.Ueb_akt                                  // Für Statuskontrolle

      T      Dyn.Sk.T_Err                                    // Für Statuskontrolle
      L      Dyn.Sk.Terr_Zelle                               // Maximalzeit
      >I                                                     // abgelaufen ?
      AN     Dyn.Sk.Err_Uebzeit
      JC     en24                                            // Nein !

      A      Ueb_akt                                         // Überwachungszeit aktivieren
      S      Dyn.Sk.Err_Uebzeit

      L      0                                               // Zeitwert löschen
      T      Dyn.Sk.Terr_Zelle

      BEU

en24: NOP 0

--- NW 35: Überwachungszeit +1 ---
      AN     Dyn.Sk.Ueb_akt                                  // Schrittaktion ist aktiv
      ON     "1s-Impuls"
      BEC

      L      Dyn.Sk.Terr_Zelle
      +      1                                               // Üb.zeit +1s
      T      Dyn.Sk.Terr_Zelle

      BEU


--- NW 36: Ende ---
      BE

