[Programmierstil] Was gehört in die Globale Variablenliste

Zuviel Werbung?
-> Hier kostenlos registrieren
Bei Deiner Lösung gibst Du entweder alle Variablen einer Instanz frei oder Du mußt Dir aus jeder Instanz die zu veröffentlichenden Variablen raussuchen!

Nö, muss ich nicht. Weil auch auf der HMI-Seite agiere ich etwas geschickter.
Und ich gebe gar keine Variablen einer Instanz frei. Weil für Außenzugriffe sind die per se gar nicht geblockt.

Wenn Du mal richtig objektorientiert anfängst, merkst Du was das für ein Schmarrn ist, alles durch die Schnittstellen durchzutragen. Da die meisten aber immer noch flach und höchstens eine Ebene tief programmieren, fällt das den meisten gar nicht auf.

Und zu Thema Datenkosistenz und Multitreading, glaube ich, bin ich nicht so schlecht aufgestellt. Ich denke immer in Multitreading, wenn ich Software entwickle.
 
Bei Übergabe über die Bausteinschnittstelle bekommt man automatisch konsistente Kopien der HMI-Variablen. Wenn die HMI direkt in der Instanz liest oder schreibt, dann muß man selber extra für ein konsistentes Abbild der HMI-Variablen sorgen.

Vorsicht
Ganz so pauschal stimmt das leider bei der 1500er nicht.
Das Thema Call_by_Value oder Call_by_Reference ist bei InOut-Variablen an optimierten FBs auch noch zu beachten.
Einfache Datentypen werden mit Call_by_Value (also Kopie), komplexe Datentypen mit Call_by_Reference (keine Kopie)
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Leider hast Du meine Erweiterung noch nicht verstanden.

Ich habe deine Erweiterung schon verstanden, das war mir auch vorher schon klar. Es war einfach nur mal ein ganz einfaches Beispiel.
Dass dieses so wie ich es runtergetippt habe keinen Sinn ergibt ist klar. Es geht nur um darum darzustellen dass eine Variable zur Laufzeit
seinen Zustand ändern kann und der Abholpunkt undefiniert ist....
 
Wenn Du diese Erweiterung auf alle Variablen, die Du zwischzeitlich mit "falschen" Werten beschreibst, anwendest, hast Du das Problem nicht mehr, das ein falscher Wert in das HMI kommt.
So funktioniert es auch bei Mulitreading, wenn zwei Tasks auf den gleichen Speicher zugreifen müssen.

Dann ist der Abholzeitpunkt unwichtig.
 
Zuletzt bearbeitet:
Nö, muss ich nicht. Weil auch auf der HMI-Seite agiere ich etwas geschickter.
Und ich gebe gar keine Variablen einer Instanz frei. Weil für Außenzugriffe sind die per se gar nicht geblockt.

Wo wir wieder bei Datensicherheit wären... es kann also (später) jeder Programmierer in Deinen Instanzen rumfummeln....

Da Du so auf die Objektorientiertheit abhebst: Wofür habe ich Objekte? Nicht nur zum Vererben, sondern auch zur Datensicherheit: Damit niemand auf meine internen Variablen zugreifen kann. Dafür gibts dann extra die Putter, Getter und Attribute...

Über den Sinn und Unsinn der objektorientierten Programmierung in einer SPS hat es schon andere Threads gegeben, die Diskussion müssen wir hier nicht wieder anfangen.

Aber ich bin der Meinung (!), daß man nur Variablen freigeben sollte, die auch nach außen benötigt werden (hat dann neben Sicherheit auch irgendwann mal was mit Variablenkontingenten zu tun, Du kannst nicht beliebig viele Variablen freigeben) und daß man dieses sehr gut über Variablenlisten machen kann.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wenn Du diese Erweiterung auf alle Variablen, die Du zwischzeitlich mit "falschen" Werten beschreibst, anwendest, hast Du das Problem nicht mehr, das ein falscher Wert in das HMI kommt.
So funktioniert es auch bei Mulitreading, wenn zwei Tasks auf den gleichen Speicher zugreifen müssen.

Dann ist der Abholzeitpunkt unwichtig.

