TIA S7-1500 spukhaftes Verhalten, Lokaldatenstackproblem?

Mephisto

Level-1
Beiträge
242
Reaktionspunkte
12
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo!

Ich hoffe, die Überschrift ist nicht komplett verwirrend. Ich habe folgende Anwendung: Eine S7-1500 kommuniziert via OpenUserCommunication (TCP) mit einem PC. Ein FB sammeldt Daten, die an den PC gesendet werden sollen, in einem Array zusammen. Ein zweiter FB sendet diese Daten dann an den PC. Dadurch, dass es vom Daten-FB mehrere geben soll, liegt das Array im iDB des Sende-FBs. Den Sende-FB übergebe ich dann als Parameter (IN-OUT) (Call by Reference?) an den Daten-FB. Somit kann der Daten-FB direkt in das Array des Sende-FB schreiben.
Meine Bausteine sind hinsichtlich der Datenmenge sehr groß geworden. (64kByte Array im Sende-DB, noch größeres, als FiFo arbeitendes Array im Daten-DB).
Es kommt nun vor, dass, wenn ich Daten in das Array schreiben möchte, diese Daten nicht komplett geschrieben werden und schlimmer noch, dass stattdessen an irgendwelchen Datenpunkten aus dem STATIC-Bereich irgendwelche Werte überschrieben werden.
Verkürzt: Wenn ein FB in den iDB eines anderen FB schreibt, dann geschehen spukhafte Dinge.
Kennt jemand von euch das Problem und weiß wie ich ihm auf die Schliche kommen kann?
Hat überhaupt jemand verstanden, was genau mein Problem ist? (Ich zweifle hier nicht an euch sondern an meiner Gabe als Geschichtenerzähler)

mfg mephisto
 
Ja, schwierige Sache, bei der 300-er wußte man noch in etwas was genau vorgeht, bei der 1500-er tappen wir da eher im Dunkeln rum.

Sendest du jetzt schon mehrfach (über unterschiedliche Daten-FB) oder passiert das auch, wenn du nur einen einzigen Daten-FB nutzt und nur diesem den Sende-FB übergibst?
Ich hab das noch nicht gemacht, wenn du den Sende-FB übergibst, woher weiß der im Daten-FB dann, welchen IDB er selbst nutzt oder übergibst du den IDB des Sende-FB???

Wenn du schon mehrfach sendest, ist das gegeneinander verriegelt, so daß nur immer ein Daten-FB Daten in den Sende-FB schreibt?

Hast du OB aktiv, die den FB unterbrechen können?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo!

- Es gibt nur einen OB (zyklisch 1ms)
- Es gibt nur einen Daten-FB, somit ist keine Verriegelung notwendig, obwohl die programmiert wäre
- Dad Phänomen tritt auf, wenn ein Daten-FB verbunden ist. Mit mehreren hab ich's noch gar nicht probiert.

Ich übergebe den iDB des Sende-FBs an den Daten-FB über einen INOUT vom Typ "Sende-FB".

Das mit dem dunkeln tappen ist richtig. Hab dazu auch schon den Support von Siemens befragt. Bin aber an jemanden geraten bei dem es mir (unserem kurzen Gespräch nach zu urteilen) unerklärlich ist, wie der eine technische Ausbildung bestehen konnte.
 
Ich finde es wäre einfacher wenn du das ganze als multiple-instance programmiert.
Ein obergeordnete FB mit den Datensammlung, und darin auch den Sende-FB als multi-Instanz.
Aber Ausnahme, das Daten-Array wurde ich mit ein UDT und als externe Daten (IN-OUT) deklarieren.
Dann hast du ein grossen FIFO Global-DB, und ein kleineres Instanz-DB.
 
prinzipiell arbeitet die Kommunikation "parallel" zum OB1 und u.U. auch mehrere Zyklen lang. "Konsistenz" ist hier das Schlagwort. Es kann also passieren, dass der "OB1-Code" quasi "gleichzeitig" Daten verändert, die Du grad senden willst, bzw. umgekehrt.

Ich denke, das könnte Dein Problem sein.

Gruß
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Die Zeile macht mich zumindest stutzig.

Somit kann der Daten-FB direkt in das Array des Sende-FB schreiben.
mfg mephisto

Bei der Open User Com ist es wichtig das die Daten am Parameter DATA nicht geändert werden dürfen, nachdem am Sendebaustein der REQ Parameter auf eins gesetzt wurde.
Schreibt der Daten FB vielleicht zyklisch in den Sende FB?
 
Hallo!

