TIA Gesammten Datenbausstein auswerten

S7Anfänger

Level-2
Beiträge
291
Reaktionspunkte
2
Zuviel Werbung?
-> Hier kostenlos registrieren
Moin zusammen,

Ich habe einen Datenbaustein mit den ganzen Störmeldungen aus meiner Programmierung; Also alles einzelne Bits.
Jetzt bin ich am überlegen, ob man diesen Datenbaustein nicht einfach mit einer Zahl vergleichen kann um damit dann die Störmeldung auszugeben.

z.B: im DB5 sind 16 Störmeldungen, die alle ein 0-Signal führen und nur im Fehlerfall die entsprechende Störung auf 1
Könnte man jetzt nicht einfach das DB5 nehmen und auf "größer" "0" vergleichen.
Wenn dann irgend eine Störmeldung auf 1 geht, müsste der Vergleich doch auf 1 gehen und meine Störmeldeleuchte leuchtet.

oder klappt das alles nicht?
Wollte damit vermeiden, alle Störmeldungen auf ein "oder" zu legen und dann auszuwerten.


Beste Grüße
Hagen
 
Also der Datentyp der der einzelnen Fehlermeldungen ist Bool. Arbeiten tue ich mit TIA V15.1
Und Programmiersprache ist FUP
 
Ich habe einen Datenbaustein mit den ganzen Störmeldungen aus meiner Programmierung; Also alles einzelne Bits.
(...)
Wenn dann irgend eine Störmeldung auf 1 geht, müsste der Vergleich doch auf 1 gehen und meine Störmeldeleuchte leuchtet.
Du willst also wissen, ob irgendeines der Störmeldebits aktiv (also 1) ist. Dazu müsstest Du jedes Störmeldebit checken (zumindest solange bis Du ein aktives Bit gefunden hast.) Ob Du das Überprüfen mit einer langen OR-Kette machst oder ob da eine (D)WORD-Zusammenfassung oder eine Schleife geht oder der Vergleich mit einem Speicherbereich mit alle-0-Bits günstiger ist kommt darauf an, wie Dein bisheriges Programm aussieht und was für eine SPS Du hast.

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Der SCL Code fragt die Länge deines DBs ab und geht in einer For Schleife jedes Byte durch, ob hier ein Bit gesetzt ist.
Habe den Code allerdings nicht getestet.

Code:
#tmp := ATTR_DB(REQ := true, DB_NUMBER := #DEIN_MELDE_DB_NR, DB_LENGTH => #lenght, ATTRIB => #attrib); //DB Länge in Byte
#tmp_int := UDINT_TO_INT(#lenght);  // Konvertiere zu Int
FOR #x := 0 TO #tmp_int DO
    #tmp_byte := PEEK(area := 16#84, dbNumber := #DEIN_MELDE_DB_NR, byteOffset := #x);  //Hole das Byte aus dem DB
    #neuer_Alarm := #tmp_byte <> 0;  // Ist ein Bit in dem Byte gesetzt
END_FOR;


#x ist eine temp Variable vom Typ int
 
Der SCL Code fragt die Länge deines DBs ab und geht in einer For Schleife jedes Byte durch, ob hier ein Bit gesetzt ist.
Funktioniert der Code auch auf einer S7-1200? (welche SPS der OP hat, ist noch nicht aufgeklärt)
Weitere unbestätigte Annahmen:
Woher weißt Du, daß die ganzen Störmeldebits ohne andere Bits dazwischen in lückenlos hintereinanderliegenden Bytes liegen?
Woher weißt Du, daß die DB "Standard"-Zugriff haben und nicht etwa "optimiert" sind?

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Mich stört an dem gezeigten Code viel mehr, dass ein evtl. True-Zustand von '#neuer_Alarm' weder bis zum SchleifenEnde (durch Setzen bzw. verODERn) gerettet wird noch zum Abbruch der Schleife führt und damit den True-Zustand nach der Schleife abfragbar zur Verfügung stellt. ;)
In der gezeigten Form wird '#neuer_Alarm' nach der Schleife nur True sein, wenn (zufällig!) das zuletzt geprüfte Byte <>0 ist.
 
