Behinderungen symbolischer Programmierung - Wie umgehen ?

Machtnix

Level-2
Beiträge
77
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

ich schreibe meine S7-Programme als AWL-Quelltext und habe mich entschlossen aus Gründen der Überschaubarkeit, Wiederverwendbarkeit und Verläßlichkeit dies rein symbolisch zu tun. Also keine Verwendung von absoluten Operanden im Quelltext. (Ausnahme sind Ein- und Ausgänge in dafür speziellen Funktionen).

Nun ist aber leider der AWL-Compiler von Siemens so gebaut, daß er die rein symbolische Programmierung mehr behindert als fördert. Während sich die siemenschliche Lust an Fehlermeldungen und Pedanterie voll austobt, fehlt es an elementaren Zugriffsmöglichkeiten auf das, was hinter den Symbolen steht.Vieles, was auf absoluter Ebene leicht und einfach zu machen ist, erfordert auf symbolischer Ebene lange Umwege und Verrenkungen.

Um rein symbolisch auf Bits von einem WORD in einem Datenbaustein zuzugreifen, brauch ich zb eine Funktion die mir die Nummer des DB herausgibt, für eine Anypointerbastelei um mit Blockmove dann ein WORD in eine UDT zu laden. Oder ich brauche eine Funktion, die Bit für Bit vom WORD ins UDT schaufelt. Und eine weitere für den Rückweg. Das geht natürlich ganz schön auf die Performance und Zykluszeit, wenn es häufig geschehen muß. Und das alles nur, damit der Compiler nicht meckert.

Wie geht ihr mit solchen Problemen um? Welche Tricks gehen am wenigsten auf Kosten der Zykluszeit. Welche Umwege sind die kürzesten?
 
hab ich bei Siemens auch mal angeregt, einen symbolischen Bitindexzugriff auf die Bits eines Wortes ...

ansonsten kenne ich aus meiner Praxix nur einen konkreten Anwendungsfall: Schieberegister. Da schiebt man gerne wortweise und braucht aber die Bits ... - hab ich umgestellt, indem ich die Bitschieberei tatsächlich als Bitschieberei code. allerdings bin ich noch nicht soweit gegangen, so ein Schieberegister als UDT zu definieren, um dann auch per Indexzeiger variabel auf zur Laufzeit bestimmbare Bits zugreifen zu können ...
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Symbolische Programmierung ist so ne Sache mit S7, eine falsche Einstellung eines Kollegen oder Instandhalters im Bausteinordner kann dir etliches zerschiessen. Ich verwende Quellen eigentlich ausschließlich für SCL (geht ja auch nicht anders). Den Wechsel zwischen Bit und WORD/DWORD Zugriff mache ich mit einem entsprechenden UDT, der mit dem Befehl AT auf den entsprechenden Bereich gelegt wird.
Im Kop/Fup Bereich habe ich noch Konvertierungsfunktionen geschrieben
WORD_TO_BITS und umgekehrt. Hin und wieder kommen sie zum Einsatz.
Mit Zykluszeiten hatte ich dadurch noch keine Probleme.
 
@Perfektionist

Und ? Hat Siemens reagiert ? Wenn der Aufwand, den Siemens betreibt um Fehlermeldungen zu generieren, was alles nicht geht, in Lösungen gesteckt würde, sähe es viel besser aus.

In C gibts zB ein sogenanntes "casting", eine extra angesagte Typumwandlung. Also man sagt dem Compiler:" sieh das jetzt doch einfach mal als WORD und mecker nicht rum, ich weiß schon was ich tu". Oder eine "union" , die schon bei der Deklaration erklärt, daß man auf diesen Speicherbereich mit mehreren Typen zugreifen kann.
 
Zuletzt bearbeitet:
@kiestumpe

Versteh ich nicht, was an symbolischer Programmierung so gefährlich sein sollte. Sags mal genauer. An meine Programme geht normalerweise niemand anderes dran, aber es interessiert mich trotzdem.

