TIA SCL sauber/ strukturiert programmieren

Zuviel Werbung?
-> Hier kostenlos registrieren
Wie unterteilt Ihr das ..

Handfunktionen, Automatik, Übergabe der Ausgänge, HMI, Schnittstellenhandling

Handfunktionen, Automatik sind bei mir nach wie vor in KOP / FUP.
Logische Verknüpfungen sind einfach damit übersichtlicher.

Mittlerweile kann man in TIA auch SCL in KOP/FUP-Bausteinen nutzen.
Davon mache ich in der Zwischenzeit sehr häufig Gebrauch.
Eben wie früher mit den AWL-Netzwerken.

Für jede Aufgabe eben das richtige Werkzeug ;)

Gruß
Blockmove
 
Regions haben einem das Leben wirklich einfacher gemacht. Ich hab früher immer Kommentarbalken über die gesamte Zeilenbreite gemacht wenn ich einen "Abschnitt" vom nächsten trennen wollte. Heute mache ich nur noch ne Überschrift und eine Region außendrum.
Hilfreich sind sie besonderns (finde ich) wenn man die Stelle gefunden hat an der man eine Änderung vornehmen müsste, dies aber in der Onlinesicht getan hat. Gibt man das erste Zeichen ein, schnurrt alles zusammen und man findet sich gar nicht mehr zurecht. Vor allem da Scrollen im SCL Code mit dem Trackpad ebenfalls nicht so der Bringer ist.

Wenn man dann weiß in welcher Region man war, kann man wenigstens wieder an den Anfang gehen und dann mit den Pfeiltasten Zeile um Zeile durchgehen.
Ich finde die Regions auch großartig und schade, wenn ein Programmierer sie in größeren SCL-Bausteinen nicht verwendet. Erinnert an AWL-Schrittketten in einem einzigen Netzwerk mit 1000+ Zeilen... :rolleyes:

Ebenfalls finde ich die Integration von SCL-Netzwerken in KOP- und FUP-Bausteine (inkl. online Beobachten) sehr gelungen. Das nutze ich häufig für Berechnungen, für die sich m. E. kein eigener FC lohnt. Die Formel der Berechnung kommt häufig von den Kollegen aus der Verfahrenstechnik, diese versuche ich dann im Kommentar auch so wie in der Anlagen-Doku darzustellen. Falls dann mal ein Kollege mit Schwierigkeiten bei diesen Berechnungen an die Anlage muss, hat er damit denke ich bessere Chancen, dennoch erfolgreich zu sein.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Moin,

ja, Regions helfen bei der Programmstrukturierung.
Ich finde mich in Jespers Ausführungen wieder: KOP und SCL!

Das Argument, dass man in AWL ja jede Anweisung schön untereinander hatte (erzwungenermaßen) und das in SCL nicht mehr so ist, kann ich nicht stehen lassen.
Auch in SCL kann ich eine Befehlszeile einfach in mehrere Zeilen Aufteilen. Bei einer Zuweisung steht das Ergebnis halt nicht mehr unten, sondern oben:

Code:
#Produkt :=
#Multiplikator *
#Multiplikant;

oder

Code:
#Summe :=
#Summand1 +
#Summand2 +
#Summand3 +
#Summand4;

oder

Code:
#Ergebnis :=
#Bedingung1 AND
#Bedingung2 OR
#Bedingung3;

VG

MFreiberger
 
Ich mache logische Verknüpfungen in SCL immer so, dass pro Zeile nur eine Bedingung steht.

Wenn man sich das dann Online anschaut, muss man nicht auf die Pfeile zum ausklappen drücken sndern kann gleich sehen welche Bedingung fehlt.

Braucht halt etwas Platz, aber ich spare bei der Fehlersuche etwas Zeit.
In KOP geht es natürlich noch einfacher, aber nur wegen einer einzigen Verknüpfung mit 5 bis 6 Stellen nen KOP Baustein dann mit lauter SCL Netzwerken vollzuhauen finde ich grotesk.
 
In KOP geht es natürlich noch einfacher, aber nur wegen einer einzigen Verknüpfung mit 5 bis 6 Stellen nen KOP Baustein dann mit lauter SCL Netzwerken vollzuhauen finde ich grotesk.