Also das Programm ist noch nicht komplett fertig. Es können durchaus noch mehrere Störungen dazukommen.
Diese Störungen kommen von ausgelösten Motorschutzschaltern oder falsche Messwerte und so weiter, die ich dann einzeln auf einen "DB Störungen" als BOOL lege.
Um dann eine Sammelstörung als LED am Schaltschrank darzustellen, kahm mir halt der Gedanke, das man vielleicht den gesamten Inhalt des DB mit dem Zahlenwert 0 vergleichen kann. Sobald der DB Inhalt größer 0 = LED "Sammelstörung" an.
Aber wenn es so aufwendig ist, dann nehme ich mir wieder alle einzelnen Meldungen aus dem DB auf ein OR und steuere damit die LED an.
 
Aber wenn es so aufwendig ist, ...
Aufwändig muss es doch nicht sein, das wurde Dir hier schon mehrfach nahegelegt.
Und erweiterbar (bzw. von vornherein mit Reserve zu planen) ist ein Array allemal - auch mit einer evtl. Kopie des Arrays zum Vergleichen auf <>0.
Die "händischen EinzelBits" lassen sich auch als Bestandteil einer Struktur anlegen, die die Gesamtheit der enthalten Bits mit einem (einzigen) symbolischen Namen aufrufbar macht.

PS:
Bitte mach Dich von dem Ziel frei, einen kompletten DB zu vergleichen. Wenn die o.g. Struktur das einzige ist, was Du in diesem DB benutzt/belegt hast, dann ist die Struktur doch (zufällig) identisch mit dem kompletten DB. Bei einer Struktur "weiss die Steuerung", was wie verglichen werden muss.
Bei einem DB "ohne Struktur" ist die Steuerung da hilflos.
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
In der gezeigten Form wird '#neuer_Alarm' nach der Schleife nur True sein, wenn (zufällig!) das zuletzt geprüfte Byte <>0 ist.
Das stimmt wohl :) Das könnte man durch ein IF leicht ändern, damit das Bit nur dann gesetzt wird, wenn ein Byte <> 0 ist, aber nicht zurückgesetzt wird.

Funktioniert der Code auch auf einer S7-1200? (welche SPS der OP hat, ist noch nicht aufgeklärt)
Weitere unbestätigte Annahmen:
Woher weißt Du, daß die ganzen Störmeldebits ohne andere Bits dazwischen in lückenlos hintereinanderliegenden Bytes liegen?
Woher weißt Du, daß die DB "Standard"-Zugriff haben und nicht etwa "optimiert" sind?

Harald
Funktioniert natürlich nur, wenn der DB auch tatsächlich nur die Störmeldebits enthält. Das geht nicht ganz aus den Aussagen des OP her. Lückenlos ist dabei nicht das Problem, es darf halt nur nix anderes in dem DB gespeichert werden.
Der DB darf dabei nicht optimiert sein! Habe ich vergessen dazu zu schreiben
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Der obige Code funktioniert auf einer 1500er. Habe ich gerade in PLCSim getestet. Man muss lediglich noch eine IF Anweisung hinzufügen, damit #neuer_Alarm nur gesetzt wird, wenn ein Bit gesetzt ist.
Den DB noch auf nicht optimiert setzen und fertig.
 
Der SCL Code fragt die Länge deines DBs ab und geht in einer For Schleife jedes Byte durch, ob hier ein Bit gesetzt ist.
Habe den Code allerdings nicht getestet.
Wir haben sehr viele Fehlermeldungen in unserem DB. Deshalb sind wir bei dem Vergleicher auf DWORD (PEEK_DWORD) umgestiegen. Das spart einiges an Zykluszeit.
 
Warum macht ihr nicht ein Array of Bool? Man kann doch wunderbar mit ein paar Zeilen große Mengen bearbeiten
( und auch die Menge der Meldungen / Funktionen schnell oder variabel anpassen )

Code:
VAR
    Fehlermeldung : ARRAY [1..1000] OF BOOL;
    i : INT;
    fehlerStehtAn : BOOL;
END_VAR

// 1000 Fehlermeldungen abloeschen:
FOR i := 1 TO 1000 DO
    Fehlermeldung[i] := FALSE;
END_FOR;

// 1000 Fehlermeldungen auswerten ( min eine steht an )
fehlerStehtAn := FALSE;
FOR i := 1 TO 1000 DO
    IF Fehlermeldung[i] THEN
        fehlerStehtAn := TRUE;
        EXIT;
    END_IF;
END_FOR;

Das muss ja jetzt nicht die Musterlösung sein, ich habe das nur mal frei runtergetippt.
 
Zuletzt bearbeitet:
Zurück
Oben