Mir gehts bei symbolischer Programmierung um Wiederverwertung, schnelles Zurechtfinden auch in älteren Programmen, einfaches Ändern und Erweitern. Deshalb bevorzuge ich auch Quellen, eine pro CPU, in denen alles wesentliche drinsteht. Die Symboltabelle brauch ich eigentlich nur für die Zuordnung der Nummern von Bausteinen und Timern und die sind ja im Prinzip beliebig austauschbar. Ein- und Ausgänge sind in speziellen Bausteinen(FCDigEin,FCDigAus,FCAnaEin...) im Quelltext zugeordnet.

SCL hab ich mir nur mal kurz angeschaut und dabei nichts gefunden, wodurch mir der Umstieg lohnenswert erschiene.
 
@Machtnix, das Problem gibt es meistens wenn zwei oder mehr Leute am selben PC/PG arbeiten. Wenn einer die Priorität von "Absolut" auf "Symbolisch" oder umgekehrt umschaltet und der andere entscheidet sich entweder ein Symbol oder eine Absolut-Adresse zu umzubennen bzw. zu ändern bei falscher Priorität kann das gewaltig in die Hosen gehen. Das gesagt, ich habs gelegentlich selbst gemacht aus versehen und es tut echt Weh!

Übrigens, ich programmiere auch bevorzugt symbolisch.
 
Ich arbeite fast ausschließlich mit DBs. Da kann man jedem Objekt in der Anlage einen DB zuweisen, mit einem prägnanten Namen und schon hat man keinen M 23.4 sondern "DB_Beleuchtung".Tageslichtsensor, zum Bleistift. EAs bleiben latürnich so, werden aber möglichst sinnig benannt und schon kann man prima symbolisch tippeln.
Ist bei Siemens aber von Vorteil, wenn man noch in etwa weiß, welchen EA- oder Merkerbereich man wo verwendet.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ist bei Siemens aber von Vorteil, wenn man noch in etwa weiß, welchen EA- oder Merkerbereich man wo verwendet.

EAs stehen bei mir unsymbolisch im Quelltext, aber geordnet alle in jeweils einem Baustein. Beispiel Ausschnitt:
Code:
// Baugruppenträger 0, Steckplatz 9

U  E20.0 ;= "DPumpSt".P3.ESchrank; // Pumpstation Pumpe 3 Schrankbedienung
U  E20.1 ;= "DPumpSt".P3.EWarte  ; // Pumpstation Pumpe 3 Warte /Automatik
U  E20.2 ;= "DPumpSt".P3.ENTAus  ; // Pumpstation Pumpe 3 Nicht Taster AUS
U  E20.3 ;= "DPumpSt".P3.ETsEin  ; // Pumpstation Pumpe 3 Taster EIN
U  E20.4 ;= "DPumpSt".P3.ELmFu   ; // Pumpstation Pumpe 3 läuft über FU
U  E20.5 ;= "DPumpSt".P3.ELmSdr  ; // Pumpstation Pumpe 3 läuft im Stern-Dreieck Betrieb (nicht FU)
U  E20.6 ;= "DPumpSt".P3.EStoer  ; // Pumpstation Pumpe 3 Störung
// E20.7 Reserve

Merker werde ich ganz vermeiden und durch Global-DB ersetzen. Dann kann ich alles im Quelltext definieren und brauch die Symboltabelle nicht anrühren oder beachten.
 
Ich programmiere ausschließlich vollsymbolisch. Das meiste lässt sich problemlos damit machen (wenn man sich mal von der absoluten Denkweise getrennt hat). Was mir nicht gefällt ist das Handling S7->WinCC (Attribut S7_m_c). Warum kann man die sybolischen Variablennamen bei Multiinstanz-FBs nur IN und IN_OUT bzw. OUTS ins Leitsystem anlegen lassen - warum nicht mit STATS? Alle diese Daten werden beim FB im zugehörigen Instanz-DB gehalten. Das Handling -> WinCC funktioniert nicht mit ARRAY und UDT- / Strukturen (wäre für einige Anwendungen eine feine Sache). Die sybolische Bearbeitung auf der Step7-Seite ist eigentlich ganz brauchbar - nur bei der Übergabe an die OS (WinCC) hakt's halt noch.
 
