SCL mit langen Bitverknüpfungen

COCO-RB

Level-2
Beiträge
30
Reaktionspunkte
1
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo, ich bin in der SCL-Programmierung noch neu. Ich habe angefangen einen Baustein von AWL nach SCL umzuschreiben. Soweit seiht das im TIA-Portal V14 ja auch ganz übersichtlich aus. Bei den längeren Logikverknüpfungen bin ich mir aber noch etwas unsicher. Ich habe die Onlinehilfe dazu gelesen, finde bei Siemens außer der Beschreibung aber kaum Beispiele.

Operatoren und ihre Auswertungsreihenfolge
Ausdrücke können durch Operatoren miteinander verknüpft oder ineinander geschachtelt sein.
Die Reihenfolge der Auswertung von Ausdrücken hängt von der Rangfolge der Operatoren und der Klammerung ab. Grundsätzlich gelten folgende Regeln:

  • Arithmetische Operatoren werden vor Vergleichsoperatoren und diese vor logischen Operatoren ausgewertet.
  • Gleichrangige Operatoren werden nach ihrem Auftreten von links nach rechts ausgewertet.
  • Wertzuweisungen werden von rechts nach links ausgewertet.
  • Operationen in Klammern werden zuerst ausgewertet.

// Auszug in AWL

U #inout_Bereich_Ende
O(
UN #stat_Regler.ProgPos.Steuerwort."2_Bit_00_M090_PLC_Kanal_0"
UN #stat_Regler.ProgPos.Steuerwort."2_Bit_01_M091_PLC_Kanal_1"
UN #stat_Regler.ProgPos.Steuerwort."2_Bit_02_M092_PLC_Kanal_2"
UN #stat_Regler.ProgPos.Steuerwort."2_Bit_03_M093_PLC_Kanal_3"
UN #stat_Regler.ProgPos.Steuerwort."2_Bit_04_M094_PLC_Kanal_4"
UN #stat_Regler.ProgPos.Steuerwort."2_Bit_05_M095_PLC_Kanal_5"
)
U #in_Standby_erlauben
O #in_Halt_Vorschub
UN #in_Tippen_plus
UN #in_Tippen_minus
UN #in_Referenzfahrt_starten
U #stat_Regler.ProgPos.Statuswort."1_Bit_01_Einschaltbereit"
= #stat_Verz_StandBy.VAR_IN

// Auszug in SCL

