SR in SCL

oliversps

Level-2
Beiträge
112
Reaktionspunkte
13
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,
ich bin gerade dabei die Programmiersprache SCL (im TIA Portal) zu erlernen.

Meine Frage:
Wenn ich einen SR Baustein (aus der Sprache FUP) als SCL Code realisieren möchte, wäre dann folgender Beispielcode korrekt?

// Ausgang setzen
IF ("Eingang 1" OR "Eingang 2") AND ("Eingang 3" AND NOT "not aus")
THEN "Ausgang 1" := TRUE;
// Ausgang rücksetzen
ELSIF NOT "Eingang 3" OR "not aus"
THEN "Ausgang 1" := FALSE;
END_IF;

Ich bin gespannt auf eure Antworten und offen für Alternativen.

LG Olli
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
#PN/DP
Also Ausgang (Q) setzen wenn (Ausgang (Q) bereits gesetzt oder Startbedingung (S) erfüllt) und Rücksetzbedingung (R1) nicht erfüllt.
Habe ich das richtig verstanden?
 
Also Ausgang (Q) setzen wenn (Ausgang (Q) bereits gesetzt oder Startbedingung (S) erfüllt) und Rücksetzbedingung (R1) nicht erfüllt.
Habe ich das richtig verstanden?
Ja, so funktioniert der FUP-SR
für "S" formulierst du deine Setzbedingungen und für "R1" formulierst du die Rücksetzbedingungen, also z.B.:
Code:
Q := (Q OR (Eingang_1 OR Eingang_2)) AND NOT (NOT(Eingang_3) OR not_aus);

PS: SCL ist für logische Verknüpfungen nicht die beste Programmiersprache und verleitet zu schnell getippseltem umständlichen (und oft unvollständigem) Code.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Und da wundert man sich warum so viele Schwierigkeiten mit SCL haben...

Jetzt mal kurz überlegt: Ihr habt ein Programm und dann die Zeile

Q := (Q OR S) AND NOT R1;

Wer erkennt da denn da direkt ein SR-Glied???

Da ist es doch für jemanden der von FUP/KOP kommt folgendes deutlich einfacher und übersichtlicher:

Code:
IF S1 THEN
    Q := true;
ELSIF R THEN
    Q := false;
END_IF;


IF R1 THEN
    Q := false;
ELSIF S THEN
    Q := true;
END_IF;
 
Q := (Q OR S) AND NOT R1;

Wer erkennt da denn da direkt ein SR-Glied???
Wenn man in SCL programmiert, muss man da erkennen, dass der Code in einer anderen Programmiersprache ein SR-Glied wäre?

Da ist es doch für jemanden der von FUP/KOP kommt folgendes deutlich einfacher und übersichtlicher:

Code:
IF S1 THEN
    Q := true;
ELSIF R THEN
    Q := false;
END_IF;


IF R1 THEN
    Q := false;
ELSIF S THEN
    Q := true;
END_IF;
... und eine schöne Falle, weil man da nicht sieht, dass Q nicht TEMP und nicht OUT sein darf bzw. für diese Fälle noch zusätzlichen Code benötigt, falls weder S noch R true sind :cool:
(wie bereits erwähnt, ist schnell getippselter SCL-Code oft unvollständig)
 

siehe folgende Diskussionen:

 
Da bin ich zwiegespalten.
Ich finde z.b.
Code:
IF
    Temp1 >= (setpoint - difference) AND
    Temp1 <= (setpoint + difference) AND
    NOT errorTempSensor
THEN
    Temp := True;
ELSE
    Temp := False;
END_IF

Überzogen.

Ich würde das eher so machen:
Code:
Temp := (Temp1 >= setpoint - difference) AND
        (Temp1 <= Setpoint + difference) AND NOT
         errorTempSensor;

Aber da ich mehr im Service als im programmieren unterwegs bin, pass ich mich da an das vom Ersteller an...
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich behaupte die SR Funktion in SCL verstanden zu haben. Um das zu überprüfen lege ich noch mal eine Schüppe drauf. Habe nun eine Beispielanwendung, die zusätzlich eine Ein- und Ausschaltverzögerung beinhaltet. Zur Veranschaulichung in FUP und SCL nach meinem bisherigen Verständnis programmiert.