Im Grunde ist die Zugriffsmöglichkeit auf instanzinterne Variablen der eigentliche Frevel. Die Norm sieht vor, dass man eben genau definieren muss, welche Daten von außen beschrieben werden dürfen und welche nicht.

Und eine statische Variable sollte dementsprechend nur in dem Baustein les- und beschreibbar sein, zu dem sie gehört.

WinCC ist da vielleicht schon weiter als Step 7.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Im Grunde ist die Zugriffsmöglichkeit auf instanzinterne Variablen der eigentliche Frevel. Die Norm sieht vor, dass man eben genau definieren muss, welche Daten von außen beschrieben werden dürfen und welche nicht.

Und eine statische Variable sollte dementsprechend nur in dem Baustein les- und beschreibbar sein, zu dem sie gehört.

WinCC ist da vielleicht schon weiter als Step 7.

Für den Zugriff innerhalb von Step7 stimme ich dem ja voll zu. Aber warum sollte der Zugriff innerhalb WinCC nicht gehen. Sind an einem FB die Ein- oder Ausgänge nicht beschaltet (was ja durch aus geht), kann ich sie in der jetzigen Form auch aus dem Leitsystem heraus beschreiben - warum also nich auch mit entsprechend (S7_m_c) markierten Variablen im STATS-Bereich?
 
kleiner Umweg

Für mein Problem hab ich inzwischen nach intensiver Beschäftigung mit der Pointerei einen relativ kurzen Umweg gefunden.

Code:
FUNCTION "FCdbw2any" : VOID
TITLE =indiziertes WORD aus DB in beliebige Struktur schreiben

VERSION : 0.1

VAR_INPUT
  DBQ: BLOCK_DB;
  Index: INT; //Wortweise(wie S5), nicht Byteadresse!
  AnyZ:ANY; 
 END_VAR

VAR_TEMP
  Val: WORD;
  DBZ: INT;
END_VAR

BEGIN
NETWORK
TITLE =

L #Index;SLD 4;LAR1;
AUF #DBQ;L DBW[AR1,P#0.0];T #Val; 

