TIA FB um beliebig / unbekannt große Strukturen / UDT / Arrays aus optimierten DBs zu Nullen

meikelneit

Level-2
Beiträge
161
Reaktionspunkte
1
Zuviel Werbung?
-> Hier kostenlos registrieren
Schönen guten Morgen,

Ich habe vor kurzem ein bischen mit dem Ablöschen von Daten zu tun gehabt und daraus entstand die Frage in der Thread überschrift. Ich hatte Arrays bis dato oft mit einer FOR-Schleife abgelöscht, wobei ich über den Schleifen indes die Arrayfelder dann mit leeren Felder gleicher Datenstruktur übeschrieben habe. Dabei ist mir aufgefallen das bei großen Felder (länge>5000) je nach CPU sogar bis zu 1ms für einen einzigen Löschvorgang gebraucht werden.
Da konnte ich mit einem MOVE_Variant schon einiges einsparen, das ging Faktor 18 schneller, bei großen Feldern. Das Verhältniss wird unbedeutend bei kleinen Arrays (länge<100).

Mir an jeder Stelle eine gleichartige Struktur im temp an zu klegen die ich dann drüber bügel finde ich nicht elegant. Ich hätte gerne am ende einen FB der mir das handling abnimmt und die Daten mit denen ich es jetzt zu tuen habe sind von Prozess zu Prozess unterschiedlich lang.

Jetzt wollte ich mal in die runde fragen, ich einen TIA-Funktionsbaustein programmieren, der Datenstrukturen unbekannter Länge in einem optimierten Datenbaustein ablöscht, insbesondere solche, die UDTs und Arrays oder Arrays von UDTs enthalten, wobei die Arrays oft mehr als 1000 Felder haben? Und wie kann ich sicherstellen, dass das Ablöschen mehrfach pro Zyklus erfolgen kann, ohne die Zykluszeit zu sprengen?

Ich kenne bis jetzt nur den weg, mir irgendwo ein Array of Byte (10000) hinzulegen, und da rein zu Serialisieren, nur um heraus zu finden wieviele Bytes er dann beschrieben hat. Haltet ihr das für gangbar oder kennt ihr etwas elganteres?

Einen schönen guten Morgen und freundlichen Gruß
Meikelneit
 
Moin Meikelneit,

tatsächlich ist das serialisieren auch mein Weg, um die Länge eines Datenbereichs zu bestimmen. Nicht elegant, aber ich weiß auch keinen anderen Weg.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wie wärs mit Fill bzw. Fill_Block? Du kannst mit Upper und Lower Limit die Array größe bestimmen und dann entsprechend die Anzahl bestimmen.
Bei mehreren gleichen DBs die abgelöscht werden müssen nutze ich immer ein DB der alle Elemente bspw. FALSE hat. Durch eine einfache Zuweisung habe ich dann den zu löschenden DB abgelöscht.
 
Wie wärs mit Fill bzw. Fill_Block? Du kannst mit Upper und Lower Limit die Array größe bestimmen und dann entsprechend die Anzahl bestimmen.
Bei mehreren gleichen DBs die abgelöscht werden müssen nutze ich immer ein DB der alle Elemente bspw. FALSE hat. Durch eine einfache Zuweisung habe ich dann den zu löschenden DB abgelöscht.
Aber es geht ja gar nicht in erster Linie um Arrays mit bekanntem Datentyp.
Der Datentyp ist unbekannt und kann variieren. Vom elementaren Datentypen bis zu UDTs.
 
Fill bzw. Fill_Block kann ch mir anschauen.

Lower und Upper Bound liefern ja erstmal nur die Grenzen des Arrays, womit ich dann per FOR-Schleife den bekannten Typen ablöschen könnte. Ich denke aktuell das schnellste wäre MOVE_Variant, damit dann genau die richtige anzahl an leeren bytes drauf zu schieben. Aktuell ist das die schnellste Methode die ich kenne, vorallem bei großen Feldern. Dazu kommt, es muss nicht zwingend ein Array sein.
 
