=== FB 1279: MHMOmniWeiche  [STL] ===
INTERFACE:
  Input:
    Weichen_Nr : Int                                    // Aufruf für Weiche
    ErrQuit : Bool                                      // Ablaufstörung quittieren
    Fahren_Ok : Bool                                    // Fahren Ok
    B_Ziel_gerade : Bool                                // Ziel-Sensor gerade
    B_Ziel_abzweig : Bool                               // Ziel-Sensor abzweig
    Antrieb_Weiche_aktiv : Bool                         // Weichen-Antrieb aktiv
    Antrieb_Gerade_aktiv : Bool                         // Gerade-Antrieb aktiv
    Antrieb_Abzweig_aktiv : Bool                        // Abzweig-Antrieb aktiv
    Weiche_ist_AST : Bool                               // Weiche ist auf Arbeitsstellung
  Output:
    Y_Weiche_gerade : Bool                              // Weiche auf Gerade schalten
    Y_Weiche_abzweig : Bool                             // Weiche auf Abzweig schalten
    Error : Word                                        // Störungen übergeben
  InOut:
    Antrieb_Weiche_vor : Bool                           // Weichenantrieb einschalten
    Antrieb_Weiche_stop : Bool                          // Weichenantrieb stoppen
    Antrieb_Weiche_gerade_vor : Bool                    // Weichenantrieb gerade einschalten
    Antrieb_Weiche_gerade_stop : Bool                   // Weichenantrieb gerade stoppen
    Antrieb_Weiche_abzweig_vor : Bool                   // Weichenantrieb abzweig einschalten
    Antrieb_Weiche_abzweig_stop : Bool                  // Weichenantrieb abzweig stoppen
    hStOk : Bool                                        // Anzeige Start n. Störung aktivieren
  Static:
    SAVE : Struct
      Schleusen_DB : Int                                // Schleuse-1-DB
      Schleuse-1_DW : Int                               // Schleuse-1-DW
      Res : Array[1..3] of Int                          // Reserve
    Para : Struct                                       // Parameter
      Weichen_DL_DB : Int                               // Einsprung Weichen-Datenliste-DB
      Weichen_DL_DW : Int                               // Einsprung Weichen-Datenliste-DW
      Schleusen_DL_DB : Int                             // Einsprung Schleuse-Datenliste-DB
      Schleusen_DL_DW : Int                             // Einsprung Schleuse-Datenliste-DW
      Res1 : Array[1..1] of Int                         // Reserve
    Weiche : "UDLOmniWeiche_2fach"                      // Fahrbereichs Daten
    Dyn : Struct                                        // Dynamische Daten fürs Einfahren
      Status : Struct                                   // Status
        Weiche_frei : Bool                              // Rückmeldung: Weiche ist wieder frei
        Kein_StartOk : Bool                             // Input StartOk <>1
        Weiche_abzweigen : Bool                         // Weiche auf Abzweig schalten
        Weiche_geradeaus : Bool                         // Weiche auf Gerade schalten
        MindestZeit_ok : Bool                           // Mindestzeit für Weichendurchfahrt erreicht?
        Ziel_erreicht : Bool                            // Ziel erreicht
        Reservierung _noch aktiv : Bool                 // Reservierung noch aktiv!
        Weiche_aktiv : Bool                             // Weiche ist aktiv
        Auto_akt : Bool
        Hand_akt : Bool
        Bereich_ok : Bool
        MindestZeit_nachtriggern : Bool                 // Mindestzeit nachtriggern
        Res14 : Bool
        Res15 : Bool
        Error_aktiv : Bool                              // Störung vorhanden
        Reset_aktiv : Bool := TRUE                      // Reset aktiv
      TrolleyID : DInt                                  // Trolley-Nr (Eintrag Schleuse, Austrag Weiche)
      Weichen_Ziel : Word                               // Weichen-Ziel (Eintrag Schleuse, Austrag Weiche)
      Schleuse -1 : Int                                 // Schleuse, woher Ziel kam
      Zwischen_Ziel : Word                              // Zwischen-Ziel
      HMI : Struct
        TrolleyID_Weiche : DInt                         // Trolley-Nr im Weichenbereich (IN:PLC, OUT:PLC)
        WeichenZiel : DInt                              // Ziel im Weichenbereich (IN:PLC, OUT:PLC)
        Weiche_resetten : Bool                          // Weiche resetten (IN:HMI, Out:PLC)
      Rueckmld : Struct
        RET_VAL_BLKMOV_Weiche : Int                     // Rückmeldung nach BLKMOV-Aufruf
        RET_VAL_DL_Weichen : Byte                       // Rückmeldung nach DatenOut-Aufruf
        RET_VAL_DL_Schleusen : Byte                     // Rückmeldung nach DatenOut-Aufruf
      Error : "UErrOmniWeiche_2fach"
      FahrKontrolle : Struct
        Para_Mindestzeit : Int                          // BM erst nach dieser Zeit im Ziel
        Para_Überwachungszeit : Int                     // BM nach dieser Zeit in Weiche verklemmt
        Akt_Mindestzeitzeit : Int                       // BM erst nach dieser Zeit im Ziel
        Akt_Überwachungszeit : Int                      // BM nach dieser Zeit in Weiche verklemmt
      Leer_Zeit : Int                                   // Lager ist frei [1s]
      Schalttakte : DInt                                // Anzahl der getätigten Umschaltungen
      Frei200 : Array[1..44] of Int
  Temp:
    Quelle : Any                                        // Zeiger, wo Rein-Daten sind
    Ziel : Any                                          // Zeiger, FIFO-Stelle
    Parameter : Word                                    // Parameter
    AR1Zeiger : DWord                                   // Statt AR1 (ging nur bis DB-Länge <= 8191 Bytes)
    AR1Start : DInt                                     // Startwert mit Offset 0
    Bereich+1ID : Int
    Bereich+1_DB : Int
    Keine_Einfahrt : Bool                               // Keine Einfahrt angemeldet
    Err_Bereich+1 : Bool
    Abzweig_Ziel : Bool
    Gerade_Ziel : Bool
    Antriebe_ein : Bool
  Constant:

--- NW 1: Parameter-Übergabe ---
      L      Weichen_Nr                                      // Aufruf-Parameter (für Baustein beobachten)

      L      279                                             // Einsprung Weichen-DL
      T      Para.Weichen_DL_DB                              // vor Aufruf übergeben!
      L      0
      T      Para.Weichen_DL_DW

      L      274                                             // Einsprung Schleuse-DL
      T      Para.Schleusen_DL_DB                            // vor Aufruf übergeben!
      L      0
      T      Para.Schleusen_DL_DW


--- NW 2: Gesamt: Out-Bits zum Zurücksetzen ---
      L      Weichen_Nr

      SET
//       R     #Y_Weiche_gerade     //Wegen Reset
//       R     #Y_Weiche_abzweig    //Wegen Reset

      SET                                                    // Erst mal
      R      Dyn.Status.Weiche_frei
      S      Dyn.Status.Weiche_aktiv


--- NW 3: HMI-Zeug ---
// Von HMI:
      A      Dyn.HMI.Weiche_resetten
      R      Dyn.HMI.Weiche_resetten                         // von HMI
      S      Dyn.Status.Reset_aktiv
      JCN    HMI1

      L      0
      T      Dyn.Leer_Zeit                                   // da kein Sk
      T      Dyn.FahrKontrolle.Akt_Mindestzeitzeit
      T      Dyn.FahrKontrolle."Akt_Überwachungszeit"

      SET
      R      Dyn.Error."Übzeit_Gerade"
      R      Dyn.Error."Übzeit_Abzweig"

// An HMI:
HMI1: L      Dyn.TrolleyID
      T      Dyn.HMI.TrolleyID_Weiche

      L      Dyn.Weichen_Ziel
      T      Dyn.HMI.WeichenZiel


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

      A      Dyn.Error.Weichen_DL                            // Weichen-Datenliste fehlerhaft
      =      "M200.0"
      A      Dyn.Error.Undef_Weiche                          // undefinierte Weiche
      =      "M200.1"
      A      Dyn.Error.BLKMov                                // Fehler bei Block kopieren
      =      "M200.2"
      A      Dyn.Error."Undef_Bereich+1"
      =      "M200.3"
      A      Dyn.Error.Frei04
      =      "M200.4"
      A      Dyn.Error.Frei05
      =      "M200.5"
      A      Dyn.Error.Ziel_undefiniert
      =      "M200.6"
      A      Dyn.Error.Err_Schleusen_DL
      =      "M200.7"
      A      Dyn.Error."Err_Undef_Schleuse-1"
      =      "M201.0"
      A      Dyn.Error."Übzeit_Gerade"                       // BM bei Weiterfahrt in Weiche verklemmt (-> Antrieb stoppen)
      =      "M201.1"
      A      Dyn.Error."Übzeit_Abzweig"                      // BM bei Ausfahrt in Weiche verklemmt (-> Antrieb stoppen)
      =      "M201.2"
      A      Dyn.Error.Gerade_Sensor_aktiv
      =      "M201.3"
      A      Dyn.Error.Abzweig_Sensor_aktiv
      =      "M201.4"
      A      Dyn.Error.Gerade_Bereich_belegt
      =      "M201.5"
      A      Dyn.Error.Abzweig_Bereich_belegt
      =      "M201.6"
      A      Dyn.Status.Reset_aktiv
      =      Dyn.Error.Reset_aktiv
      =      "M201.7"

      L      "MW200"
      T      Error                                           // Schnittstelle nach Außen

// Störung vorhanden:
      L      0
      <>I                                                    // Ja !
      =      Dyn.Status.Error_aktiv