Ein paar Sachen mehr gibt es da schon noch zu beachten:
AbhilfeZu den oben beschriebenen Systemeigenschaften empfehlen wir Ihnen die folgenden Abhilfen:

  • Vermeiden Sie in parallelen Prozessen schreibende Variablenzugriffe auf dieselbe Variable.

  • Erstellen Sie einen globalen Schnittstellen-Datenbaustein mit zwei getrennten Datenstrukturen (evtl. unter Verwendung von PLC-Datentypen), z.B. für HMI und PLC-Zugriffe.
  • In einer Datenstruktur greifen Sie schreibend nur vom Prozess 1 z.B. HMI aus zu.
  • In der anderen Datenstruktur greifen Sie schreibend nur von Prozess 2 z.B. der PLC aus zu.
  • Lesend können Sie generell von beiden Prozessen auf beide Datenstrukturen zugreifen.
  • Somit vermeiden Sie, dass parallele Prozesse sich gegenseitig Variablen überschreiben.

  • Vermeiden Sie bei Bausteinzugriffen Bereichsübergänge zwischen optimiert und nicht optimiert. Neu erzeugte Bausteine bei der S7-1200/S7-1500 haben das Attribut "Optimierter Bausteinzugriff". Bausteine aus der S7-300/S7-400 haben den nicht optimierten Bausteinzugriff. Wenn Sie diese Bausteine für die S7-1500 verwenden, empfehlen wir Ihnen, den Bausteinzugriff auf Optimiert einzustellen. Ändern können Sie den Bausteinzugriff in den Bausteineigenschaften im Register "Attribute".

PS:
Siemens empfiehlt ja selber die Verwendung eines Schnittstellen DB:
  • Erstellen Sie einen globalen Schnittstellen-Datenbaustein mit zwei getrennten Datenstrukturen (evtl. unter Verwendung von PLC-Datentypen), z.B. für HMI und PLC-Zugriffe.
Quelle:
https://support.industry.siemens.co...servers-in-der-s7-1500-kommen-?dti=0&lc=de-WW
 
Zuletzt bearbeitet:
Ein paar Sachen mehr gibt es da schon noch zu beachten:

Das diese Empfehlungen von Siemens nicht ausreichend sind, das Du doch gerade mit Deinem Beispiel anschaulich gezeigt.
Man kann eben nicht von einem anderen Task eine Variable lesen, wenn die von dem schreibenden Task z.B. mit 0 initialisiert und dann mit dem richtigen Wert beschrieben wird.

Da hilft nur das umkopieren und dieser Wert kann dann von dem anderen Task gelesen werden. So hatte ich es empfohlen.
 
Das diese Empfehlungen von Siemens nicht ausreichend sind, das Du doch gerade mit Deinem Beispiel anschaulich gezeigt.

Das ist so nicht richtig. Mindestens diese drei Punkte habe ich nicht beachtet. Mit den beiden markierten Punkten hätte ich jeweils das Problem umgehen können.


  • Vermeiden Sie in parallelen Prozessen schreibende Variablenzugriffe auf dieselbe Variable. <= Habe ich nicht beachtet

  • Erstellen Sie einen globalen Schnittstellen-Datenbaustein mit zwei getrennten Datenstrukturen... <= Habe ich gar nicht beachtet
  • In einer Datenstruktur greifen Sie schreibend nur vom Prozess 1 z.B. HMI aus zu.
  • In der anderen Datenstruktur greifen Sie schreibend nur von Prozess 2 z.B. der PLC aus zu.
  • Lesend können Sie generell von beiden Prozessen auf beide Datenstrukturen zugreifen.
  • Somit vermeiden Sie, dass parallele Prozesse sich gegenseitig Variablen überschreiben.
  • Vermeiden Sie bei Bausteinzugriffen Bereichsübergänge zwischen optimiert und nicht optimiert.
 
Kurze Frage, wohin umkopieren?

Ok, ich habe vorher in deinem Beispiel überlesen, dass du die Variablen in eine Struktur schreibst.
Damit umgehst du natürlich das Problem.

Aber nichts für Ungut, wo ist da jetzt der Unterschied zu einem Übergabe-DB. Hier ist es halt eine Übergabe-Struktur?

