TIA TIA SCL-Code vereinfachen ?

Beiträge
2.630
Reaktionspunkte
766
Zuviel Werbung?
-> Hier kostenlos registrieren
Servus..

ich bin jetzt dabei mir die SCL Sprache mit die Methode "learning by doing" rein zu ziehen.
Als unterlagen das Berger, Johannes Hofer Buch und natürlich das SPS-Forum.
Durch das der SCL Editor im TIA recht Anfänger freundlich ist komme ich ganz gut voran.

Doch kommt die mir die frage auf ob solche (Einfache) Code noch zu vereinfachen ist.

Code:
 // Alarm High High
IF NOT #HH_Activ THEN
    #HH_AL_Intern := false;
    GOTO Jump_HH;
    ;
END_IF;
IF #AV_intern >= #Limit_HH THEN
    #Running_Time_HH_Help_M := TRUE;
ELSE
    #Running_Time_HH_Help_M := false;
    ;
END_IF;
#TIMER_HH(IN := #Running_Time_HH_Help_M,
         PT := #Delay_HH);
IF #TIMER_HH.Q = true THEN
    #HH_AL_Intern := true;
ELSIF (#ACK AND #Extern_ACK_Activ) OR ((#AV_intern < (#Limit_HH - #HYSTERYSE_HH) AND NOT #Extern_ACK_Activ))
THEN
    #HH_AL_Intern := false;
    ;
END_IF;
Jump_HH:


// Analog
#LL_LIM_OUT := #Limit_LL;
#Comm_ZLT.Limit_LL := #Limit_LL;


//Alarm and BIT OUT and STATE
IF #LL_AL_Intern THEN
    #LL_ALARM_OUT := true;
    #STATE_HMI.LL_ALARM_OUT := true;
    #Comm_ZLT.STATE.LL_ALARM_OUT := true;
ELSE
    #LL_ALARM_OUT := false;
    #STATE_HMI.LL_ALARM_OUT := false;
    #Comm_ZLT.STATE.LL_ALARM_OUT := false;
    ;
END_IF;

z.b.
Beim teil //Alarm High High, habe ich versucht die IF-Struktur zu verschachteln. Test haben gezeigt das diese Code dann nicht funktioniert. ist das die kürzte Methode ? Den Flipflop die ich drinnen hab geht auch bestimmt anders.

Beim Teil //Analog will ich das #Limit_LL auf diverse andere stellen schreiben. Mus ich das #Limit_Ll dann bei jede Zuweisung abfragen oder geht das auch das mann nur 1 ml abfragt und dann auf die andere stellen schreibt.

Beim Teil //Alarm and BIT OUT and STATE will ich das Bit #LL_AL_Intern auch weiter rangieren.
Muss man da so vorgehen wie ich gemacht hab ? (in der AWL komm ich mit 4 Zeilen zurecht)

ich bin gespannt auf euer Bemerkungen.

Bram
 
Zuletzt bearbeitet:
Hallo Bram,

so notwendig GOTO auch in AWL ist, so sehr versucht man es in Hochsprahcen zu vermeiden.
Arbeite lieber mit IF/ELSE oder anderen Konstrukten. GOTO macht Code unübersichtlich und man findet Fehler auch nicht so schnell.

Was meinst Du mit
Beim teil //Alarm High High, habe ich versucht die IF-Struktur zu verschachteln.

Beim Teil //Analog will ich das #Limit_LL auf diverse andere stellen schreiben. Mus ich das #Limit_Ll dann bei jede Zuweisung abfragen oder geht das auch das mann nur 1 ml abfragt und dann auf die andere stellen schreibt.
Ich denke, das geht nur so...

Beim Teil //Alarm and BIT OUT and STATE will ich das Bit #LL_AL_Intern auch weiter rangieren.
Muss man da so vorgehen wie ich gemacht hab ? (in der AWL komm ich mit 4 Zeilen zurecht)
Du kannst Dir theoretisch das IF sparen und den Wert #LL_AL_Intern direkt an die Variablen zuweisen. Wenn Du nichts Komplizierteres machen möchtest, wäre das ein 3zeiler.

Doch kommt die mir die frage auf ob solche (Einfache) Code noch zu vereinfachen ist.
Code vereinfachen heißt dann nicht unbedingt, daß er leserlicher wird. Da wir aus den Zeiten der notwendigen Codeoptimierungen ziemlich raus sind, schreibe ich oft eher eine Zeile mehr, wenn der Code dadurch verständlicher wird.
Theoretisch könntest Du Dir in diesem Fall das
Code:
IF #AV_intern >= #Limit_HH THEN
    #Running_Time_HH_Help_M := TRUE;
ELSE
    #Running_Time_HH_Help_M := false;
    ;
END_IF;
sparen und die Bedingung in Klammern direkt an den Timereingang schreiben, da Du mit der Hilfsvariablen sonst nichts weiter machst.

Gruß
JS
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Danke JS,

Du kannst Dir theoretisch das IF sparen und den Wert #LL_AL_Intern direkt an die Variablen zuweisen. Wenn Du nichts Komplizierteres machen möchtest, wäre das ein 3zeiler.
Und
Code vereinfachen heißt dann nicht unbedingt, daß er leserlicher wird. Da wir aus den Zeiten der notwendigen Codeoptimierungen ziemlich raus sind, schreibe ich oft eher eine Zeile mehr, wenn der Code dadurch verständlicher wird.
Theoretisch könntest Du Dir in diesem Fall das
Code:
IF #AV_intern >= #Limit_HH THEN
#Running_Time_HH_Help_M := TRUE;
ELSE
#Running_Time_HH_Help_M := false;
;
END_IF;
sparen und die Bedingung in Klammern direkt an den Timereingang schreiben, da Du mit der Hilfsvariablen sonst nichts weiter machst

hab ich so umgesetzt nach die Vorschlag.:D

Das sind jetzt die Denkanstöße die Mann braucht.

Beim teil //Alarm High High, habe ich versucht die IF-Struktur zu verschachteln.
Da hab ich es einfach mal probiert, mit dem ziel die Code die zusammen gehört, zusammen in ein IF zu machen.

Wie springe ich im Hochsprache über stücke Programme wenn "GOTO" vermieden werden soll ?
,, Schaue es mir über IF-Else an so wie du sagst..

Bram
 
Zuletzt bearbeitet:
Wie springe ich im Hochsprache über stücke Programme wenn "GOTO" vermieden werden soll ?

Indem Du sie in einen IF oder ELSE-Zweig setzt:
Code:
 // Alarm High High
IF NOT #HH_Activ THEN
    #HH_AL_Intern := false;
ELSE
   IF #AV_intern >= #Limit_HH THEN
       #Running_Time_HH_Help_M := TRUE;
   ELSE
       #Running_Time_HH_Help_M := false;
       ;
   END_IF;
   #TIMER_HH(IN := #Running_Time_HH_Help_M,
            PT := #Delay_HH);
   IF #TIMER_HH.Q = true THEN
       #HH_AL_Intern := true;
   ELSIF (#ACK AND #Extern_ACK_Activ) OR ((#AV_intern < (#Limit_HH - #HYSTERYSE_HH) AND NOT #Extern_ACK_Activ))
   THEN
       #HH_AL_Intern := false;
       ;
   END_IF;
END_IF;
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Bram,

Solche Konstruktionen
Code:
IF #LL_AL_Intern THEN
    #LL_ALARM_OUT := true;
    #STATE_HMI.LL_ALARM_OUT := true;
    #Comm_ZLT.STATE.LL_ALARM_OUT := true;
ELSE
    #LL_ALARM_OUT := false;
    #STATE_HMI.LL_ALARM_OUT := false;
    #Comm_ZLT.STATE.LL_ALARM_OUT := false;
    ;
END_IF;

kannst du vereinfachen
Code:
#LL_ALARM_OUT := #LL_AL_Intern;
#STATE_HMI.LL_ALARM_OUT := #LL_AL_Intern;
#Comm_ZLT.STATE.LL_ALARM_OUT := #LL_AL_Intern;

Gruß
Dieter
 
Statt
Code:
   IF #AV_intern >= #Limit_HH THEN
       #Running_Time_HH_Help_M := TRUE;
   ELSE
       #Running_Time_HH_Help_M := false;
       ;
   END_IF;

sollte doch auch

Code:
#Running_Time_HH_Help_M := #AV_intern >= #Limit_HH;

funktionieren.

Wäre aber Geschmackssache.
 
Ja, ich hab gemeint immer in Else verwenden zu müssen.

Im Prinzip entspricht "IF ... THEN ... END_IF" einem Setze- oder Rücksetze-Befehl in KOP/FUP/AWL.
Ein "IF ... THEN ... ELSE ... END_IF" ist eine Zuweisung(=).
Ein "IF ... THEN ... ELSIF ... END_IF" ist ein S/R.

Gruß
Dieter
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Aber eine zweiteilige mit Sprungbefehlen sowie SET und Clear.

Eine reine Zuweisung wäre in meinen Augen das, was MasterOhh gepostet hat.

Eines der "Probleme" mit SCL ist, dass manche Programmierer alles mit IF-THEN erschlagen wollen.
Da werden selbst einfache binäre Verknüpfungen zu wahren Orgien von verschachtelten IF-THEN-Ausdrücken.

Wenn man in AWL schreibt
Code:
U E1.0
S M1.0
UN E1.0
R M1.0

sagt jeder, dass das unschön ist und eine simple Zuweisung
Code:
U E1.0
= M1.0
richtiger ist

In SCL findest du aber jede Menge
Code:
IF E1.0 THEN
  M1.0 := TRUE;
ELSE
  M1.0 := FALSE;
END_IF;

obwohl hier genauso
Code:
M1.0 := E1.0;
die bessere Wahl wäre.

Gruß
Dieter
 
*ACK*

Du nimmst mir die Worte aus dem Mund, was ich aber vorhin am Handy nicht so ausführlich schreiben konnte.
 
Eines der "Probleme" mit SCL ist, dass manche Programmierer alles mit IF-THEN erschlagen wollen.
Da werden selbst einfache binäre Verknüpfungen zu wahren Orgien von verschachtelten IF-THEN-Ausdrücken.

Wollen nicht unbedingt.
Hab gedenkt es muss so.

Hellebarde hat es ein paar Treads her auch so geschrieben.

Ziel ist schon einen saubere, übersichtliche schnelle SCl Code schreiben zu können.
Und dabei fange ich unten an...



xxxxxxxxxxxxxxxxxxxxxxx

So, der SCL Baustein ist fertig.
Im vergleich zu seine AWL (Zykluszeitoptimierte Version) Vorlage ist er auch 5 bis 10% schneller :smile:

Bram
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Wollen nicht unbedingt.
Hab gedenkt es muss so.

Hellebarde hat es ein paar Treads her auch so geschrieben.

Ziel ist schon einen saubere, übersichtliche schnelle SCl Code schreiben zu können.
Und dabei fange ich unten an...



xxxxxxxxxxxxxxxxxxxxxxx

So, der SCL Baustein ist fertig.
Im vergleich zu seine AWL (Zykluszeitoptimierte Version) Vorlage ist er auch 5 bis 10% schneller :smile:

Bram

Hallo

da kann ich mir ja gleich zwei grinsen.

Erstens, dass diese unnötigen IF ... THEN ... := true ELSE ... := false verschwinden
und zweitens, dass SCL schneller geworden ist wie die Zykluszeitoptimierte AWL-Version


'n schön' Tach auch
HB
 
Wenn man vernünftigen SCL-Code schreibt, dann erzeugt der Compiler auch schnellen Code.
Löst man die Aufgabe selber in AWL, dann ist geschwindigkeitsoptimierter Code oft unübersichtlich.

Gruß
Dieter
 
Mahlzeit.
Hab mich grad wegen dieser Diskusion angemeldet, da ich selber eine Frage diesbezüglich habe und jeden tag ins Forum schaue um neue Ideen zu sammeln.
Wie würdet ihr das Vorzeichen einer Real variable in SCL entfernen? Ich hab das Bisher so gemacht
Code:
 #T_POS_RE_DIF := DWORD_TO_REAL(DW#16#7FFFFFFF And REAL_TO_DWORD(#IO_AKT_PRG[1].WKZ_H - #IO_AKT_PRG[2].WKZ_H));
was absolut nicht schön ist, so mach ich das normaler weise auch in AWL.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
mahlzeit.
Hab mich grad wegen dieser diskusion angemeldet, da ich selber eine frage diesbezüglich habe und jeden tag ins forum schaue um neue ideen zu sammeln.
Wie würdet ihr das vorzeichen einer real variable in scl entfernen? Ich hab das bisher so gemacht
Code:
 #t_pos_re_dif := dword_to_real(dw#16#7fffffff and real_to_dword(#io_akt_prg[1].wkz_h - #io_akt_prg[2].wkz_h));
was absolut nicht schön ist, so mach ich das normaler weise auch in awl.

Code:
#t_pos_re_dif := ABS(#io_akt_prg[1].wkz_h - #io_akt_prg[2].wkz_h);
 
Mahlzeit.
Hab mich grad wegen dieser Diskusion angemeldet, da ich selber eine Frage diesbezüglich habe und jeden tag ins Forum schaue um neue Ideen zu sammeln.
Wie würdet ihr das Vorzeichen einer Real variable in SCL entfernen? Ich hab das Bisher so gemacht
Code:
 #T_POS_RE_DIF := DWORD_TO_REAL(DW#16#7FFFFFFF And REAL_TO_DWORD(#IO_AKT_PRG[1].WKZ_H - #IO_AKT_PRG[2].WKZ_H));
was absolut nicht schön ist, so mach ich das normaler weise auch in AWL.

Solche Converter Funktionen würde ich auch einsetzen, und es wird immer andere und bessere wegen geben denke ich.


Wie mehr ich jetzt mit der SCL mache, wie mehr ich mir abfrage warum ich mich nicht früher damit auseinander gesetzt hab.
hab jetzt echt so etwas von " Ich mache nie wieder AWL"
Es macht echt spaß.

Bram
 
Wie mehr ich jetzt mit der SCL mache, wie mehr ich mir abfrage warum ich mich nicht früher damit auseinander gesetzt hab.
hab jetzt echt so etwas von " Ich mache nie wieder AWL"
Es macht echt spaß.

Bram

Schau dir die Sichten / Views (Deklaration mit AT) an.
Das macht dann richtig Spass!

Gruß
Dieter
 
Zurück
Oben