Würde mich interessieren ob das so korrekt geschrieben/programmiert ist.

Zeitbausteine FUP und SCL mit SR Funktion.png
 
Es wird wahrscheinlich identisch funktionieren - ist aber in der Code-Umsetzung nicht identisch.
Wichtig zu beachten ist in jedem Fall : deine Hilfs-Variablen müssen Merker oder STAT-Variablen sein - mit TEMP-Variablen würde es nicht funktionieren ...
 
In Deinem Code muß Q auch ein STAT sein... wie soll sonst (Q OR S) funktionieren?
(Q OR S) funktioniert bzw. "geht" auch, wenn Q ein TEMP ist (und Q vorher was sinnvolles zugewiesen wurde) - das wird aber meist ein Programmierfehler oder sehr schlechter Programmierstil sein, der aber nicht angemeckert wird

klär mich auf....
in den IF_THEN-Varianten wird gerne übersehen, dass Q nicht OUT sein darf
oder sie sind direkt falsch implementiert, wie die zwei Varianten von @NBerger mit den ELSIF - so funktioniert ein SR-Glied aber nicht
Code:
IF S1 THEN
    Q := true;
ELSIF R THEN
    Q := false;
END_IF;

(...)

Wie man Logik in SCL programmiert kann man endlos diskutieren ... es gibt keine vorgeschriebene oder richtige oder falsche Variante
 
Zuviel Werbung?
-> Hier kostenlos registrieren
(Q OR S) funktioniert bzw. "geht" auch, wenn Q ein TEMP ist (und Q vorher was sinnvolles zugewiesen wurde) - das wird aber meist ein Programmierfehler oder sehr schlechter Programmierstil sein, der aber nicht angemeckert wird


in den IF_THEN-Varianten wird gerne übersehen, dass Q nicht OUT sein darf
oder sie sind direkt falsch implementiert, wie die zwei Varianten von @NBerger mit den ELSIF - so funktioniert ein SR-Glied aber nicht


Wie man Logik in SCL programmiert kann man endlos diskutieren ... es gibt keine vorgeschriebene oder richtige oder falsche Variante
Ich glaube, bei den 1200 und 1500-er SPS funktiniert das vieleicht nicht mehr. An jedem Bausteinanfang werden den Temp defaultmäßig False und 0 etc. zugewiesen (jedenfalls lt. Siemens), das ist neu gegenüber den 300-er SPS. Und auch bei den 300-er funktioniert das nur zufällig, wie ich aus leidvoller Erfahrung sagen kann, denn dort liegen die Temp auf dem Stack und werden nicht initialisiert. Wenn also kein anderer Baustein Daten auf den Stack ablegt und ihn damit verändert geht das, andernfalls können diese Temp beliebige Werte annehmen. Also in keinem Fall sollte eine Selbsthaltung zuverlässig funktionieren.
 
Also in keinem Fall sollte eine Selbsthaltung zuverlässig funktionieren.
Mit IF..THEN auch nicht :cool: (ganz davon abgesehen, ob SR in TEMP überhaupt einen Sinn macht)
Bei Selbsthaltung wird aber wenigstens gewarnt, wenn Q in OUT liegt (TIA V16: "Der Parameter '#Q' wird möglicherweise nicht initialisiert")
Bei IF..THEN geht das völlig ohne Warnung durch (vielleicht bei FC?? nicht getestet).

Ich weiß, effizientes Programmieren ist bei S7-1x00 ja nicht mehr nötig ;) trotzdem hier mal eine Gegenüberstellung der vom SCL-Compiler erzeugten Codegrößen bei einem FB:
Code:
Codegröße FB, TIA V16 (mit/ohne IEC-Prüfung ist egal)
          S7-1200     S7-1500
         opt  Std    opt  Std   opt "optimiert" / Std "Standard"
2x IF  :  42   41    112  105
ELSIF  :  44   43    114  107
Selbsth:  34   33    102   97   Warnung, wenn Q in OUT

Der verwendete Code (FB):
Code:
//*** 2x IF
IF #S THEN
    #Q := TRUE;