Wegen einer Verknüpfung mache ich auch keinen KOP / FUP Baustein.
Schönes Beispiel ist für mich das Handling von NC-Antrieben.
Startbedingungen, Freigaben und Betriebsmodi mach ich in FUP.
Berechnung von Verfahrpositionen, Geschwindigkeiten, usw. erfolgt in SCL.
In der Summe ergibt das - meines Erachtens - einen sauber strukturierten und übersictlichen Baustein

Gruß
Blockmove
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

ich weiß nicht ob das hier her gehört wenn nicht bitte löschen!

Beschäftige mich gerade mit OSCAT und zwar mit Baustein HEAT_TEMP.

Das Problem was ich habe ist das ich den Baustein nicht Aktiviren bzw., deaktiviren kann.
Nach dem deaktiviren bleiben die Werte eingefroren sollte aber bei mir "0" sein.

Jetzt habe ich selber im SCL rum gepfuscht. Funktion ist gegeben aber ist das so sauber?

Danke grüße


Code:
VERSION : '1.2'
AUTHOR  : hugo
NAME    : HEAT_TMP
FAMILY  : HLK

VAR_INPUT
    EIN_AUS : BOOL;
    T_EXT : REAL;
    T_INT : REAL;
    OFFSET : REAL;
    T_REQ : REAL;
END_VAR
VAR_INPUT
    TY_MAX : REAL := 70.0;
    TY_MIN : REAL := 25.0;
    TY_CONFIG : REAL := 70.0;
    T_INT_CONFIG : REAL := 20.0;
    T_EXT_CONFIG : REAL := -15.0;
    T_DIFF : REAL := 10.0;
    C : REAL := 1.33;
    H : REAL := 3.0;
END_VAR
VAR_OUTPUT
    TY : REAL;
    HEAT : BOOL;
END_VAR
VAR
    tr : REAL;
    tx: REAL;
END_VAR

BEGIN


tr := T_INT + OFFSET;
tx := (tr - T_EXT) / (T_INT_CONFIG - T_EXT_CONFIG);

IF EIN_AUS =0 THEN 
    TY :=0;
    HEAT :=0;
END_IF;    
  IF EIN_AUS =1 THEN
   
  
    IF T_EXT + H > tr THEN
       TY := 0.0;
    ELSE
       TY := LIMIT(MN:=TY_MIN,IN:=tr + T_DIFF * 0.5 * tx + (TY_CONFIG - T_DIFF * 0.5 - tr) * (tx**(1.0 / C)),MX:=TY_MAX);
    END_IF;

TY := MAX(IN1:=TY, IN2:=T_REQ);
HEAT := TY > 0.0;

  END_IF;
 
Hallo,
so richtig schlüssig bin ich auch nicht, ob das hier hingehört - ich lasse es aber erstmal hier (ein ganz bißchen passt es ja ;))
Ich würde den Code geringfügig abändern (das ist aber nur kosmetisch) :
Code:
VERSION : '1.2'
AUTHOR  : hugo
NAME    : HEAT_TMP
FAMILY  : HLK

VAR_INPUT
    EIN_AUS : BOOL;
    T_EXT : REAL;
    T_INT : REAL;
    OFFSET : REAL;
    T_REQ : REAL;
END_VAR
VAR_INPUT
    TY_MAX : REAL := 70.0;
    TY_MIN : REAL := 25.0;
    TY_CONFIG : REAL := 70.0;
    T_INT_CONFIG : REAL := 20.0;
    T_EXT_CONFIG : REAL := -15.0;
    T_DIFF : REAL := 10.0;
    C : REAL := 1.33;
    H : REAL := 3.0;
END_VAR
VAR_OUTPUT
    TY : REAL;
    HEAT : BOOL;
END_VAR
VAR
    tr : REAL;
    tx: REAL;
END_VAR

BEGIN


tr := T_INT + OFFSET;
tx := (tr - T_EXT) / (T_INT_CONFIG - T_EXT_CONFIG);

IF not EIN_AUS THEN 
    TY :=0;
    HEAT :=0;
