TIA Vergleich/Abfrage eines UDTs

cyborg93

Level-2
Beiträge
51
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,
ich muss folgenden UDT abfragen ob mind. eines der Fehlerbits gesetzt und entsprechend eine Sammelmeldung erzeugen, welche dann zur Auswertung genutzt werden kann (z.B. Anlage in Störung oder nicht):
1756120785638.png

Ich will aber nicht einfach alle einzelnen Einträge mit einer Oder-Verknüpfung abfragen, da wie zu erkennen ist es mehrere Instanzen der Einträge vorhanden sind.
Habt ihr eine Idee/Vorschlag wie man das "clever" anstellen kann?
 
Ich denke du solltest einfach deine Variable stRescourceErrors mit einem Word vergleichen.
Ist das Ergebnis <> W#16#0 dann weißt du, dass einer der Fehler ansteht.

In SCL musst du da ev. mit GATHER/SCATTER arbeiten - da du keinen optimierten Baustein hast, könntest du (nicht empfehlenswert) auch direkt das Word adressmäßig abgleichen
 
Ich will aber nicht einfach alle einzelnen Einträge mit einer Oder-Verknüpfung abfragen, da wie zu erkennen ist es mehrere Instanzen der Einträge vorhanden sind.
Hast du eine Baustein der einen Array Struktur bearbeitet ?
Also, nur eine von die stRessourceErrors, oder mehrere in eine Schleife ?
Für nur 10 Alarmmeldungen wurde ich einfach in diese Baustein eine 'Kein_Fehler' Bit programmieren mit die 10 Alarme als N.C.'s in Reihe. Nur weil es ist kompakter als 10 N.O.'s in parallel.
Diese Bit negiert ist die Sammelfehler.
Mit so wenige Bits lohnt es sich nicht mit mehr komplizierte Lösungen.
 
Das Array "astRecource" könntest du per Schleife durcharbeiten (ist die Schreibweise mit c eigentlich Absicht?).
Der "astResourceError" ist etwas problematischer, da kein Array.
Entweder fragst du die 9 Bits händisch per OR ab oder du machst aus dem UDT per Serialize ein Byte-Array wertest dieses per Maske aus.
Würde bei nur 9 Bits aber eher zur einfachen Lösung per OR greifen, da besser lesbar.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Du könntest von dem UDT_ResourceErrors eine Instanz mit alles 0 anlegen und deine Arbeits-Instanz mit der 0-Instanz vergleichen, der Compiler erzeugt dann (vermutlich) effizienten Code, der alle Variablen in den Instanzen vergleicht - du must das aber nicht selbst tippen.
Etwa so: Sammelfehler := MyInstanz....stResourceErrors <> keinFehler.ResourceErrors;
 
Vielen Dank für die vielen Hinweise. Mit dem Oder-Verknüpfung habe ich auch schon überlegt, aber wie im Screenshot dargestellt, kann ich x-viele astRecource[x] haben und jedes davon hat diese Fehlerbits. Gather/Scatter und For-Schleife geht bei UDTs halt nicht...

Ich habe nun einen kleinen FC geschrieben, der mit Serialize und dann einer IF-Abfrage und For-Schleife das Error-UDT durchgeht und entsprechend die Rückmeldung gibt ob mind. einer der Einträge UngleichNull oder ob alle GleichNull sind.
Den kann ich dann für jede weitere solcher Anwendungen benutzen.
 
Du kannst auch einfach eine temp-Variable "EmptyUdtErrors" mit der UDT_RecourceErrors Struktur und ein "Index" Integer und ein "FoundError" Bool anlegen (schneller als eine statische Instanz); und da temporär ist bei jedem FB-Aufruf erst mal immer alles Null/False. Damit vergleichst du dein stResourceErrors. Wenn ungleich, dann liegt ein Fehler an.

Diesen Vergleich (Einzeiler, kein FC), packst du in eine Schleife und zählst dein Index hoch. Ist nach dieser FOR-Schleife dein Bit "FoundError" TRUE, wurde irgendwo mindestens ein Fehler gefunden.