END_IF;
IF #R1 THEN
    #Q := FALSE;
END_IF;

//*** ELSIF
IF #R1 THEN
    #Q := FALSE;
ELSIF #S THEN
    #Q := TRUE;
END_IF;

//*** Selbsthaltung
#Q := (#Q OR #S) AND NOT #R1;
 
#PN/DP
Ach jau, bei der IF THEN ELSIF Anweisung einfach die Resetbedingung zuerst.
Jetzt fällt es mir wie Schuppen von den Augen.
 
Mit IF..THEN auch nicht :cool: (ganz davon abgesehen, ob SR in TEMP überhaupt einen Sinn macht)
Bei Selbsthaltung wird aber wenigstens gewarnt, wenn Q in OUT liegt (TIA V16: "Der Parameter '#Q' wird möglicherweise nicht initialisiert")
Bei IF..THEN geht das völlig ohne Warnung durch (vielleicht bei FC?? nicht getestet).

Ich weiß, effizientes Programmieren ist bei S7-1x00 ja nicht mehr nötig ;) trotzdem hier mal eine Gegenüberstellung der vom SCL-Compiler erzeugten Codegrößen bei einem FB:
Code:
Codegröße FB, TIA V16 (mit/ohne IEC-Prüfung ist egal)
          S7-1200     S7-1500
         opt  Std    opt  Std   opt "optimiert" / Std "Standard"
2x IF  :  42   41    112  105
ELSIF  :  44   43    114  107
Selbsth:  34   33    102   97   Warnung, wenn Q in OUT

Der verwendete Code (FB):
Code:
//*** 2x IF
IF #S THEN
    #Q := TRUE;
END_IF;
IF #R1 THEN
    #Q := FALSE;
END_IF;

//*** ELSIF
IF #R1 THEN
    #Q := FALSE;
ELSIF #S THEN
    #Q := TRUE;
END_IF;

//*** Selbsthaltung
#Q := (#Q OR #S) AND NOT #R1;
Na ja ...
if then else selbstredend mit statischen Variablen.
Aber ich muß zugeben, temp nutze ich seit Jahren nur noch für ganz einfache Zwischenrgebnisse etc. Wann immer es geht nehme ich statVar, die kann man zumindest im IDB jederzeit anschauen oder wenn nötig tracen. Na ja und tatsächlich achte ich nur noch wenn unbedingt nötig auf wirklich effizientes Programmieren, wichtiger ist, dass jeder sehen und erkennen kann, was man machen wollte.

PS: Wenn Schrittketten mit Graph programmiert werden, dann ist es mit der Effizienz ohnehin nicht mehr so weit, da ist ja auch unendlich viel Overhead drin.
 
Da bin ich zwiegespalten.
Ich finde z.b.
Code:
IF
    Temp1 >= (setpoint - difference) AND
    Temp1 <= (setpoint + difference) AND
    NOT errorTempSensor
THEN
    Temp := True;
ELSE
    Temp := False;
END_IF

Überzogen.

Ich würde das eher so machen:
Code:
Temp := (Temp1 >= setpoint - difference) AND
        (Temp1 <= Setpoint + difference) AND NOT
         errorTempSensor;

Aber da ich mehr im Service als im programmieren unterwegs bin, pass ich mich da an das vom Ersteller an...
Dein Beispiel ist aber kein SR sondern eine einfache logische Verknüpfung, und da wäre ein IF THEN ELSE auf jeden Fall Käse.

Wenn Du irgendwas je nach Temperatur einschalten willst, musst Du zwingend ne Hysterese haben und brauchst ein Setze/Rücksetze. Dann sieht der Code aber anders aus als bei Dir. Wenn an Deinem Temp nen Schütz für ne Heizung hängt, wird das nicht lange überleben...

Ist quasi der Klassiker für ein notwendiges SR:
Code:
IF
    Temperatur >= (setpoint + difference) OR
    errorTempSensor
THEN
    Heizung := False;
ELSIF
    Temperatur <= (setpoint - difference) 
THEN
    Heizung := True;
END_IF
 
Zuletzt bearbeitet:
Zurück
Oben