else  
    IF T_EXT + H > tr THEN
       TY := 0.0;
    ELSE
       TY := LIMIT(MN:=TY_MIN,IN:=tr + T_DIFF * 0.5 * tx + (TY_CONFIG - T_DIFF * 0.5 - tr) * (tx**(1.0 / C)),MX:=TY_MAX);
    END_IF;

   TY := MAX(IN1:=TY, IN2:=T_REQ);
   HEAT := TY > 0.0;

END_IF;
 
Funktion ist gegeben aber ist das so sauber?
Code:
VERSION : '1.2'
[COLOR="#FF0000"]AUTHOR  : hugo[/COLOR]
NAME    : HEAT_TMP
FAMILY  : HLK

VAR_INPUT
    EIN_AUS : BOOL;
    T_EXT : REAL;
    T_INT : REAL;
    OFFSET : REAL;
    T_REQ : REAL;
END_VAR
VAR_INPUT
    TY_MAX : REAL := 70.0;
    TY_MIN : REAL := 25.0;
    TY_CONFIG : REAL := 70.0;
    T_INT_CONFIG : REAL := 20.0;
    T_EXT_CONFIG : REAL := -15.0;
    T_DIFF : REAL := 10.0;
    C : REAL := 1.33;
    H : REAL := 3.0;
END_VAR
VAR_OUTPUT
    TY : REAL;
    HEAT : BOOL;
END_VAR
VAR
    tr : REAL;
    tx: REAL;
END_VAR

BEGIN


tr := T_INT + OFFSET;
tx := (tr - T_EXT) / (T_INT_CONFIG - T_EXT_CONFIG);

IF [COLOR="#FF0000"]EIN_AUS =0[/COLOR] THEN 
    TY :=[COLOR="#FF0000"]0[/COLOR];
    HEAT :=0;
END_IF;    
  IF [COLOR="#FF0000"]EIN_AUS =1[/COLOR] THEN
   
  
    IF T_EXT + H > tr THEN
       [COLOR="#0000FF"]TY[/COLOR] := 0.0;
    ELSE
       [COLOR="#0000FF"]TY[/COLOR] := LIMIT(MN:=TY_MIN,IN:=tr + T_DIFF * 0.5 * tx + (TY_CONFIG - T_DIFF * 0.5 - tr) * (tx**(1.0 / C)),MX:=TY_MAX);
    END_IF;

[COLOR="#FF0000"]TY[/COLOR] := MAX(IN1:=[COLOR="#FF0000"]TY[/COLOR], IN2:=T_REQ);
HEAT := [COLOR="#FF0000"]TY[/COLOR] > 0.0;

  END_IF;
Was meinst Du mit "deaktivieren"? Nicht mehr aufrufen (FUP/KOP EN = FALSE)? --> dann bleiben naturgemäß alle Werte "eingefroren"
Wenn Du ein kontrolliertes Setzen auf 0-Werte brauchst, dann gib dem Baustein noch einen zusätzlichen Input - ist das der EIN_AUS ?

- es ist nicht gut, einen INPUT im Baustein mehrmals zu verwenden/abzufragen (Multitasking!)
- es ist nicht gut, einem OUTPUT mehrmals Werte zuzuweisen (Multitasking! z.B. mit HMI-Kommunikation)
- es ist nicht gut, einen OUTPUT zu lesen!
- vergleichen von BOOL-Werten auf 0 oder 1 ist unprofessionell/nicht schön
- Verwendung von Konstanten: für BOOL- und REAL-Konstanten sollte man auch BOOL- und REAL-Werte schreiben, und nicht so faul 0 und 1
- die Zuweisung an den OUTPUT HEAT kann man 2x (in beiden IF-Zweigen, übersichtlicher) oder 1x (nach dem END_IF, Code kürzer) nachen
- man könnte testen/abfangen, daß C nicht 0.0 sein darf und daß T_INT_CONFIG <> T_EXT_CONFIG sein muß

Besser:
Code:
VAR_TEMP
    tr : REAL;
    tx : REAL;
    tq : REAL;
END_VAR

IF NOT EIN_AUS THEN   //EIN_AUS = FALSE
  TY := 0.0;
  HEAT := FALSE;
