From e9f6d3466535e4ba78bffc27980d8f94da23117e Mon Sep 17 00:00:00 2001 From: Embi Date: Wed, 8 Jul 2026 09:53:43 +0200 Subject: [PATCH] =?UTF-8?q?LP=5FZiel=5FFC=20als=20SCL=20Datei=20hinzugef?= =?UTF-8?q?=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SCL-Export/=A01+UH07-KF00/LP_Ziel_FC.scl | 139 +++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 SCL-Export/=A01+UH07-KF00/LP_Ziel_FC.scl diff --git a/SCL-Export/=A01+UH07-KF00/LP_Ziel_FC.scl b/SCL-Export/=A01+UH07-KF00/LP_Ziel_FC.scl new file mode 100644 index 0000000..ec1e563 --- /dev/null +++ b/SCL-Export/=A01+UH07-KF00/LP_Ziel_FC.scl @@ -0,0 +1,139 @@ +FUNCTION "LP_Ziel_FC" : Void +TITLE = Ziel-FC: LeerPuffer_OmniFahren +{ S7_Optimized_Access := 'FALSE' } +AUTHOR : AE +FAMILY : Module +NAME : Ziel +//SCL-Portierung des AWL-Bausteins FC5181 "LP_Ziel_FC" (verhaltensgleich). +// +//Der Baustein hatte im AWL-Original die Bausteineigenschaft "Parameterversorgung +//ueber Register" (ParameterPassing) aktiv und wurde per "UC FC[..]" indirekt aus +//AWL aufgerufen -> aus SCL nicht compilierbar. Er liest ausschliesslich globale +//Merker (MW190 = Schleusen-Nr) sowie den Bool-Merker "MB3305" und ruft die +//Zielbausteine voll qualifiziert auf -> keine echte Registerabhaengigkeit. +//Als SCL-Baustein entfaellt die Option und er ist direkt aus SCL aufrufbar +//(CASE 5181 in MHMOmniSchleuse). +// +//Der indirekte Dispatch (AWL: "L MW190 / L 3305 / NE_I / JC X3305E") ist als CASE +//ueber die Schleusen-Nr (MW190) ausgefuehrt. Es existiert nur der Zweig 3305; ein +//AWL-BEU/BEC im getroffenen Zweig ist als RETURN bzw. "IF THEN RETURN;" +//umgesetzt (verhaltensgleich, da nach dem Dispatch nur noch das Bausteinende folgt). +//Die Merker-Schnittstelle (MW190 vom Aufrufer, M180.6 = Weiterfahrt-Freigabe, +//MB199 = DatenOut-Rueckmeldung) bleibt erhalten. +// +//ABWEICHUNGEN ZUM AWL-ORIGINAL (bei Inbetriebnahme pruefen!): +// - DatenOut: der Merker-Scratch-Bereich M220 (Such-/OutDaten-Pointer P#M220.0) +// ist durch den lokalen Puffer #DatenPuffer ersetzt (SEARCHDATEN/OUTDATEN sind +// VARIANT statt POINTER). MW220/MW224/MW226 werden dadurch NICHT mehr als +// Merker beschrieben/gelesen (Ergebnis identisch, keine Merker-Nebenwirkung). +// Lager-DB = Datensatz-Wort 2 (=M224), Lager-DW = Wort 3 (=M226). +// - BTI (BCD-Wort -> Int, "Damit Int 1-10 als Ziel") ist ueber den Projekt-FC +// "BCD (4stellig)_to_INT" ausgefuehrt; Fehlerverhalten bei ungueltiger BCD kann +// abweichen (BTI setzt BIE). +// - Indirekter DB-Zugriff (AWL: OPEN_DB DB[Lager_DB] / A DBX[AR1Zeiger] mit +// Pointer-Arithmetik ADD DINT#70 / SLD 3 / OD 7) ist durch PEEK_BOOL +// (area 16#84, byteOffset = Lager_DW+70, bitOffset = 7 -> Bit 7: Inilauf) +// ersetzt. Die Temp "AR1Zeiger" wird dadurch nicht mehr benoetigt. +// - AWL "CLR / S M180.6": die Set-Operation steht unter RLO=0 (CLR) und wird +// daher NICHT ausgefuehrt (bewusst deaktiviert; Weiterfahrt wird ueber +// MSorterRein FB5423/5 gestartet). M180.6 bleibt an dieser Stelle unveraendert. +// - "MB3305" wird (wie im AWL: A / BEC) als Bool-Symbol behandelt. +// - Word-Vergleiche direkt (z.B. (Ziel_hex AND W#16#F000) = W#16#A000); +// MW190 wird fuer den CASE ueber WORD_TO_INT in Int gewandelt. +// - Zusaetzliche Temp "DatenPuffer" (Array[0..15] of Word, nicht im XML-Interface) +// als DatenOut-Puffer eingefuehrt. TypedConstants DINT#70/DINT#1/DINT#0 1:1. +// - "Default_Ziel"/"Rec_DEST_Ziel" werden als Int beschrieben (AWL: 16-Bit-T von +// Ziel_int); falls die DB-Member als Word deklariert sind -> INT_TO_WORD noetig. + VAR_TEMP + Ziel_hex : Word; + Ziel_int : Int; + Zielebene : Word; + Error : Byte; + Position : Int; + Lager_DB : Int; + Lager_DW : Int; + AR1Zeiger : DWord; // Statt AR1 (ging nur bis DB-Länge <= 8191 Bytes) + AR1Start : DInt; // Startwert mit Offset 0 + SSDW : Int; + EndZiel : Word; + Variante : Int; + AbrufID : DInt; + Fahrlisten_TrolleyID : DInt; + Fahrlisten_AbrufID : DInt; + Fahrlisten_Lager : Int; + Trolley_unbekannt : Bool; // Trolley ist nicht in DL + Express_Abruf : Bool; + DatenPuffer : Array[0..15] of Word; // Puffer fuer DatenOut (ersetzt Merker-Scratch M220) + END_VAR + +BEGIN + // NW1: Rueckmeldung - Rueckmeldungen erst mal resetten + "M180.6" := FALSE; // Weiterfahrt von Ziel-FC erlaubt + + // NW2: Schleuse 3305: Weiterfahren erlaubt ? (Sorter LP) + // AWL: L MW190 / L 3305 / NE_I / JC X3305E (Aufruf von Schleuse 3305?) + CASE WORD_TO_INT("MW190") OF + + 3305: + IF "MB3305" THEN + RETURN; // AWL: A MB3305 / BEC + END_IF; + + // Leer-Puffer ermitteln: + "Leerpuffer to Rein-Lager ermitteln"(Puffer => "Ziel_hex"); + + // Ziel = Leer-Lager? + IF ("Ziel_hex" AND W#16#F000) <> W#16#A000 THEN // (AWL: AW F000 / EQ_I A000 / JC LagerOk / BEU) + RETURN; // Kein Lager frei! + END_IF; + + // AWL: L Ziel_hex / L W#16#FF / AW / BTI / T Ziel_int (Damit Int 1-10 als Ziel!) + "BCD (4stellig)_to_INT"(BCD_Wert := ("Ziel_hex" AND W#16#00FF), + Int_Wert => "Ziel_int"); + + // Check, ob Ziel-Lager Inilauf aktiv hat: + #DatenPuffer[0] := INT_TO_WORD("Ziel_int"); // Suchschluessel (AWL: T MW220) + "DatenOut"(SSDB := 275, + SSDW := 0, + PARA := W#16#0000, // Eintrag lesen + SEARCHDATEN := #DatenPuffer, + RE_VAL => "MB199", + Position => #Position, + OUTDATEN := #DatenPuffer); + + // AWL: L MB199 / L 2#1111111 / AW / L 0 / NE_I / JC Egal (Bit 7 ausblenden; Fehler vorhanden?) + IF BYTE_TO_INT("MB199" AND B#16#7F) = 0 THEN // kein Fehler -> Inilauf pruefen + "Lager_DB" := WORD_TO_INT(#DatenPuffer[2]); // AWL: L MW224 / T Lager_DB + "Lager_DW" := WORD_TO_INT(#DatenPuffer[3]); // AWL: L MW226 / T Lager_DW + "AR1Start" := INT_TO_DINT("Lager_DW"); // Startwert mit Offset 0 + // AWL: ADD DINT#70 / SLD 3 / OD 7 -> Bit-Pointer auf DBX(Lager_DW+70).7 (Bit 7: Inilauf) + IF PEEK_BOOL(area := 16#84, + dbNumber := INT_TO_DINT("Lager_DB"), // Lager-DB + byteOffset := "AR1Start" + DINT#70, // Offset Status + bitOffset := 7) THEN // Lager hat Inilauf aktiv + RETURN; // Sonst kann der Inilauf nie beendet werden! + END_IF; + END_IF; + + // Egal: + "DLP_Sorter".Sorter_MB3305.Separator.Default_Ziel := "Ziel_int"; + "DLP_Sorter".Sorter_MB3305.Dyn.Scanner.Rec_DEST_Ziel := "Ziel_int"; + + // Pseudo-IDX uebergeben: + // AWL: L Rec_IDX / L DINT#0 / NE_D / BEC (Daten schon erzeugt? Ja!) + IF "DLP_Sorter".Sorter_MB3305.Dyn.Scanner.Rec_IDX <> DINT#0 THEN + RETURN; + END_IF; + "DLP_Sorter".Pseudo_IDX := "DLP_Sorter".Pseudo_IDX + DINT#1; // Da kein Leser verbaut + "DLP_Sorter".Sorter_MB3305.Dyn.Scanner.Rec_IDX := "DLP_Sorter".Pseudo_IDX; // IDX + + // AWL: CLR / S M180.6 -> Set steht unter RLO=0 (CLR) und wird NICHT ausgefuehrt. + // Weiterfahrt wird ueber MSorterRein (FB5423/5) gestartet -> M180.6 bleibt unveraendert. + // AWL: BEU -> Bausteinende + + ELSE + ; // andere Schleusen-Nr -> nichts tun (AWL: X3305E / NOP 0) + END_CASE; + + // NW3: Ende (AWL: BE) +END_FUNCTION