#stat_Verz_StandBy.VAR_IN := (
(#stat_Regler.ProgPos.Statuswort."1_Bit_01_Einschaltbereit" AND
NOT #in_Referenzfahrt_starten AND
NOT #in_Tippen_minus AND
NOT #in_Tippen_plus) AND
#in_Halt_Vorschub OR
#in_Standby_erlauben AND
((NOT #stat_Regler.ProgPos.Steuerwort."2_Bit_00_M090_PLC_Kanal_0"
AND NOT #stat_Regler.ProgPos.Steuerwort."2_Bit_01_M091_PLC_Kanal_1"
AND NOT #stat_Regler.ProgPos.Steuerwort."2_Bit_02_M092_PLC_Kanal_2"
AND NOT #stat_Regler.ProgPos.Steuerwort."2_Bit_03_M093_PLC_Kanal_3"
AND NOT #stat_Regler.ProgPos.Steuerwort."2_Bit_04_M094_PLC_Kanal_4"
AND NOT #stat_Regler.ProgPos.Steuerwort."2_Bit_05_M095_PLC_Kanal_5")
OR #inout_Bereich_Ende));

Ist die Umsetzung Richtig oder gibt es auch eine einfachere Lösung?
Kennt Ihr Beispiele zu solchen Umsetzungen Vergleich AWL / SCL Programmierung?

Vielen Dank!
:)
 
Zuletzt bearbeitet:
Auf die Schnelle fällt mir nur ein das vielleicht in mehrere Teile zu Teilen mit temporären Variablen. Das könnte dann etwas lesbarer werden.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich finde in deinen Beispiel keinen Unterschied hinsichtlich der Lesbarkeit,
allerhöchstens hätte ich bei SCL das "AND" vor den zeilenubruch mit in die
Folgende Zeile genommen.

Das unleserliche kommt von den langen Variablen, die könntest du ja Temponär
auf kürze umlade oder über die Bausteinschnittstelle in kurze Variablen wandeln.
 
Hallo,

vielen Dank für die Antworten!

Ich denke ein umkopieren um kürzere Texte zu erhalten ist eher unpraktisch. Ich möchte ja die Symbolischen Namen sehen und nicht eine Abkürzung oder einen Stellvertreter.
Die Position der Verknüpfung am Zeilenanfang ist eine gute Idee, ich habe auch einen zusammengehörigen Block nach innen gerückt.

Wenn man lange in AWL gearbeitet hat, ist das lesen der Verknüpfung von Rechts nach Links sehr ungewohnt, gerade wenn durch die langen Symbolischen Variablen am Ende oft nur wenige Variablen hintereinander stehen. Es ja so als müsste man von unten nach oben lesen und dann auch noch die Rangfolge beachten. Das mit der Rangfolge führt ja auch zu mehr Klammern.

Ich werde mit diesen Zeilen mal ein Testprogramm schreiben um zu prüfen ob die Logik dann das gleiche wie die AWL Zeilen macht.

Zusätzlich habe ich auch eine Frage an den Siemens Support gestellt, wenn es eine gute Antwort gibt werde ich mich melden.
Es ist mir halt wichtig, einen fehlerfreien und gut lesbaren Code zu schreiben. Wenn ich mal mehr in SCL mache möchte ich nicht ständig nacharbeiten oder andere Überraschungen erleben.

Schöne Grüße,
COCO


#stat_Verz_StandBy.VAR_IN := (
(#stat_Regler.ProgPos.Statuswort."1_Bit_01_Einschaltbereit" AND
NOT #in_Referenzfahrt_starten AND
NOT #in_Tippen_minus AND
NOT #in_Tippen_plus)
AND #in_Halt_Vorschub
OR #in_Standby_erlauben
AND ((NOT #stat_Regler.ProgPos.Steuerwort."2_Bit_00_M090_PLC_Kanal_0"
AND NOT #stat_Regler.ProgPos.Steuerwort."2_Bit_01_M091_PLC_Kanal_1"
AND NOT #stat_Regler.ProgPos.Steuerwort."2_Bit_02_M092_PLC_Kanal_2"
AND NOT #stat_Regler.ProgPos.Steuerwort."2_Bit_03_M093_PLC_Kanal_3"
AND NOT #stat_Regler.ProgPos.Steuerwort."2_Bit_04_M094_PLC_Kanal_4"
AND NOT #stat_Regler.ProgPos.Steuerwort."2_Bit_05_M095_PLC_Kanal_5")
OR #inout_Bereich_Ende));
 
Wenn das zuviel wird (Kann bei Handling-Freigaben schon mal kompliziert werden), dann kann man ja durchaus ein Stück Code in einen AWL- oder KOP/FUP-Baustein auslagern und sich das Ergebnis zurück holen.
Besonders Verschachtelungen sind schnell unübersichtlich.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
ich habe jetzt mal einen Test der SCL im Vergleich zu den AWL Zeilen gemacht. Wenn die letzte UND-Verknüpfung "..._Einschaltbereit" ein 0-Signal hat, muss das Ergebnis auch Null haben!

U #stat_Regler.ProgPos.Statuswort."1_Bit_01_Einschaltbereit"
= #stat_Verz_StandBy.VAR_IN

Mit dem SCL-Code erhalte ich aber eine 1.

Was mache ich falsch? Oder muss der die SCL-Zeile nicht von Rechts nach Links gelesen werden?

Test_SCL.jpg
 
Ich lese SCL-Zeilen von Links nach rechts (Ausgehend von der Zuweisung). Und weil mir das irgendwie seltsam vorkam, hab ich das mal nachgebastelt, was ich lese.

Oben der AWL-Code, unten der SCL-Code:
Unbenannt.jpg

Ich erhebe nicht den Anspruch auf Richtigkeit!
 
Zuletzt bearbeitet:
ok, danke für deine Überlegungen!

Gleichrangige Operatoren werden nach ihrem Auftreten von links nach rechts ausgewertet.Wertzuweisungen werden von rechts nach links ausgewertet.

Die Erklärung, ohne Beispiel, von Siemens hat mich vermutlich auf den falschen Pfad gebracht.

Wie würde dann eine gleichwertige SCL Zuweisung aussehen?
Ich werde jetzt auch mal in die Richtung links nach rechts testen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich finde in deinen Beispiel keinen Unterschied hinsichtlich der Lesbarkeit...
Das sehe ich auch so. Diese wechselseitigen UND und ODER Verknüpfungen sind sowohl in AWL als auch in SCL eine Katastrophe. Wenn es unbedingt in SCL oder AWL sein muss, dann in diesem Fall vielleicht besser mit Zwischenergebnissen als mit Klammerebenen arbeiten. Wenn ich mich nicht täusche, muss der SCL-Code mit Klammerebenen mit drei Klammern beginnen. Hab's aber nicht getestet und erhebe auch keinen Anspruch auf Richtigkeit.

Auf die Antwort von Siemens wäre ich mal gespannt. Gibt sich der Support wirklich mit so etwas ab?
Im TIA-Portal der aktuellen Version kannst du übrigens in FUP-Bausteinen auch AWL- und SCL-Netzwerke einfügen, zumindest bei der 1500. Das ist für so etwas nicht uninteressant.
 
So und jetzt hänge ich mich noch weiter raus und präsentiere meine Variante des Code-Äquivalents:

Code:
#stat_Verz_StandBy.VAR_IN:=

(#inout_Bereich_Ende or (
not #stat_Regler.ProgPos.Steuerwort."2_Bit_00_M090_PLC_Kanal_0" 
and not #stat_Regler.ProgPos.Steuerwort."2_Bit_01_M091_PLC_Kanal_1"
and not #stat_Regler.ProgPos.Steuerwort."2_Bit_02_M092_PLC_Kanal_2"
and not #stat_Regler.ProgPos.Steuerwort."2_Bit_03_M093_PLC_Kanal_3"
and not #stat_Regler.ProgPos.Steuerwort."2_Bit_04_M094_PLC_Kanal_4"
and not #stat_Regler.ProgPos.Steuerwort."2_Bit_05_M095_PLC_Kanal_5"
)
and #in_Standby_erlauben
or #in_Halt_Vorschub)
and not #in_Tippen_plus
and not #in_Tippen_minus
and not #in_Referenzfahrt_starten
and #stat_Regler.ProgPos.Statuswort."1_Bit_01_Einschaltbereit"
;

Und ja: Dafür hab ich jetzt 20 Minuten gebraucht und 2 Tassen kalten Kaffee von heute morgen :shock:

Edit2: schnell noch finales Semikolon rein, bevor es einer merkt :cool:
 
Zuletzt bearbeitet:
danke für deine Bemühungen, echt super!
Ich habe den Code getestet, alles ok!

Alternativ hatte ich schon eine Version getestet, bei der ich nach jeder Anweisung eine Klammer setze.
Dann kann zwar in der Reihenfolge wie bei AWL programmiert werden, das sieht aber unübersichtlich aus!

Ich denke das größte Problem war mein falscher Ansatz, von rechts nach links zu lesen!
Das sollte in der Onlinehilfe besser mit einem Beispiel erklärt werden.

#stat_Verz_StandBy.VAR_IN := ((((((#inout_Bereich_Ende
OR (NOT #stat_Regler.ProgPos.Steuerwort."2_Bit_00_M090_PLC_Kanal_0"
AND NOT #stat_Regler.ProgPos.Steuerwort."2_Bit_01_M091_PLC_Kanal_1"
AND NOT #stat_Regler.ProgPos.Steuerwort."2_Bit_02_M092_PLC_Kanal_2"
AND NOT #stat_Regler.ProgPos.Steuerwort."2_Bit_03_M093_PLC_Kanal_3"
AND NOT #stat_Regler.ProgPos.Steuerwort."2_Bit_04_M094_PLC_Kanal_4"
AND NOT #stat_Regler.ProgPos.Steuerwort."2_Bit_05_M095_PLC_Kanal_5")
AND #in_Standby_erlauben)
OR #in_Halt_Vorschub)
AND NOT #in_Tippen_plus)
AND NOT #in_Tippen_minus)
AND NOT #in_Referenzfahrt_starten)
AND #stat_Regler.ProgPos.Statuswort."1_Bit_01_Einschaltbereit");

Deinen Vorschlag werde ich in der Software beim Kunden Morgen übernehmen, nochmal vielen Dank!
 
Zuviel Werbung?
-> Hier kostenlos registrieren
ich habe die Änderung im Programm (für Morgen) schon einmal übernommen. Dabei habe ich mir meine erste Version dieser Verknüpfung noch einmal angesehen.

Da hatte ich von links nach rechts gelesen, ist ja auch einfacher zu lesen! Ich bin erst mit den Anpassungen angefangen, als es nicht gleich lief.
(da fehlte dann ja nur eine Klammer nach der OR Anweisung)erster_Versuch.jpg
 
Also ganz ehrlich das mit den Klammern macht es nicht wirklich übersichtlich,
wenn schon nicht kurz dann vielleicht wirklich mal ein paar temporäre Zwischenergebnisse
erzeugen. Deine folgenden Kollegen und Kunden werden es dir danken.
Da sind doch ein paar gleichartige Signale wie die von den Reglern, Tippen ...
 
@rostiger Nagel
Es stand vermutlich der Vorsatz dahinter, den effizienten AWL-Code in effizienten SCL-Code zu überführen.
Ich fände schon Zwischenergebnisse bei der AWL-VAriante besser.

Codeeffizienz bemisst sich heute nicht an der Speichergröße und kaum an der Ausführungsgeschwindigkeit. Die Lesbarkeit sollte vornedran gerückt sein...

@COCO-RB

Wertzuweisungen von rechts nach links- Da ist sowas gemeint:
var_a:=var_b:=var_c:=var_d:=true;
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
der letzte Vorschlag hat leider nicht funktioniert, in der Simulation hatte ich wohl nicht genug getestet.

SPS_Portal_Test_negativ.jpg

Ich habe aber eine Lösung gefunden, der SCL-Code muss bei der Wertzuweisung aber von Rechts nach Links gelesen werden!
Das ist dann so als würde der AWL-Code von unten nach oben geschrieben.

LÖSUNG.jpg

Von Siemens kam nur die Empfehlung einen SCL-Kurs zu besuchen!
Ich denke der kostenlose Support ist damit Überfordert!

Mit unserem Siemens Vertriebspartner habe ich jetzt einen SCL Workshop abgesprochen.
(ein Tag ist im Werk kostenlos, vermutlich müssen wir aber auch mal Kurse belegen)
 
Aber das Einklammern mache ich in SCL schon immer, aus Gewohnheit. Wahrscheinlich ist mit das deshalb noch nie wirklich aufgefallen.
 
der SCL-Code muss bei der Wertzuweisung aber von Rechts nach Links gelesen werden!
Ich denke da machst du einen Fehler
Gleichrangige Operatoren werden nach ihrem Auftreten von links nach rechts ausgewertet.
(#inout_Bereich_Ende or (
Da "inout_Bereich_Ende" bereits True ist wird die weitere Abarbeitung hier abgebrochen und das Ergebnis ist True.

Habe eben kein SCL zur Hand und darum die Verknüpfung in Codesys nachgestellt. Ist hier genauso.
OR.jpg

Holger
 
Zuviel Werbung?
-> Hier kostenlos registrieren
ich habe jetzt doch noch eine brauchbare Information vom Siemens Service erhalten.

Mit Wertzuweisung ist einfach nur gemeint, dass der Teil der auf der Linken Seite steht der Variablen auf der Rechten Seite zugeordnet wird.
Mit Gleichartigen Operanden sind dann die Verknüpfungen OR, AND usw. gemeint.
Ich kann den Code in SCL also in der gleichen Reihenfolge wie in AWL programmieren.
Es besteht jedoch der Unterschied, dass es bei SCL eine Rangordnung gibt und AND z.B. vor OR ausgeführt wird.
Um die Reihenfolge in meinem Fall sicherzustellen, müssen Klammen verwendet werden.

Die tatsächliche Reihenfolge spielt also keine Rolle, in jedem Fall gibt es eine Lösung.
Da mir das lesen von links nach rechts bzw. von oben nach unten (wie bei AWL) besser gefällt, habe ich die Zeilen noch einmal umgeschrieben.

Na das war jetzt aber ein Weg, hoffe mal einen Kurs besuchen zu dürfen!
Vielen Dank an alle für die guten Beiträge!

LÖSUNG_2.jpg
 
Im ersten Ansatz habe ich vmtl. eine Klammer vergessen:

Code:
#stat_Verz_StandBy.VAR_IN:=

((#inout_Bereich_Ende or (
not #stat_Regler.ProgPos.Steuerwort."2_Bit_00_M090_PLC_Kanal_0" 
and not #stat_Regler.ProgPos.Steuerwort."2_Bit_01_M091_PLC_Kanal_1"
and not #stat_Regler.ProgPos.Steuerwort."2_Bit_02_M092_PLC_Kanal_2"
and not #stat_Regler.ProgPos.Steuerwort."2_Bit_03_M093_PLC_Kanal_3"
and not #stat_Regler.ProgPos.Steuerwort."2_Bit_04_M094_PLC_Kanal_4"
and not #stat_Regler.ProgPos.Steuerwort."2_Bit_05_M095_PLC_Kanal_5"
))
and #in_Standby_erlauben
or #in_Halt_Vorschub)
and not #in_Tippen_plus
and not #in_Tippen_minus
and not #in_Referenzfahrt_starten
and #stat_Regler.ProgPos.Statuswort."1_Bit_01_Einschaltbereit"
;

Ich werde das aber wohl heute abend mal im Twincat-Simulator durchspielen.
 
// Auszug in AWL

U #inout_Bereich_Ende
O(
UN #stat_Regler.ProgPos.Steuerwort."2_Bit_00_M090_PLC_Kanal_0"
UN #stat_Regler.ProgPos.Steuerwort."2_Bit_01_M091_PLC_Kanal_1"
UN #stat_Regler.ProgPos.Steuerwort."2_Bit_02_M092_PLC_Kanal_2"
UN #stat_Regler.ProgPos.Steuerwort."2_Bit_03_M093_PLC_Kanal_3"
UN #stat_Regler.ProgPos.Steuerwort."2_Bit_04_M094_PLC_Kanal_4"
UN #stat_Regler.ProgPos.Steuerwort."2_Bit_05_M095_PLC_Kanal_5"
)
U #in_Standby_erlauben
O #in_Halt_Vorschub
UN #in_Tippen_plus
UN #in_Tippen_minus
UN #in_Referenzfahrt_starten
U #stat_Regler.ProgPos.Statuswort."1_Bit_01_Einschaltbereit"
= #stat_Verz_StandBy.VAR_IN

// Auszug in SCL

#stat_Verz_StandBy.VAR_IN := (
(#stat_Regler.ProgPos.Statuswort."1_Bit_01_Einschaltbereit" AND
NOT #in_Referenzfahrt_starten AND
NOT #in_Tippen_minus AND
NOT #in_Tippen_plus) AND
#in_Halt_Vorschub OR
#in_Standby_erlauben AND
((NOT #stat_Regler.ProgPos.Steuerwort."2_Bit_00_M090_PLC_Kanal_0"
AND NOT #stat_Regler.ProgPos.Steuerwort."2_Bit_01_M091_PLC_Kanal_1"
AND NOT #stat_Regler.ProgPos.Steuerwort."2_Bit_02_M092_PLC_Kanal_2"
AND NOT #stat_Regler.ProgPos.Steuerwort."2_Bit_03_M093_PLC_Kanal_3"
AND NOT #stat_Regler.ProgPos.Steuerwort."2_Bit_04_M094_PLC_Kanal_4"
AND NOT #stat_Regler.ProgPos.Steuerwort."2_Bit_05_M095_PLC_Kanal_5")
OR #inout_Bereich_Ende));

Sorry, aber warum man solchen AWL-Code schreibt verstehe ich nicht. In FUP oder KOP lässt er sich nicht übersetzen.


Fpr die SCL-Variante:
Ich habe mir angewohnt die "Smart" Codeformatierung von S7 bzw. TIA-Portal abzuschalten und formatiere manuell, so das es hierarchisch lesbar wird. Der obige Code sieht dann halt so aus:

Code:
#stat_Verz_StandBy.VAR_IN := 
        (
[COLOR=#ff0000]            ([/COLOR]
                (
                    #stat_Regler.ProgPos.Statuswort."1_Bit_01_Einschaltbereit" 
                    AND (NOT #in_Referenzfahrt_starten) 
                    AND (NOT #in_Tippen_minus) 
                    AND (NOT #in_Tippen_plus)
                ) 
                AND #in_Halt_Vorschub 
            [COLOR=#ff0000])[/COLOR]
            OR [COLOR=#ff0000]([/COLOR]
                #in_Standby_erlauben 
                AND (
                    (
                        (NOT #stat_Regler.ProgPos.Steuerwort."2_Bit_00_M090_PLC_Kanal_0")
                        AND (NOT #stat_Regler.ProgPos.Steuerwort."2_Bit_01_M091_PLC_Kanal_1")
                        AND (NOT #stat_Regler.ProgPos.Steuerwort."2_Bit_02_M092_PLC_Kanal_2")
                        AND (NOT #stat_Regler.ProgPos.Steuerwort."2_Bit_03_M093_PLC_Kanal_3")
                        AND (NOT #stat_Regler.ProgPos.Steuerwort."2_Bit_04_M094_PLC_Kanal_4")
                        AND (NOT #stat_Regler.ProgPos.Steuerwort."2_Bit_05_M095_PLC_Kanal_5")
                    )
                    OR #inout_Bereich_Ende
                )
        [COLOR=#ff0000]    )[/COLOR]
        );

Die wesentlichen Merkmale sind das hierarchische Einrücken, das bedingungslose Klammern - so muss man nicht nachdenken ob OR oder AND stärker bindet. Zudem wird jedes NOT immer zum Operanden geklammert. Von der Logik her sieht es nun auch so ähnlich wie FUP aus.
Ach ja: die roten Klammern hab ich dazugefügt.

lg
 
Zurück
Oben