L P##AnyZ;LAR1;
L W [AR1,P#4.0]; T #DBZ ;L 0; ==I;SPB NoDB; 

AUF DB[#DBZ];

NoDB: L D [AR1,P#6.0];LAR1;
L #Val;T W [AR1,P#0.0];
 
END_FUNCTION
 
Für den Zugriff innerhalb von Step7 stimme ich dem ja voll zu. Aber warum sollte der Zugriff innerhalb WinCC nicht gehen. Sind an einem FB die Ein- oder Ausgänge nicht beschaltet (was ja durch aus geht), kann ich sie in der jetzigen Form auch aus dem Leitsystem heraus beschreiben - warum also nich auch mit entsprechend (S7_m_c) markierten Variablen im STATS-Bereich?

Tolle Idee, wer soll jemals rausfinden, wann was wo warum ... von außen in die internen Daten deines FB reinschmiert. Vielleicht noch eine kleine Datenbank, die per Libnodave oder OPC die Statdaten umwurschtelt? Dazu sind doch IN- OUT- und INOUT-Variablen da? Wär ja ganz nett, wenn sich wenigstens einige wenige Programmierer über die tatsächlichen Folgen genial anmutender Ideen im Klaren wären.

Ich bin gerade zum zweiten Mal damit beschäftigt, ein Programm umzuschreiben, dessen Programmierer, ganz wild Daten von einem Instanz-DB in den nächsten kopieren etc. etc. Kein Wunder, daß die Firma Pleite gegangen ist.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Zugriff auf Instanz-DBs - Warum nicht?

Was können wir aus den WinCC-Problemen lernen? Daß es wohl besser ist, Variablen in FBs standardmäßig als in_out (VAR_IN_OUT) zu deklarieren und nicht als stat (VAR). Jedenfalls, wenn man sicher gehen will, daß der Zugriff darauf auch noch möglich ist, wenn die Pedanten sich noch mehr durchsetzen.

Ich hab hier des öfteren gelesen, was für ein Frevel es sei, von einem Baustein aus auf Instanzdaten eines anderen zuzugreifen. Anscheinend für einige ein Dogma. Aber warum? Wozu soll das gut sein?

Ein Baustein ist doch nur sinnvoll, wenn er nicht nur autistisch mit seinen eigenen Daten rumspielt, sondern auch Daten austauscht mit anderen Bausteinen, unter anderem solchen, die sich um die Peripherie kümmern oder die Kommunikation mit PCs und anderen SPSen. Wenn nun keiner auf die Daten des Anderen zugreifen darf, muß der Datenaustausch über Umwege gehen, über Globale DBs oder Merker. Also wird das ganze umfangreicher, langsamer und vor allem unübersichtlicher. Und wo bleibt da der Nutzen?
 
Daszu sind doch IN- OUT- und INOUT-Variablen da. Wozu müssen auch die Stat-Daten von Außen beschrieben werden? Weil jemand zu faul ist die dazu nötigen Variablen nochmals zu definieren? Ich hab schon gemerkt, daß du das nicht verstanden hast, aber warum stopfst du eigentlich Essen in deinen Mund? Intravenös, oder per Magensonde ginge doch auch. Wenn aber dein Arzt nicht weiß, daß du so nebenbei noch eine Sonde liegen hast, kann er sich nur wundern, daß du nicht verhungerst. Genau so geht es jedem Programmierer, der nicht genau weiß, was du wann genau in die Stat-Daten impfst. Im übrigen ist es schon schwierig genug bei globalen DB die Übersicht zu behalten, bei statischen Daten greifen ja nicht einmal mehr die Referenzdaten!

Jedenfalls, wenn man sicher gehen will, daß der Zugriff darauf auch noch möglich ist, wenn die Pedanten sich noch mehr durchsetzen.
Nun uns ob sich andere von dir als Pedant betiteln lassen, soll mal dahingestellt sein, für mich bist du ein Depp, bitte schön, zumindest, was das betrifft. :evil: Denn in diesem Fall kann man nur von Selbstschutz vor Möchtegernsuperproggern sprechen.
 
Zuletzt bearbeitet:
Tolle Idee, wer soll jemals rausfinden, wann was wo warum ... von außen in die internen Daten deines FB reinschmiert. Vielleicht noch eine kleine Datenbank, die per Libnodave oder OPC die Statdaten umwurschtelt? Dazu sind doch IN- OUT- und INOUT-Variablen da? Wär ja ganz nett, wenn sich wenigstens einige wenige Programmierer über die tatsächlichen Folgen genial anmutender Ideen im Klaren wären.

Ich bin gerade zum zweiten Mal damit beschäftigt, ein Programm umzuschreiben, dessen Programmierer, ganz wild Daten von einem Instanz-DB in den nächsten kopieren etc. etc. Kein Wunder, daß die Firma Pleite gegangen ist.

Ich kann das nicht ganz nachvollziehen. Vielleicht reden wir ja auch aneinander vorbei. Hast Du vielleicht ein Beispiel, um Deine Aussage mal für mich deutlicher zu machen?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Daszu sind doch IN- OUT- und INOUT-Variablen da.
Wenn das erlaubt ist, ist ja alles klar, dann hab ich da keine Probleme mit. Deshalb brauchst du doch nicht so ausfallend zu werden. Du hast doch keine Ahnung, was ich verstehe und was nicht.

Mit den Pedanten mein ich doch nicht dich, sondern die Step7 - Entwickler von Siemens, die für die symbolische Programmierung lauter sinnlose Hindernisse einbauen und dadurch zu unübersichtlichen Umwegen und Verrenkungen zwingen oder einige sogar zu unsauberer Mischprogrammierung ( symbolisch + absolut) verleiten.

Wenn es verboten sein soll, auf die stat-Variablen (Im Quelltext einfach nur VAR) von außen zuzugreifen, warum nennen sie es nicht privat oder ähnlich? Statisch sind die IN- OUT- und INOUT-Variablen ja genauso. In den Erklärungen zu den Stat-Variablen steht auch nur der Unterschied zu den Temp-Variablen, nichts davon, daß man nicht von außen darauf zugreifen sollte.
 
Ich kann das nicht ganz nachvollziehen. Vielleicht reden wir ja auch aneinander vorbei. Hast Du vielleicht ein Beispiel, um Deine Aussage mal für mich deutlicher zu machen?

Wie ich schon erwähnte, hatte ich letztes Jahr die Ehre ein Graph7-Programm, daß immer mal nicht machte, was es sollte, in ein normales Schrittkettenprogramm umzuschreiben, bzw. neuzuschreiben. Dabei war natürlich erst einmal etwas Reengineering angesagt, um sich etwas Arbeit zu ersparen. Dabei stellte sich heraus, daß der verehrte Kollege seine globalen Daten so verteilte, daß er sie als Stat-Var in einigen FB deklarierte und dann am Anfang des FB diese Variablen per SFC20 umkopierte. Das ging ja noch, da wenigstens nachvollziehbar. Aber dabei ist er ja nicht geblieben. Meßdaten wurden munter hin- und herkopiert, was einmal klappt, geht ja auch woanders. Stat-Bits in FB wurden von außen (aus irgendeinem FC/FB) gesetzte bzw. gelöscht. Rezeptdaten wurden aus ProTool direkt in Stat-Var geschrieben. In einem solchen Gemenge, ist eine Fehlersuche fast schon Glückssache, daher kam ja der Entschluß des Auftraggebers, das Ganze neu zu schreiben.

@Machtnix

Ich habe auf das geantwortet, was du geschrieben hast, also drück dich vielleicht etwas klarer aus. Trotzdem hatte ich nicht den Eindruck, daß du die Argumente der Antwortenden überhaupt zu Kenntnis genommen hast. Weil etwas geht, muß man es nicht machen und es muß auch nicht gut sein. Temp-Var sind ja nut TEMPORÄR, also nicht für Berechnungen über mehrere SPS-Zyklen etc. geeignet. Dafür gabs dann die Stat-Var, ein immerhin treffender Name. Man hätte sie für dich vielleicht StatLokal-Var nennen sollen. Aber alleine die Tatsache, daß sie im Instanz-DB liegen, der also ausschließlich zu seinem FB gehört, sollte ja genug sagen.

PS: Ich weiß auch, daß Siemens selbst ein grandioses Beispiel für Zugriffe auf den IDB geliefert hat (FB125) aber dort werden die Daten nur zum Anzeigen auf Visualisierungen ausgelesen und nicht verändert, was in diesem speziellen Fall sicher die SPS-schonenste Variante war.
 
Wenn es verboten sein soll, auf die stat-Variablen (Im Quelltext einfach nur VAR) von außen zuzugreifen, warum nennen sie es nicht privat oder ähnlich? Statisch sind die IN- OUT- und INOUT-Variablen ja genauso. In den Erklärungen zu den Stat-Variablen steht auch nur der Unterschied zu den Temp-Variablen, nichts davon, daß man nicht von außen darauf zugreifen sollte.

Hallo!

Die STAT-Variablen sind Private Variablen genauso wie die IN- OUT- und INOUT-Variablen. Diese gehören nur zu dem Baustein in denen sie Deklariert sind!
Zugänglich von außen sind sie ja nur dadurch geworden weil ja ein Speicherbereich in der SPS geschaffen werden muss und das hat man mit einem I-DB gelöst.
Und wenn du jetzt von aussen in den I-DB in einen Speicherbereich schreibst dann kann das kein Mensch nachvollziehen von wo das kommt. Wenn du aber IN- OUT- und INOUT-Variablen anlegst und diese hoffentlich auch nicht über den I-DB beschreibst sondern richtig beim Bausteinaufruf mit einem Wert von einem anderen Speicherbereich und den Speicherbereich dann einen schönen Namen/Kommentar gibts wie zb. von wo der Wert herkommt (Visualisierung) dann kann auch ein Betriebselektriker mit wenig Programmierkenntnisse nachvollziehen das dieser Wert aus der HMI kommt und nicht von Irgendeinem anderen Programmteil und er gleich bei einem Störfall in der HMI nachsehen kann und draufkommt das der Bediener nur einen Falschen Parameter/Wert eingegeben hat und nicht irgendwo ein Sensor oder sonstiges defekt ist.

godi
 
Zurück
Oben