// Anzeige Start n. Störung aktivieren:
      A      Dyn.Error."Übzeit_Gerade"                       // BM bei Weiterfahrt in Weiche verklemmt (-> Antrieb stoppen)
      O      Dyn.Error."Übzeit_Abzweig"                      // BM bei Ausfahrt in Weiche verklemmt (-> Antrieb stoppen)
      S      hStOk


--- NW 5: Statische Weichen-Parameter holen ---
      L      Weiche.Weichen_Nr                               // Nummer der Weiche
      L      Weichen_Nr                                      // Aufruf-Parameter
      ==I                                                    // Identisch ?
      R      Dyn.Error.Weichen_DL                            // Weichendatenbank fehlerhaft
      R      Dyn.Error.Undef_Weiche                          // undefinierte Weiche
      JC     en06_Mig                                        // Ja !

      T      "MW200"                                         // Search-Daten

CALL FC "DatenOut" (SSDB:=Para.Weichen_DL_DB, SSDW:=Para.Weichen_DL_DW, PARA:=WORD#16#0000, SEARCHDATEN:=P#M200.0, RE_VAL:="MB199", OUTDATEN:=P#M220.0, Position:="MW196")

      L      "MB199"
      T      Dyn.Rueckmld.RET_VAL_DL_Weichen                 // Rückmeldung bei Datenbank-Zugriff (Gefälle-DL)

      JBI    G_Ok

      A      "M199.0"
      =      Dyn.Error.Weichen_DL                            // Weichendatenbank fehlerhaft
      BEC

      SET
      S      Dyn.Error.Undef_Weiche                          // undefinierte Weiche

      BEU

// Kennung + Datenbytes
G_Ok: SET
      R      Dyn.Error.Weichen_DL                            // Weichendatenbank fehlerhaft
      R      Dyn.Error.Undef_Weiche                          // undefinierte Weiche

      L      16#1004                                         // Kennung 10 + Word=04
      T      LW0                                             // Any-Kennung, Datentyp
      L      40                                              // 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_Weiche, DSTBLK:=Weiche)   // Datenliste-Daten speichern | #Ziel

      L      Dyn.Rueckmld.RET_VAL_BLKMOV_Weiche              // Rückmeldung
      L      0                                               // Fehler vorhanden ?
      <>I                                                    // Ja !
      =      Dyn.Error.BLKMov                                // Error bei Block kopieren
      BEC

      L      Weiche.Weichen_Typ                              // Weichentyp = 279 (Weiche 2fach)
      L      279                                             // Dieser Aufruf-FB ?
      ==I                                                    // Ja !
      JC     en06_Mig

      SET
      S      Dyn.Error.Undef_Weiche                          // undefinierte Weiche

      L      0                                               // Weiche ungültig !
      T      Weiche.Weichen_Nr                               // Nummer der Weiche

      BEU

en06_Mig: NOP 0


--- NW 6: 
 ---
      AN     Dyn.Status.Reset_aktiv
      JC     En06

      SET
      S      Antrieb_Weiche_vor
      S      Antrieb_Weiche_gerade_vor                       // Antrieb gerade einschalten
      S      Antrieb_Weiche_abzweig_vor                      // Antrieb abzweig einschalten

      AN     Antrieb_Weiche_aktiv
      ON     "1s-Impuls"
      JC     En06

      L      Dyn.Leer_Zeit                                   // Zeit für LeerCheck [1s]
      +      +1
      T      Dyn.Leer_Zeit                                   // Zeit für LeerCheck [1s]

      L      Weiche.Wartezeit_bis_Weiche_leer                // Leer-Zeit erreicht ?
      <I                                                     // Nein !
      JC     En06

// Dyn.Daten löschen:
      SET
      R      Dyn.Status.Reset_aktiv
      R      Dyn.Status.Weiche_abzweigen
      R      Dyn.Status.Weiche_geradeaus

      L      DINT#0
      T      Dyn.TrolleyID
      L      0
      T      Dyn.Weichen_Ziel
      T      Dyn.Zwischen_Ziel
      T      Dyn."Schleuse -1"
      T      Dyn.Leer_Zeit
      T      Dyn.FahrKontrolle.Akt_Mindestzeitzeit
      T      Dyn.FahrKontrolle."Akt_Überwachungszeit"
      T      SAVE.Schleusen_DB
      T      SAVE."Schleuse-1_DW"

// Rückmeldungen löschen:
      L      0
      T      Dyn.Rueckmld.RET_VAL_DL_Weichen
      T      Dyn.Rueckmld.RET_VAL_BLKMOV_Weiche
      T      Dyn.Rueckmld.RET_VAL_DL_Schleusen

// Störungen löschen:
      SET
      R      Dyn.Error.Weichen_DL
      R      Dyn.Error.Undef_Weiche
      R      Dyn.Error.BLKMov
      R      Dyn.Error."Undef_Bereich+1"
      R      Dyn.Error.Frei04
      R      Dyn.Error.Frei05
      R      Dyn.Error.Ziel_undefiniert
      R      Dyn.Error.Err_Schleusen_DL
      R      Dyn.Error."Err_Undef_Schleuse-1"
      R      Dyn.Error."Übzeit_Gerade"
      R      Dyn.Error."Übzeit_Abzweig"
      R      Dyn.Error.Gerade_Sensor_aktiv
      R      Dyn.Error.Abzweig_Sensor_aktiv
      R      Dyn.Error.Gerade_Bereich_belegt
      R      Dyn.Error.Abzweig_Bereich_belegt
      R      Dyn.Status."Reservierung _noch aktiv"
      R      Dyn.Error.Reset_aktiv                           // Reset ist aktiv

      L      0                                               // Damit statische Werte neu aus Datenbank geholt werden !
      T      Weiche.Weichen_Nr                               // Nummer der Weiche

      BEU

En06: NOP 0


--- NW 7: Einsprung Schleuse -1 ermitteln ---
      L      Dyn."Schleuse -1"                               // Nr. der Schleuse -1 [In/OUT von Schleuse -1 / Reset]
      T      "MW200"                                         // Search-Daten
      L      0                                               // angegeben ?
      ==I                                                    // Nein !
      =      Keine_Einfahrt
      JC     En08

      L      SAVE.Schleusen_DB                               // Weichen-FIFO-DB
      L      0                                               // Einsprung-Zeiger bekannt ?
      >I                                                     // Ja !
      R      Dyn.Error.Err_Schleusen_DL                      // Schleusen-Datenliste fehlerhaft
      R      Dyn.Error."Err_Undef_Schleuse-1"                // undefinierte Schleuse-1
      JC     En08

CALL FC "DatenOut" (SSDB:=Para.Schleusen_DL_DB, SSDW:=Para.Schleusen_DL_DW, PARA:=WORD#16#0000, SEARCHDATEN:=P#M200.0, RE_VAL:="MB199", OUTDATEN:=P#M220.0, Position:="MW196")

      L      "MB199"
      T      Dyn.Rueckmld.RET_VAL_DL_Schleusen               // Rückmeldung bei Datenbank-Zugriff (Weichen-DL)

      JBI    W_Ok

      A      "M199.0"
      =      Dyn.Error.Err_Schleusen_DL                      // Schleusen-Datenliste fehlerhaft
      BEC

      SET
      S      Dyn.Error."Err_Undef_Schleuse-1"                // undefinierte Schleuse-1

      BEU

W_Ok: L      "MW224"                                         // Rein-FIFO-DB
      T      SAVE.Schleusen_DB                               // Weichen-FIFO-DB
      L      0                                               // sinnvoller Wert ?
      <=I                                                    // Nein !
      S      Dyn.Error."Err_Undef_Schleuse-1"                // undefinierte Schleuse-1
      BEC

      L      "MW226"                                         // Rein-FIFO-DW
      T      SAVE."Schleuse-1_DW"                            // Weichen-FIFO-DW

      BEU

En08: NOP 0


--- NW 8: 
 ---
// Antrieb zusätzlich starten:
      A      ErrQuit                                         // Überwachungszeit abgelaufen quittieren
      S      Antrieb_Weiche_vor                              // Weichenantrieb starten
      S      Antrieb_Weiche_gerade_vor                       // Antrieb gerade einschalten
      S      Antrieb_Weiche_abzweig_vor                      // Antrieb abzweig einschalten

      AN     ErrQuit
      AN     Keine_Einfahrt
      JC     En08_Mig

// Störungen löschen:
      SET
      R      Dyn.Error.Ziel_undefiniert
      R      Dyn.Error.Err_Schleusen_DL
      R      Dyn.Error."Err_Undef_Schleuse-1"
      R      Dyn.Error."Übzeit_Gerade"
      R      Dyn.Error."Übzeit_Abzweig"
      R      Dyn.Error.Gerade_Sensor_aktiv
      R      Dyn.Error.Abzweig_Sensor_aktiv
      R      Dyn.Error.Gerade_Bereich_belegt
      R      Dyn.Error.Abzweig_Bereich_belegt

// Kann nur über Reset zurückgesetzt werden:
// /      R     #Dyn.Error.Weichen_DL
// /      R     #Dyn.Error.Undef_Weiche
// /      R     #Dyn.Error.BLKMov
// /      R     #Dyn.Error."Undef_Bereich+1"
// /      R     #Dyn.Error.Frei04
// /      R     #Dyn.Error.Frei05
// /      R     #Dyn.Error.Reset_aktiv//Reset ist aktiv

En08_Mig: NOP 0


--- NW 9: Einfahrt angemeldet/reserviert ? ---
      A      Keine_Einfahrt                                  // Also keine Schleuse -1 aktiv
      O      Dyn.Error.Err_Schleusen_DL                      // Schleusen-Datenliste fehlerhaft
      O      Dyn.Error."Err_Undef_Schleuse-1"                // undefinierte Schleuse-1
      JCN    Schalt                                          // Negierter Sprung!

// Einsprung löschen:
      L      0
      T      SAVE.Schleusen_DB
      T      SAVE."Schleuse-1_DW"

// Weichendaten löschen:
      L      DINT#0
      T      Dyn.TrolleyID
      L      0
      T      Dyn.Weichen_Ziel
      T      Dyn.Zwischen_Ziel
      T      Dyn.FahrKontrolle."Akt_Überwachungszeit"

      SET
      R      Dyn.Status.Kein_StartOk
      R      Dyn.Status.MindestZeit_ok
      R      Dyn.Status.Ziel_erreicht
      R      Dyn.Status."Reservierung _noch aktiv"
      R      Dyn.Status.Weiche_geradeaus
      R      Dyn.Status.Weiche_abzweigen

      JU     Ret                                             // Weichen-Checkerei überspringen


--- NW 10: Weiche aufgrund vom Weichen-Ziel checken ---
// Ziel-Check für Kontrolle:
Schalt: L      Dyn.Weichen_Ziel
      L      Weiche.Abzweig.Ziel                             // Abzweig-Ziel?
      ==I                                                    // Ja!
      =      Abzweig_Ziel

      CAC
      L      Weiche.Gerade.Ziel                              // Gerade-Ziel?
      ==I                                                    // Ja!
      =      Gerade_Ziel

      A      Dyn.Status."Reservierung _noch aktiv"           // Schleuse -1 muss Reservierung noch löschen!
      JC     Ret                                             // Damit Meldung an Schleuse -1

      A      Dyn.Status.Weiche_abzweigen                     // Weiche auf Abzweig schalten
      O      Dyn.Status.Weiche_geradeaus                     // Weiche auf Gerade schalten
      O      Dyn.Status."Reservierung _noch aktiv"           // Schleuse -1
      R      Dyn.Error.Ziel_undefiniert
      R      Dyn.Error.Gerade_Sensor_aktiv
      R      Dyn.Error.Abzweig_Sensor_aktiv
      R      Dyn.Error.Gerade_Bereich_belegt
      R      Dyn.Error.Abzweig_Bereich_belegt
      JC     en10

      AN     Fahren_Ok
      =      Dyn.Status.Kein_StartOk
      JC     Ret

// Ziel-Check zum Schalten:
      L      Dyn.Weichen_Ziel
      L      0
      ==I
      S      Dyn.Error.Ziel_undefiniert
      JC     New

      CAC
      L      Weiche.Abzweig.Ziel                             // Abzweig-Ziel?
      ==I                                                    // Ja!
      JC     Abzweigen

      CAC
      L      Weiche.Gerade.Ziel                              // Gerade-Ziel?
      ==I                                                    // Ja!
      O(
      L      16#FFFF                                         // Universal-Ziel?
      ==I                                                    // Ja!
      )
      JC     Gerade

      SET
      S      Dyn.Error.Ziel_undefiniert

      JU     New

Gerade: NOP 0
// Gerade-Fahrt gewünscht**************************************************
// Ziel-Sensor-Check:
      A      B_Ziel_gerade
      =      Dyn.Error.Gerade_Sensor_aktiv
      A      Dyn.Error.Gerade_Sensor_aktiv                   // Muss erst quittiert werden!
      JC     New

// Bereich-1-Check:
      AN     Weiche.Parameter."Bereich+1_Gerade"             // Datenbereich +1?
      JC     GOk

// Bereich +1 frei ?
      L      Weiche.Gerade."Bereich+1"
      T      "Bereich+1ID"

CALL FC "DL_Einsprung" (Bereich_DL:=274, ID:="Bereich+1ID", Dyn.DB:="Bereich+1_DB", AR_Start:=AR1Start, Error:="Err_Bereich+1")

      A      "Err_Bereich+1"
      =      Dyn.Error."Undef_Bereich+1"
      JC     New

      OPN    DB["Bereich+1_DB"]                              // Bereich+1 -DB öffnen

      L      AR1Start                                        // Startwert mit Offset 0
      +      DINT#86
      SLD    3
      T      AR1Zeiger                                       // Statt Dyn.Bereichsstop (ging nur bis DB-Länge <= 8191 Bytes)

      L      DBD [AR1Zeiger]                                 // Trolley-ID (DBD 86)
      L      0                                               // Daten vorhanden ?
      <>I
      =      Dyn.Error.Gerade_Bereich_belegt
      JC     New

// Trolley geradeaus fahren:
GOk:  SET
      S      Dyn.Status.Weiche_geradeaus                     // Weiche auf Gerade schalten
      R      Dyn.Status.Weiche_abzweigen                     // Weiche auf Abzweig schalten

// Zeiten speichern:
      L      Weiche.Gerade.Mindestzeit                       // Nach dieser Zeit kann Trolley erst aus Weiche sein
      T      Dyn.FahrKontrolle.Para_Mindestzeit
      L      Weiche.Gerade."Überwachungszeit"                // Nach dieser Zeit muss Trolley Zielbereich erreicht haben
      T      Dyn.FahrKontrolle."Para_Überwachungszeit"

      JU     en10

Abzweigen: NOP 0
// Abzweig-Fahrt gewünscht**************************************************
// Ziel-Sensor-Check:
      A      B_Ziel_abzweig
      =      Dyn.Error.Abzweig_Sensor_aktiv
      A      Dyn.Error.Abzweig_Sensor_aktiv                  // Muss erst quittiert werden!
      JC     New

// Bereich+1-Check:
      AN     Weiche.Parameter."Bereich+1_Abzweig"            // Datenbereich +1?
      JC     AOk

// Bereich +1 frei ?
      L      Weiche.Abzweig."Bereich+1"
      T      "Bereich+1ID"

CALL FC "DL_Einsprung" (Bereich_DL:=274, ID:="Bereich+1ID", Dyn.DB:="Bereich+1_DB", AR_Start:=AR1Start, Error:="Err_Bereich+1")

      A      "Err_Bereich+1"
      =      Dyn.Error."Undef_Bereich+1"
      JC     New

      OPN    DB["Bereich+1_DB"]                              // Bereich+1 -DB öffnen

      L      AR1Start                                        // Startwert mit Offset 0
      +      DINT#86
      SLD    3
      T      AR1Zeiger                                       // Statt Dyn.Bereichsstop (ging nur bis DB-Länge <= 8191 Bytes)

      L      DBD [AR1Zeiger]                                 // Trolley-ID (DBD 86)
      L      0                                               // Daten vorhanden ?
      <>I
      =      Dyn.Error.Abzweig_Bereich_belegt
      JC     New

// Trolly abzweigen fahren:
AOk:  SET
      S      Dyn.Status.Weiche_abzweigen                     // Weiche auf Abzweig schalten
      R      Dyn.Status.Weiche_geradeaus                     // Weiche auf Gerade schalten

// Zeiten speichern:
      L      Weiche.Abzweig.Mindestzeit                      // Nach dieser Zeit kann Trolley erst aus Weiche sein
      T      Dyn.FahrKontrolle.Para_Mindestzeit
      L      Weiche.Abzweig."Überwachungszeit"               // Nach dieser Zeit muss Trolley Zielbereich erreicht haben
      T      Dyn.FahrKontrolle."Para_Überwachungszeit"

      JU     en10

New:  AN     ErrQuit
      JC     en10

      L      0                                               // Reservierung löschen
      T      Dyn."Schleuse -1"

en10: NOP 0


--- NW 11: Mindestzeit / Überwachungszeit ---
      A      Gerade_Ziel
      A(
      ON     Y_Weiche_gerade
      ON     Antrieb_Gerade_aktiv
      )
      O
      A      Abzweig_Ziel
      A(
      ON     Y_Weiche_abzweig
      ON     Antrieb_Abzweig_aktiv
      )
      JC     W011

// Mindestzeit neu triggern:
      A      Dyn.Status.MindestZeit_nachtriggern
      R      Dyn.Status.MindestZeit_nachtriggern
      JCN    X011                                            // Negierter Sprung

W011: L      0
      T      Dyn.FahrKontrolle.Akt_Mindestzeitzeit

      JU     y011

// Zeiten aufaddieren:
X011: AN     "1s-Impuls"                                     // 1s-Impuls
      ON     Antrieb_Weiche_aktiv
      JC     X08E

      L      Dyn.FahrKontrolle.Akt_Mindestzeitzeit
      +      1
      T      Dyn.FahrKontrolle.Akt_Mindestzeitzeit

y011: L      Dyn.FahrKontrolle.Akt_Mindestzeitzeit
      L      Dyn.FahrKontrolle.Para_Mindestzeit
      >=I
      =      Dyn.Status.MindestZeit_ok
      JCN    X080

      T      Dyn.FahrKontrolle.Akt_Mindestzeitzeit

X080: A      Dyn.Status.Ziel_erreicht
      O      Dyn.Error."Übzeit_Gerade"
      O      Dyn.Error."Übzeit_Abzweig"
      ON     "1s-Impuls"                                     // 1s-Impuls
      ON     Antrieb_Weiche_aktiv
      JC     X08E

      L      Dyn.FahrKontrolle."Akt_Überwachungszeit"
      +      1
      T      Dyn.FahrKontrolle."Akt_Überwachungszeit"

      L      Dyn.FahrKontrolle."Para_Überwachungszeit"
      <I                                                     // Max.Zeit erreicht ?
      JC     X08E                                            // Nein

// Überwachungszeit ist abgelaufen:
      A      Dyn.Status.Weiche_geradeaus
      S      Dyn.Error."Übzeit_Gerade"

      A      Dyn.Status.Weiche_abzweigen
      S      Dyn.Error."Übzeit_Abzweig"

      L      0                                               // Zeiten neu initialisieren
      T      Dyn.FahrKontrolle."Akt_Überwachungszeit"

X08E: NOP 0


--- NW 12: Ziel ist erreicht ---
      A      Dyn.Status.Ziel_erreicht                        // Einmaliger Durchlauf
      JC     X09E

      A      Dyn.Status.Weiche_geradeaus
      A      B_Ziel_gerade
      JC     Ziel_GOk

      A      Dyn.Status.Weiche_abzweigen
      A      B_Ziel_abzweig
      JC     Ziel_AOk

      JU     X09E

Ziel_GOk: SET
      S      Dyn.Status.Ziel_erreicht
      R      Dyn.Error."Übzeit_Gerade"

      AN     Weiche.Parameter."Bereich+1_Gerade"             // Keine Daten-Weitergabe
      JC     X09E

      L      Weiche.Gerade."Bereich+1"                       // Bereich für Daten-Übergabe
      JU     Daten

Ziel_AOk: SET
      S      Dyn.Status.Ziel_erreicht
      R      Dyn.Error."Übzeit_Abzweig"

      L      Dyn.Schalttakte
      +      DINT#1                                          // Auf Abzweig umgeschaltet +1
      T      Dyn.Schalttakte

      AN     Weiche.Parameter."Bereich+1_Abzweig"            // Keine Daten-Weitergabe
      JC     X09E

      L      Weiche.Abzweig."Bereich+1"                      // Bereich für Daten-Übergabe

// Daten an Bereich +1 übergeben:
Daten: T      "Bereich+1ID"

CALL FC "DL_Einsprung" (Bereich_DL:=274, ID:="Bereich+1ID", Dyn.DB:="Bereich+1_DB", AR_Start:=AR1Start, Error:="Err_Bereich+1")

      A      "Err_Bereich+1"
      JC     X09E

      OPN    DB["Bereich+1_DB"]                              // Bereich+1 -DB öffnen

      L      AR1Start                                        // Startwert mit Offset 0
      +      DINT#86
      SLD    3
      T      AR1Zeiger                                       // Statt Dyn.Bereichsstop (ging nur bis DB-Länge <= 8191 Bytes)

      L      Dyn.TrolleyID
      T      DBD [AR1Zeiger]                                 // Trolley-ID (DBD 86)

      L      AR1Start                                        // Startwert mit Offset 0
      +      DINT#152
      SLD    3
      T      AR1Zeiger                                       // Statt Dyn.Bereichsstop (ging nur bis DB-Länge <= 8191 Bytes)

      L      Dyn.Zwischen_Ziel
      T      DBW [AR1Zeiger]                                 // Zwischen-Ziel (DBW 152)

X09E: NOP 0


--- NW 13: RET: Weiche schalten ---
Ret:  A      Dyn.Status.Reset_aktiv
      JC     En13

      A      Dyn.Status.Weiche_geradeaus                     // Weiche auf Gerade schalten
      R      Dyn.Status.Weiche_abzweigen                     // Gerade hätte Vorrang
      S      Y_Weiche_gerade                                 // nicht mit =, damit Weichenstellung erst bei Änderung schaltet!
      R      Y_Weiche_abzweig

      A      Dyn.Status.Weiche_abzweigen                     // Weiche auf Abzweig schalten
      S      Y_Weiche_abzweig
      R      Y_Weiche_gerade

En13: NOP 0


--- NW 14: Antriebe ansteuern / stoppen ? ---
      A      Dyn.Status.Weiche_geradeaus                     // Weiche auf Gerade schalten
      O      Dyn.Status.Weiche_abzweigen                     // Gerade hätte Vorrang
      ON     Keine_Einfahrt                                  // Also ist Schleuse -1 aktiv
      =      Antriebe_ein

      A      Antriebe_ein
      O      Dyn.Status.Reset_aktiv
      S      Antrieb_Weiche_vor                              // Weichenantrieb starten

      A      Antriebe_ein
      A      Dyn.Status.Weiche_geradeaus
      O      Dyn.Status.Reset_aktiv
      S      Antrieb_Weiche_gerade_vor                       // Antrieb gerade einschalten

      A      Antriebe_ein
      A      Dyn.Status.Weiche_abzweigen
      O      Dyn.Status.Reset_aktiv
      S      Antrieb_Weiche_abzweig_vor                      // Antrieb abzweig einschalten

// Antriebe stoppen
      AN     Dyn.Status.Reset_aktiv
      A(
      AN     Keine_Einfahrt                                  // Also ist Schleuse -1 aktiv
      A(
      AN     Fahren_Ok
      O
      A      Dyn.Status.Weiche_abzweigen
      A(
      ON     Weiche_ist_AST
      ON     Antrieb_Abzweig_aktiv
      )
      O
      A      Dyn.Status.Weiche_geradeaus
      A(
      O      Weiche_ist_AST
      ON     Antrieb_Gerade_aktiv
      )
      )
      ON     Dyn.Status.Auto_akt                             // SystemVoraussetzungen fehlen
      O      Dyn.Status.Hand_akt
      ON     Dyn.Status.Bereich_ok
      )
      S      Antrieb_Weiche_stop                             // Alle Antriebe stoppen

      SET                                                    // //
      R      Antrieb_Weiche_stop                             // Alle Antriebe stoppen////


--- NW 15: Weiche ist frei  ---
      L      SAVE.Schleusen_DB                               // Alte Speicherung ?
      L      SAVE."Schleuse-1_DW"
      OW
      L      Dyn.Weichen_Ziel
      OW
      L      0
      ==I
      A      Keine_Einfahrt                                  // Keine Einfahrt aktiv
      AN     Dyn.Status.Weiche_geradeaus                     // Weiche auf Gerade schalten
      AN     Dyn.Status.Weiche_abzweigen                     // Gerade hätte Vorrang
      AN     Dyn.Status."Reservierung _noch aktiv"
      AN     Dyn.Status.Reset_aktiv
      =      Dyn.Status.Weiche_frei
      R      Dyn.Status.MindestZeit_nachtriggern
      NEG
      =      Dyn.Status.Weiche_aktiv                         // Zum Abfragen, damit evtl. Förderer nicht ausgeschaltet wird


--- NW 16: Schleuse -1 aktiv / vorhanden ? ---
      A      Keine_Einfahrt
      O      Dyn.Error.Err_Schleusen_DL                      // Schleusen-Datenliste fehlerhaft
      O      Dyn.Error."Err_Undef_Schleuse-1"                // undefinierte Schleuse-1
      BEC

      L      SAVE.Schleusen_DB                               // Schleusen-DB
      L      0                                               // Einsprung-Zeiger bekannt ?
      <=I                                                    // Nein !
      BEC

// Anmeldung an diese Weiche von Schleuse -1 noch aktiv?:
      L      SAVE."Schleuse-1_DW"
      ITD
      T      AR1Start                                        // Startwert mit Offset 0

      L      AR1Start                                        // Startwert mit Offset 0
      +      DINT#16
      SLD    3
      T      AR1Zeiger                                       // Statt Dyn.Bereichsstop (ging nur bis DB-Länge <= 8191 Bytes)

      OPN    DB[SAVE.Schleusen_DB]                           // FABE+ -DB öffnen

      L      DBW [AR1Zeiger]                                 // Anmeldung von dieser Schleuse (DBW16)
      L      Weichen_Nr
      ==I                                                    // Ja !
      JC     Mldg

      L      0                                               // Reservierung löschen
      T      Dyn."Schleuse -1"

      BEU


--- NW 17: Meldung an Schleuse -1: Weiche hat geschaltet ---
Mldg: L      AR1Start                                        // Startwert mit Offset 0
      +      DINT#71
      SLD    3
      L      4                                               // Damit DBX71.4
      OD
      T      AR1Zeiger                                       // Statt Dyn.Bereichsstop (ging nur bis DB-Länge <= 8191 Bytes)

      OPN    DB[SAVE.Schleusen_DB]                           // FABE+ -DB öffnen

      A(
      A      Dyn.Status.Weiche_geradeaus                     // Weiche auf Gerade schalten
      A      Gerade_Ziel
      A      Y_Weiche_gerade
      A      Antrieb_Gerade_aktiv
      O
      A      Dyn.Status.Weiche_abzweigen                     // Gerade hätte Vorrang
      A      Abzweig_Ziel
      A      Y_Weiche_abzweig
      A      Antrieb_Abzweig_aktiv
      )
      A      Fahren_Ok
      A      Antrieb_Weiche_aktiv                            // Antrieb aktiv
      AN     Dyn.Status.Reset_aktiv
      =      DBX [AR1Zeiger]                                 // Weiche hat geschaltet ? (DBX71.4)


--- NW 18: Meldung an Schleuse -1: Trolley hat Ziel erreicht  ---
      L      AR1Start                                        // Startwert mit Offset 0
      +      DINT#71
      SLD    3
      L      5                                               // Damit DBX71.5
      OD
      T      AR1Zeiger                                       // Statt Dyn.Bereichsstop (ging nur bis DB-Länge <= 8191 Bytes)

      OPN    DB[SAVE.Schleusen_DB]                           // FABE+ -DB öffnen

      A      Dyn.Status.Ziel_erreicht
      A      Dyn.Status.MindestZeit_ok
      O      Dyn.Status.Reset_aktiv
      =      DBX [AR1Zeiger]                                 // Trolley ausserhalb Weiche (DBX71.5)
      S      Dyn.Status."Reservierung _noch aktiv"
      JCN    En18                                            // Negierter Sprung

      L      0                                               // Zeiten neu initialisieren
      T      Dyn.FahrKontrolle."Akt_Überwachungszeit"

En18: NOP 0


--- NW 19: Ende ---
      BE