Das mit dem Senden über TCP hab ich eigentlich nur der Vollständigkeit halber erwähnt. Darin liegt nicht mein Problem. Wenn meine komplette Kommunikation inaktiv ist (Enable von TCON, TSEND, etc. auf FALSE), dann gibt es nur mehr meinen Daten-FB, der Daten aus meinem großen FiFo-Array im Daten-iDB in das kleine Sende-Array aus meinem Sende-iDB kopiert. Und genau dort liegt schon der Fehler. Während dieses Kopiervorgang geht schon etwas schief.
Ich kopiere z.B. via 2 MOVE_BLK Befehle Daten vom Fifo-Array ins Sende-Array, den ersten MOVE_BLK führt das Programm aus, den zweiten nicht mehr. Datenbereiche des Ziels liegen zwar direkt hintereinander, überlappen jedoch nicht. Auch das ENO wird nicht FALSE. -->spukhaft.
Ich führe z.B. eine Berechnung aus
Code:
a - b = c;
IF c < 0 THEN
c := c + 1;
END_IF;
In diesem Beispiel, wenn c < 0 ist, dann wird mir aber nicht - wie erwartet - c inkrementiert, sondern es wird ein Nonsens-Wert auf d geschrieben. (a, b, c, d vom Datentyp INT, während der Berechnung findet kein Überlauf, also Werte größer 32767 oder kleiner -32768 statt) --> spukhaft

@JesperMP
Das mit der Multi-Instanz kann ich mir zwar vorstellen, ist für meine Zwecke allerdings nicht praktikabel, da ich dann anstatt mehrerer kleine, einen großen FB habe. Und dann hab ich wieder Probleme mit der Größe meiner Bausteinschnittstelle. Da bin ich jetzt schon an der Grenze.

Daher fällt mir keine bessere Lösung ein, als den iDB via INOUT zu übergeben. Vor allem auch deswegen, weil ich nicht nur das Sende-Array beschreiben, sondern auch noch zusätzliche 5 Variablen lesen/schreiben möchte (die Verriegelungen, wer gerarde sendet, senden fertig, etc.). Somit möchte ich auch nicht via separate IN und OUT arbeiten.
Deshalb ja meine Frage an euch, ob ihr Erfahrungen in diesem Bereich habt, wie ich das besser lösen könnte. Es kann doch nicht sein, dass Schwarmintelligenz nur was für Bienen und Ameisen ist. Irgendwann müssen auch wir Menschen davon profitieren :p
 
Und wenn du es über einen separaten (globalen) Kommunikations DB machst statt über den Sende iDB? Und dann mit Poke_Blk statt Move_Blk deine entsprechenden Daten verschiebst?
 
@JesperMP
Das mit der Multi-Instanz kann ich mir zwar vorstellen, ist für meine Zwecke allerdings nicht praktikabel, da ich dann anstatt mehrerer kleine, einen großen FB habe. Und dann hab ich wieder Probleme mit der Größe meiner Bausteinschnittstelle. Da bin ich jetzt schon an der Grenze.
Wenn den FIFO Array als InOut deklariert ist, ist den Zugriff innerhalb von den Baustein mittels Pointer. Damit wird den IDB Grösse gar nicht beeinflusst von den FIFO Array. Das war der Punkt von meinen Vorschlag.

[...]Somit möchte ich auch nicht via separate IN und OUT arbeiten.
Also, du willst den Intanz direkt bearbeiten, ausserhalb von den dazuhörige FB. Das geht auch beim Multi-Instanz. Es steht dich ganz frei, ob du die Daten mittels IN und OUT übertragen willst, oder die Instanzdaten direkt zugeht. (das letztere wird von viele als schlechten Programmiestil betrachtet).
 
@Mephisto:
Ich muss gestehen, dass ich zwar dein Problem verstanden habe, nicht aber dessen Begleit-Umstände. Vielleicht erklärst du das noch mal etwas anders - möglicherweise auch mit Code. Dein SCL-Code aus Beitrag #7 sagt mir so gar nichts und die erste Anweisungszeile daraus macht ja auch so schon keinen Sinn.

Prinzipiell: Wenn du BlockMove auf überlappende Speicherbereiche loslassen würdest dann bekämst du eine Fehlermeldung. Aber ... was ist denn mit deinem Datenbereich ? Ist der ggf. "optimiert" ?

Gruß
Larry
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Zum Thema, warum passiert es etwas Spukhaftes:
Von TIA online Hilfe:
Note
Parameter transfer between blocks with optimized access and blocks with standard access
If structures are transferred to the called block as in/out parameters during a block call, they are transferred by default as pointers (Call by reference).
However, this does not apply if the two blocks have different optimization settings: If one of the blocks has the property "Optimized access" and the other block has the property "Standard access", all parameters are always transferred as copies (Call by value).
If the block contains numerous structured parameters, this can quickly lead to the temporary memory area (local data stack) overflowing.
Ist Optimierte Zugang unterschieldich eingestellt für deine FBs bzw. IDBs ?

Egal ob das obengenannte zu den Fall passt, ich wurde aber absolut nicht das Programm so organisieren. Das war ja auch deine Frage ("wie ich das besser lösen kann").

Nebenbei, ich hasse diese Geschichte mit optimiert bzw. nicht-optimiert. Für TIA sollte Siemens sich entschieden haben für einer oder der andere, nicht beide.
 
