TIA TIA V16 Arrayvergleicher mit Variant selber schreiben

qwsayxqay

Level-1
Beiträge
24
Reaktionspunkte
1
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo miteinander,

ich bin ueber Suchfunktionen auf dieses Forum aufmerksam geworden. Nun habe ich mich registriert, um ein Problem, dass mich seit einigen Tagen beschaeftig zu teilen und evtl Loesungsansaetze gemeinsam zu finden...


Was will ich?:

Ich will einen eigenen Baustein schreiben, mit dem es moeglich ist 2 Arrays miteinander auf Gleichheit ihrer Elemente zu pruefen. Voraussetzung dafuer ist natuerlich, dass die beiden Arrays vom gleichen Datentyp sind und die selbe Laenge haben. Allerdings sollen Datentyp und Laenge der beiden Arrays flexibel sein.

Dies koennte man ja bis jetzt prinzipiell mit den in TIA zur Verfuegung stehen Vergleichern unter "Einfache Anweisungen" tun, indem man den Datentyp Variant auswaehlt. Allerdings moechte ich zusaetzlich, dass die Anzahl der ungleichen Arrayelemente und der Index des ersten ungleichen Arrayelements am Bausteinausgang ausgegeben wird.


Mein Loesungsansatz:

Auf Grund der obigen Beschreibung, bin ich gezwungen, die beiden Arrays als Parametertyp Variant an den Baustein zu uebergeben. Innerhalb des Bausteins kann man dann mit den Variant Anweisung "Is_Array" pruefen, ob es sich um ein Array handelt, mit "typeOfElelents" den Datentyp der Array Elemente ermitteln und mit "countOfElements" die Array Laengen ermitteln.

Zur Pruefung der Array Elemente waere mein Ansatz nun, dass ich die einzelnen Elemente beider Arrays in einer FOR-Schleife mit der Anweisung "MOVE_BLK_VARIANT" einzeln in jeweils eine temp Variable kopiere und diese beiden temp Variablen dann miteinander vergleiche.


Problem:

Bei meinem Loesungsansatz stoeren mich 2 Dinge:

1)
Ich muss die FOR Schleife zur Pruefung der Array Elemente fuer jeden Datentyp einzeln auscodieren. Das ist erstens muehselig, unschoen und hat zusÃaezlich durch die vielen "BLK_MOVE_VARIANT" Anweisungen erhebliche Performance Verluste zur Folge.

2)
Dieser Loesungsansatz wuerde beim Datentyp BOOL schon mal nicht funktionieren, da "BLK_MOVE_VARIANT" keine Arrays of Bool kopieren kann.


Nun meine Frage letztendlich wäre, ob dass was ich vorhabe prinzipiell in TIA rein symbolisch moeglich ist? Mir ist klar, dass es mit Any Pointern, AWL und absoluter indirekte Adressierung moeglich ist, aber genau dass will ich nicht.

Man koennte auch den Parametertyp ARRAY
[*] verwenden. Allerdings muesste man dann fuer jeden Datentyp der Arrays einen eigenen Baustein schreiben, was ich auch nicht unbedingt tun will. Im Idealfall will ich einen Baustein mit dem man Arrays aller Datentypen und variabler Laenge vergleichen kann wie oben beschrieben.

Ich bin mittlerweile der Meinung, dass das so nicht umsetzbar ist, lass mich aber gerne vom Gegenteil ueberzeugen.


Mit besten Gruessen
qwsayxqay
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
@RedCali
Due meinst sicher "LGF_CompareVariant". Ja das ist richtig, dass das da so gemacht wird. Allerdings muss man dann aufwändig auscodieren um Anzahl der unterschiedlichen Elemente und den Index des ersten unterschiedlichen Elements zu erhalten. Ausserdem soll man laut unserem Regelwerk zur Programmierung keine Anweisungen nutzen, die hohe Performance Verluste mit sich tragen und dazu zählt leider auch die "Serialize" Anweisung.

Also dann hätte man nun 2 Möglichkeiten:

1)
Mit "Serialize" Variant Arrays in Arrays of Byte wandeln. Arrays of Byte vergleichen und für die unterschiedlich Datentypen einzeln die Anzahl der unterschiedlichen Elemente und den Index des ersten unterschiedlichen Elements berechnen. Wobei man hier ja im Prinzip das nicht für jeden Datentyp einzeln auscodieren müsste, sondern nur für jede Bitlänge 1Bit, 8Bit, 16Bit, 32Bit und 64Bit und die Datentypen entsprechend ihrer Bitlänge zuordnen.
Einschränkung hier: Kein Datentyp String möglich.

2)
Mein Ansatz mit "BLK_MOVE_VARIANT" mit 1) für Arrays of Bool kombinieren.

Mir gefällt 1) besser.
Bin trotzdem offen für weitere Anregungen.
 
Alte Antwort die nicht geht.....

wegen dem "für jeden Datentyp" ausprogrammieren könntest du auch die beiden Vergleicher Datenpunkte als variant übergeben und dadurch von außen die "Temps" nehme
Dann bleibt es generisch, mann muss dann nur die Array Elementtypen und die TempTypen innen auf Typgleichheit prüfen, dann kommt man ohne serialize aus.

Für Bool würde ich mir eine eigen Funktion schreiben.
 