Ich bleibe im Moment erstmal bei dem Serialisieren denke ich. Das was mich noch stört, ich muss doch immer die maximale Größe vorgeben.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Zudem ist TypeOf(..) soweit ich das sehe, nur für den Vergleich mit einem bekannten Datentypen einsetzbar. Man müsste den Datentypen auslesen können und zur Laufzeit einer Variablen zuweisen können. Das geht aber nicht.
 
Mir an jeder Stelle eine gleichartige Struktur im temp an zu klegen die ich dann drüber bügel finde ich nicht elegant.
Nur als Kommentar.
Schlimmer als nicht elegant, wenn ein TEMP nicht initialisiert ist, enthält es nicht Null sondern 'irgendetwas'.

Anstatt TEMPs mit Nullen, Ich wurde dummy-DBs mit Nullen anlegen.
S7-1500 hat sehr viel Datenspeicher, es lohnt sich nich zu sparen.
Die Programmierung ist triviell.
 
Kann sein man kan davon ausgehen, in TIA und optimierte Bausteine sind TEMPs mit Defaultwerte vorbelegt.
Aber es ist mMn. ganz falsch etwas das in andere Sprachen nie vorbelegt ist in TIA in diese Weise zu 'verbessern'.
 
Um einen Datenbaustein bzw. einen Bereich im DB mit Defaultwerten zu belegen ist auch die Funktion READ_DBL hilfreich
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Um einen Datenbaustein bzw. einen Bereich im DB mit Defaultwerten zu belegen ist auch die Funktion READ_DBL hilfreich
Keine schlechte Idée.
Aber ich denke die Zykluszeit ist länger als mit DBs in RAM. Jeden READ_DBL dauert mehrere Zyklen.
 
Zuletzt bearbeitet:
Das stimmt... vermutlich ist diese Funktion eher dafür gedacht um z. B. per Button am HMI irgendwas wieder auf Default zu schalten.

Ist vermutlich auch Abwägungssache... Per Read_DBL in mehreren Zyklen zurücksetzen oder mittels Loop innerhalb eines Zyklus was wiederum die Zykluszeit erhöht...
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,
am Anfang habe ich es mit dem "FILL_BLK" probiert, allerdings funktioniert das mit UDTs nicht so richtig wenn viele verschiedene Datentypen verwendet werden.
Deswegen lege ich inzwischen einfach eine Variable "Leer" oder "Init" vom Typ UDT im Datenbaustein an die man einfach mit dem MOVE Befehl über die Zielvariabel schreiben kann. Der 2. Vorteil daran ist, das man die Initialwerte einfach im DB ändern kann wenn man es benötigt.
Es funktioniert super auch mit verschachtelten UDTs oder Arrays of UDT
Beim ändern des UDT erfolgt die Aktualisierung so auch gleich zusammen mit den restlichen Variablen
 
Deswegen lege ich inzwischen einfach eine Variable "Leer" oder "Init" vom Typ UDT im Datenbaustein an die man einfach mit dem MOVE Befehl über die Zielvariabel schreiben kann. Der 2. Vorteil daran ist, das man die Initialwerte einfach im DB ändern kann wenn man es benötigt.
Es funktioniert super auch mit verschachtelten UDTs oder Arrays of UDT
Beim ändern des UDT erfolgt die Aktualisierung so auch gleich zusammen mit den restlichen Variablen
Diesen Weg gehe ich mit S7-1200/1500 generell, schon seit Anbeginn. Bei einzelnen Funktionsbausteinen mit einer "Leervariable" im Stat-Bereich. Bei Paketen mit einem extra CONST-DB der von einem Datentyp abgeleitet wird.
Für diese "Konstanten" werden dann auch die Namensregelungen von Konstanten angewendet.
Der Ansatz eignet sich in Grenzen auch für Safety-Anwendungen (klarerweise ohne Arrays).
 
Zurück
Oben