Jetzt verstehe ich, was du meinst, mit dem InOut. Ich kann das mal versuchen. In dem Fall müsste ich mein Sende-Array in einem globalen DB ablegen. Auch das FiFo könnte ich in einem globalen DB ablegen. Mein Sende-FB greift dann via InOut auf den Sende-Array-DB zu und mein Daten-FB via InOut auf den Sende-FB und den FiFo-DB. Das ist eine Möglichkeit, die ich probieren könnte, obwohl sie mir nicht so gut gefällt, weil ich dann wieder zwei DBs mehr in meinem Programm habe.

Das mit dem schlechten Programmierstil entscheidet sich hier durch den Anwendungsfall. Möchte ich einen Baustein, dessen Code schön zu lesen ist oder möchte ich einen Bautein, dessen Schnittstelle einfach zu beschalten ist. Da diese Bausteine für Kunden entstehen, hab ich mich bewusst für Zweiteres entschieden.

Gibt's noch andere Möglichkeiten wie ich mein Problem lösen könnte?
Oder hat generell wer eine Idee, wie es zu dem Problem (es wird zuwenig/falsch geschrieben) kommen kann?
Eigentlich würde ich lieber die Ursache bekämpfen anstatt das Symptom mittels Workaround "quickNdirty" zu umgehen.
 
Jetzt verstehe ich, was du meinst, mit dem InOut. Ich kann das mal versuchen. In dem Fall müsste ich mein Sende-Array in einem globalen DB ablegen. Auch das FiFo könnte ich in einem globalen DB ablegen.
Ich meinte nur den grossen FIFO als Global-DB anlegen. Ich wurde wie gesagt das ganze mit multi-Instanz zusammenpacken, ausser den grossen FIFO.
Das Anzahl von DBs ist mMn. egal. Wichtig ist ob den Daten und Programstruktur einfach zu verstehen ist, und zuverlässig funktioniert. Das ist nicht quickanddirty.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo!

Ich hab mittlerweile einen Versuch gestartet:
Der Sendepuffer steht nun nicht mehr im Sende-iDB sondern in einem globalen DB. Der Daten-FB(das große FiFo befindet sich nach wie vor im iDB) schreibt die Werte in diesen neuen Global-DB.
Der Sende-FB liest die zu sendenden Daten aus dem neuen Global-DB.

Damit funktioniert das Ganze.
Danke für den Tipp, JesperMP.

Das wäre auch eine Lösung, mit der ich leben könnte. Trotzdem klärt es nicht, warum es nicht mit der ursprünglichen Variante (Zugriff auf iDB) funktioniert.
Hat da jemand eine Idee=
 
@Larry Laffer:
@Mephisto:
Ich muss gestehen, dass ich zwar dein Problem verstanden habe, nicht aber dessen Begleit-Umstände. Vielleicht erklärst du das noch mal etwas anders - möglicherweise auch mit Code. Dein SCL-Code aus Beitrag #7 sagt mir so gar nichts und die erste Anweisungszeile daraus macht ja auch so schon keinen Sinn.

Prinzipiell: Wenn du BlockMove auf überlappende Speicherbereiche loslassen würdest dann bekämst du eine Fehlermeldung. Aber ... was ist denn mit deinem Datenbereich ? Ist der ggf. "optimiert" ?

Das mit dem Code ist natürlich Blödsinn. Soll heißen:
Code:
[FONT=arial][FONT=arial][FONT=courier new]c:= a - b;[/FONT]
[/FONT][FONT=courier new]IF c < 0 THEN
c := c + 1;
END_IF;[/FONT][/FONT]


Wie meinst du das mit BlockMove und optimiert? Meine beiden BlockMove Befehle greifen auf unterschiedliche und nicht angrenzende Bereiche meines FiFos zu und schreiben in unterschiedliche, nicht überlappende, jedoch angrenzende Bereiche in meinem Sende-Array.
Sowohl der Sende-FB als auch der Daten-FB sind optimiert. Gibt es da Probleme mit BlockMove und Optimierung?


 
Zuletzt bearbeitet:
Ist die Variable am Parameter Count vom MOVE_BLK ein statischer Wert oder kann dieser sich dynamisch ändern?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Für Sendedaten würde ich keinen "optimierten" Speicher verwenden, weil Sendedaten immer eine bestimmte Struktur einhalten müssen, die in "optimiertem" Speicher aber umgewürfelt wird - es sei denn die Sendedaten sind als BYTE-Array strukturiert.

Harald
 
Hallo!

Die Länge die es zu kopieren gilt ist variabel (Also der Parameter COUNT am MOVE_BLK)
Die Sendedaten sind ein Array. Ansonst müsste ich alles laut Siemens Hilfe in eine Struktur packen und die übergeben damit die Reihenfolge eingehalten wird.
First-Level wahrscheinlich schon. Eigentlich sollte ich da gar nicht hinkommen, wir sind Solution Partner, aber Siemens nimmt das wohl nicht so genau...
 
Zurück
Oben