Zuletzt bearbeitet:
@RedCali:
Ich versteh nicht so ganz was du meinst. Was meinst du mit Vergleicher Datenpunkte? Kannst du das ein bisschen genauer beschreiben?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
ah, mir fällt gerade auf, das ich den "Variant" selbst nicht vergleichen kann.....
Geht so nicht wie ich dachte, war zu schnell geantwortet ohne bis zum Ende zu denken :-(

Du hast im #1 Post eigentlich schon alle Dinge aufgezählt die damit zu tun haben und gehen oder eben nicht gehen
Da die "Variant" variante sich ziemlich schnell aufbläht, würde ich daher ehr auf die Array
[*] variante gehen
Man hat zwar mehr Funktionen, aber dafür muss hier nicht mehr unnötiger Code im Programm mitgezogen werden - das ist aber auch Geschmackssache :-)
 
Warum sollte man einen Variant nicht vergleichen können? In KOP gibts die Vergleicher Bausteine wo man Variant auswählen kann. Und in SCL gehe ich mal davon aus, dass das mit "=" geht.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
.. Zur Pruefung der Array Elemente waere mein Ansatz nun, dass ich die einzelnen Elemente beider Arrays in einer FOR-Schleife mit der Anweisung "MOVE_BLK_VARIANT" einzeln in jeweils eine temp Variable kopiere und diese beiden temp Variablen dann miteinander vergleiche...
Wie würden diese temporären Variablen in deinem Lösungsansatz deklariert sein?
 
Mit dem Datentyp der Array Elemente. Aber wie gesagt ist das schlecht, da man dann für jeden Datentyp einzeln auscodieren müsste.

Habe mittlerweile einen besseren Ansatz gefunden. Und zwar übergebe ich nun einfach 2 zusätzliche Variablen als InOut Parameter an dem Baustein. Dort muss man beim Bausteinaufruf 2 temporäre Variablen anlegen vom selben Datentyp wie die beiden Arrays. Dann kann man in einer FOR-Schleife die Array Elemente einzeln über MOVE_BLK_VARIANT den temp Variablen zuweisen und diese dann prüfen...

Dadurch sollte der Baustein für jeden Datentyp sowie PLC-Datentyp des Arrays funktionieren. Habe es noch nicht getestet, aber den Code habe ich mal mit 0 Fehlern compiliert...
 
Zuviel Werbung?
-> Hier kostenlos registrieren
So hatte ich das in dem Post gemeint / gedacht

Alte Antwort die nicht geht.....
wegen dem "für jeden Datentyp" ausprogrammieren könntest du auch die beiden Vergleicher Datenpunkte als variant übergeben und dadurch von außen die "Temps" nehme
Dann bleibt es generisch, mann muss dann nur die Array Elementtypen und die TempTypen innen auf Typgleichheit prüfen, dann kommt man ohne serialize aus.

Für Bool würde ich mir eine eigen Funktion schreiben.

Aber kann man die beiden übergeben variablen vom Typ Variant vergleichen?
Ich bin gespannt auf das Ergebnis :-)
 
Das weiss ich nicht 100%. Ich würde mal behaupten, dass es geht. Im Endeffekt geben ja die Variantparameter die Adressen + Typinformation von den aussen angelegeten temporären Variablen weiter. Ob ich diese temp Variablen nun direkt in dem Baustein vergleiche (auskodieren für jeden Datentyp notwendig) oder über Variant weitergebe und dann vergleiche sollte ja eigentlich egal sein.

Ich muss es mal nächste Woche testen. Mache dann Meldung.
 
ganz so einfach ist es nicht
Die Frage ist was da verglichen wird - der Variant selbst oder der Inhalt

Versuch macht klug, ich bin gespannt
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich verstehe nicht ganz warum man diesen Aufwand mit MOVE_BLK und Variant treibt, nur um einen Universal-Baustein zu erhalten.
Wenn du einen solchen Baustein als Template beispielsweise für DINT in SCL schreibst und die beiden Arrays als ARRAY* OF DINT übergibst, sind das 6-7 Zeilen SCL-Code.

Dem Programmierer, der den Baustein dann in ein Programm einbindet sollte es zumutbar sein, dass er für jeden Datentypen, bei dem er den Baustein einsetzen will, eine Kopie des Templates macht und den Datentyp auf REAL, STRING oder einen UDT ändert.
Der eigentliche SCL-Code bleibt dann identisch.

Du wirst in jedem Fall durch sehr kurze Laufzeiten belohnt. Variant-Behandlung zur Laufzeit ist bei den S7-1500 bis zur 1516er eine mittlere Ressourcen - Katastrophe.
 
Habe den Baustein wie beschrieben mit Variant getestet. Es funktioniert!

@maxder2te
Das was du schreibst wäre auch mein Ansatz gewesen. Und ich denke es wird auch darauf hinauslaufen. Allerdings wollte ich jetzt doch wissen ob es mit Variant als Universalbaustein geht...
 
Habe den Baustein wie beschrieben mit Variant getestet. Es funktioniert!

@maxder2te
Das was du schreibst wäre auch mein Ansatz gewesen. Und ich denke es wird auch darauf hinauslaufen. Allerdings wollte ich jetzt doch wissen ob es mit Variant als Universalbaustein geht...

Streng genommen geht es nicht universell, sondern nur für jene Datentypen, die du intern explizit ausprogrammierst. Spätestens wenn du PLC-Datentypen einsetzen willst kriegst du einen Vogel, weil du ständig irgendetwas nachpflegen musst.
 
Zurück
Oben