Code:
FOR i := 0 TO 99 DO                   
[B][COLOR=#ff0000]    stHmi.Farbe[/COLOR][/B][i] := Farbe[i];                                        
END_FOR;

*ROFL**ROFL*
Echt jetzt? Dann habe ich jetzt einen weiteren Grund Siemens-Projekte abzulehnen.

Übergabe-DB? das ist ja wie vor 30 Jahren!
 
Zuletzt bearbeitet:
Vermeiden Sie in parallelen Prozessen schreibende Variablenzugriffe auf dieselbe Variable. <= Habe ich nicht beachtet

Doch, hast Du beachtet. Es sei denn die Definition von "Paralleler Prozess" ist Dir noch nicht ganz klar.

Kurze Frage, wohin umkopieren?

Ich habe doch geahnt, dass Du meine Erweiterung noch nicht verstanden hast.

Hier ein einfacheres Beispiel:
Code:
Variable1 := 0;
IF Bedingung#1 THEN
    Variable1 := 1;
ELSIF Bedingung#2 THEN
    Variable1 := 2;
END_IF
Variable2 := Variable1;

Variable2 kann von jedem beliebigen Task zu jedem Zeitpunkt gelesen werden und enthält immer den richtigen Wert. Im Gegensatz zu Variable1.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Doch, hast Du beachtet. Es sei denn die Definition von "Paralleler Prozess" ist Dir noch nicht ganz klar.



Ich habe doch geahnt, dass Du meine Erweiterung noch nicht verstanden hast.

Hier ein einfacheres Beispiel:
Code:
Variable1 := 0;
IF Bedingung#1 THEN
    Variable1 := 1;
ELSIF Bedingung#2 THEN
    Variable1 := 2;
END_IF
Variable2 := Variable1;

Variable2 kann von jedem beliebigen Task zu jedem Zeitpunkt gelesen werden und enthält immer den richtigen Wert. Im Gegensatz zu Variable1.

Das mag ja alles sein, aber bevor ich mit solchen Konstrukten anfange mache ich leichter einen vernünftigen Übergabe DB ( so wie du deine Struktur stHmi. )
Dann muss ich auch nicht die 5 Siemens Punkte bei jeder HMI Variable beachten, was ja auch fehlerbehaftet sein kann wenn man es mal übersieht
bei den hunderten HMI Variablen.
 
Aber nichts für Ungut, wo ist da jetzt der Unterschied zu einem Übergabe-DB. Hier ist es halt eine Übergabe-Struktur?

Der Unterschied ist, dass ich die Instanz nicht über die Schnittstelle verlassen muss und damit Arbeit einspare. Ob Struktur, einfache Variable oder Übergabe-DB, das ändert aber nicht prinzipielles.
 
Das mag ja alles sein, aber bevor ich mit solchen Konstrukten anfange mache ich leichter einen vernünftigen Übergabe DB ( so wie du deine Struktur stHmi. )
Dann muss ich auch nicht die 5 Siemens Punkte bei jeder HMI Variable beachten, was ja auch fehlerbehaftet sein kann wenn man es mal übersieht
bei den hunderten HMI Variablen.

So lange Du beim Singletreading bleibts, ist alles gut. Aber wenn Du mal Multitreading brauchst, solltest Du Dich an diesen Tipp erinnern.

...bei den hunderten HMI Variablen..
Durch meine Arbeitsweise ohne Übergabe DB reduziere ich die "hunterte Variablen" enorm, das war auch der ursprüngliche Sinn meiner Einlassung.

Aber ich möchte hier nicht Richtg oder Falsch sagen. Das ist dann persönlicher Geschmack.
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Um noch einmal ganz kurz zurück zukommen.

Es ist mir natürlich schon klar, dass man diese Probleme umgehen kann, dass vieles einfacher geht...
Bei einem neuen TIA Projekt fällt mir dieses "Problem" auch nicht mehr auf die Füße.

Aber bei einer 1:1 Migration eines S7-300 Programm auf TIA 1200/1500 treten diese Probleme eben ( u.U. ) auf.
Weil man dieses Verhalten damals bei der S7-300 Programmierung nicht berücksichtigt hat. Und dann geht der Ärger / die Umprogrammiererei los,
weil es viele dann erst vor Ort merken und es aber nach dem Wochenende alles wieder laufen soll.

Und auf einer Messe wird einem erzählt: "Projekt einfach migrieren, ein bisschen anpassen und fertig".
Darauf fallen halt viele rein, dass es so einfach doch nicht ist. Und bei einer Kommissionieranlage mit
hunderten Stellplätzen würde ich mittlerweile nicht mehr migrieren sondern neu aufsetzen.
Bzw. setze ich mittlerweile nur noch neu auf. ( aus verschiedenen Gründen )

Aber das ist ja auch ein anderes Thema.

Viele Grüße
 
Ganz in dem Sinne des Forums "Wissen ist das einzige Gut, das sich vermehrt, wenn man es teilt" habe ich folgendes gelernt:

Sollte ich jemals eine 1500er programmieren, muss ich die Grundsätze des Multitreadings beim Anbinden eines HMI's beachten.
Bei den 300er und auch bei TwinCAT muss ich das nicht tun, da der PLC- und "Pseudo-"HMI-Lesetask sich abwechselnd synchron zueinander verhalten.
 
Code:
IF stHmi.Einstellwert > 0 AND stHmi.Einstellwert < 100 THEN
  Sollwert := 12345 / stHmi.Einstellwert;
END_IF;
Sowas kann in Division durch 0 enden...


Zu gutem Programmierstil gehört für mich auch, daß man nicht nur an seine eigene vielleicht eingesparte Arbeitsstunde denkt sondern auch an die Nachfolger-Programmierer, die irgendwann mal an dem Programm was ändern sollen oder auf eine andere CPU migrieren oder das HMI ändern oder austauschen ... Dann vereinfachen klare definierte globale Schnittstellen (z.B. Übergabe-DB) die Arbeit ungemein. Dann ist es auch hilfreich, wenn man sicher ist, daß nur auf wenige hundert dokumentierte Variablen überhaupt von außen zugegriffen werden kann und man nicht zigtausend dummerweise freigegebene Variablen im Verdacht der Änderung von außen hat.

Harald
 
Zurück
Oben