ELSE                  //EIN_AUS = TRUE
  tr := T_INT + OFFSET;
  tx := (tr - T_EXT) / (T_INT_CONFIG - T_EXT_CONFIG);

  IF T_EXT + H > tr THEN
    tq := 0.0;
  ELSE
    tq := LIMIT(MN:=TY_MIN, IN:=tr + T_DIFF * 0.5 * tx + (TY_CONFIG - T_DIFF * 0.5 - tr) * (tx**(1.0 / C)), MX:=TY_MAX);
  END_IF;

  tq := MAX(IN1:=tq, IN2:=T_REQ);
  TY := tq;
  HEAT := tq > 0.0;
END_IF;

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich würde noch FALSE und TRUE-Zweig tauschen (keine Negierung bei IF) bzw. FALSE sogar ganz weg lassen (Initalisierung nutzen):
Code:
VAR_TEMP
    tr : REAL;
    tx : REAL;
    tq : REAL;
END_VAR


BEGIN

// Initialisierung
tq := 0.0;

// Berechnung (nur bei EIN)
IF  EIN_AUS THEN 
  tr := T_INT + OFFSET;
  tx := (tr - T_EXT) / (T_INT_CONFIG - T_EXT_CONFIG);

  IF T_EXT + H <= tr THEN
    tq := LIMIT(MN:=TY_MIN, IN:=tr + T_DIFF * 0.5 * tx + (TY_CONFIG - T_DIFF * 0.5 - tr) * (tx**(1.0 / C)), MX:=TY_MAX);
  END_IF;

  tq := MAX(IN1:=tq, IN2:=T_REQ);
END_IF;

// Ausgänge
TY := tq;
HEAT := tq > 0.0;

PS:
Theoretisch ist bei TIA mit S7-1x00 die Initialisierung der Temp-Variablen nicht einmal notwendig.
Ich nehme sie aus Lesbarkeits- und Kompatiblitätsgründen trotzdem immer mit rein.
 
Zuletzt bearbeitet:
Mich stört nur noch eine Winzigkeit:
Für mein Verständnis würde ich bei dem Namen EIN_AUS erwarten, dass mit einem Impuls "StromStossRelais-mässig" von EIN auf AUS bzw. umgekehrt umgeschaltet wird.
Möglichst versuche ich Namen für boolesche Variablen so festzulegen, dass sie aussagen, welche Bedeutung sie im Falle TRUE haben.
Dabei unterstelle ich, erwähne es aber nicht im Namen, dass im Falle FALSE das Gegenteil zutrifft.
In Falle von EIN_AUS würde ich z.B. AKTIV oder auf NeuDeutsch ENABLE bevorzugen.
Hat jemand eine Idee, wie man's vielleicht noch besser, treffender, unmissverständlicher formulieren könnte?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
ENABLE könnte verwirrend sein, da man beim grafischen Aufruf ja schon EN/ENO hat. Im Neudeutschen nutze ich dann Active, ob das jetzt einwandfreies Englisch ist, kann ich nicht beurteilen.
 
Was meinst Du mit "deaktivieren"? Nicht mehr aufrufen (FUP/KOP EN = FALSE)? --> dann bleiben naturgemäß alle Werte "eingefroren"
Wenn Du ein kontrolliertes Setzen auf 0-Werte brauchst, dann gib dem Baustein noch einen zusätzlichen Input - ist das der EIN_AUS ?

Ja ich dachte EN=FALSE und Ausgänge werden nicht mehr beschalten.

Da es nicht funktionierte habe ich EIN_AUS reingepackt.

Vielen DANK euch!!!:s6:
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Req nutze ich eher zum starten von Aktionen (z.B. für einen Fahrbefehl) und nicht zum Ein/Ausschalten einer Funktionalität.
Aber die Vergabe von Variablennamen ist oft einer der schwierigsten Teile der Programmierung und 2 Programmierer haben da mindestens 5 Meinungen :ROFLMAO:
 
Unter REQ verstehe ich eine einmalige Anforderung, von der intern eine Flanke gebildet wird, damit das Angeforderte nur einmal ausgeführt wird, egal wie lange der REQ ansteht.

Ich würde den Freigabeeingang z.B. ENABLE oder FREIGABE oder ACTIVE oder EIN nennen.

Harald
 
Zurück
Oben