FOR Index := 1 TO "iConstCountOfRecourcesCon1" DO
IF astRecource[Index].stResourceErrors <> EmptyUdtErrors THEN
FoundError := TRUE;
END_IF;
END_FOR;
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Grundsätzlich hast du jetzt schon einige Lösungsansätze gehört. Ich würde tatsächlich mit dem Vergleich mit einer leeren Struktur arbeiten.

Weiterhin, als Grundsatzleitfaden: Solche Sachen immer am besten als Vielfaches von einem INT Programmieren, d.h. Wenn du 12 Fehler hast, programmierst du 16 Fehler, bei 17 Fehlern sind es 32 Fehlern. Der Rest ist halt reserve.
Folgende Lösung fällt mir dazu ein, da der Baustein ja schon nicht optimiert ist:
1756209334699.png

Für weitere Informationen, guckst du hier.

Somit kannst du Integer, oder Double Integer auf 0 abfragen und der Drops ist gelutscht.
 
Hast du eine Baustein der einen Array Struktur bearbeitet ?
Also, nur eine von die stRessourceErrors, oder mehrere in eine Schleife ?
Ich hätte gerne dies beantwortet.
Wenn die Daten schon in eine Schleife bearbeitet werden, dann wäre es logisch dass die Sammelfehler-Auswertung in dieselbe Schleife gemacht wurde, und nicht in eine weitere eksterne Baustein.
 
Hallo.
Machs dir ganz einfach. Im Baustein deiner Abfrage FB oder FC eine Temporäre Variable vom TYP "UDT_ResourceErrors" anlegen.
Abfrage ->
ohne_Fehler:= DB..UDT_ResourceErrors = Temp UDT_ResourceErrors;
Sammelstörung:= NOT ohne_Fehler;

Da im Baustein am Anfang alle Temoräre Variablen Null sind ist das am einfachsten. Dabei ist es egal optimiert oder nicht.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Da im Baustein am Anfang alle Temoräre Variablen Null sind ist das am einfachsten. Dabei ist es egal optimiert oder nicht.
Das ist nicht korrekt. In nicht optimierten Bausteinen wird TEMP nicht initialisiert. Und in optimierten Bausteinen bei S7-1200/1500 erst ab Firmware V4.0

Also man sollte sich nicht darauf verlassen, sondern immer an die Regel halten: TEMP-Variablen gehören grundsätzlich selbst initialisiert bzw. es muß grundsätzlich erst etwas hineingeschrieben werden, bevor etwas da 'raus gelesen werden darf.
 
Hast du eine Baustein der einen Array Struktur bearbeitet ?
Also, nur eine von die stRessourceErrors, oder mehrere in eine Schleife ?
Für nur 10 Alarmmeldungen wurde ich einfach in diese Baustein eine 'Kein_Fehler' Bit programmieren mit die 10 Alarme als N.C.'s in Reihe. Nur weil es ist kompakter als 10 N.O.'s in parallel.
Diese Bit negiert ist die Sammelfehler.
Mit so wenige Bits lohnt es sich nicht mit mehr komplizierte Lösungen.
Ich habe variabel viele Einträge in dem oberen Array und jedem ist die gleiche Error-UDT vorhanden.

Vielen Dank allen, grundsätzlich hätte es mit einem Vergleich gut funktioniert. Nur sehe ich dabei das Problem falls man die Struktur nachträglich anpasst, muss man auch an die Abfrage denken... "Unnötigerweise" mehr Einträge als notwendig würde ich ungern machen.
Daher bin ich auf meine Lösung doch sehr stolz, damit kann ich jede beliebige Struktur, Array, UDT, etc. abfragen (unabhängig von der Länge und späteren Änderungen)
 
Vielen Dank allen, grundsätzlich hätte es mit einem Vergleich gut funktioniert. Nur sehe ich dabei das Problem falls man die Struktur nachträglich anpasst, muss man auch an die Abfrage denken... "Unnötigerweise" mehr Einträge als notwendig würde ich ungern machen.
Daher bin ich auf meine Lösung doch sehr stolz, damit kann ich jede beliebige Struktur, Array, UDT, etc. abfragen (unabhängig von der Länge und späteren Änderungen)

Du kannst doch ein Array unbestimmter Größe übergeben, die Grenzen per upperbound und lowerbound ermitteln diese Werte in deiner for-schleife benutzen.
 
Zurück
Oben