TIA Array of bool in Array of word schreiben TIA v18

Zuviel Werbung?
-> Hier kostenlos registrieren
Habe heute erst gemerkt das die Datei gar nicht hochgeladen wurde:ROFLMAO:.
Projekt ist natürlich zu groß!:rolleyes:
Daher habe ich eine Bibliothek erstellt. Bitte mal gucken ob alles enthalten ist!
 

Anhänge

  • Meldesystem_LIB.zip
    1,8 KB · Aufrufe: 8
Ich persönlich würde die Überlagerung nutzen, weil Du eh' einen FB hast:
1701272488385.png

Dann kannt Du unabhängig von der Firmware diese beiden Regionen komplett rauswerfen:
1701272602211.png

Wann immer #STAT_Meldungen[#i] ein Wert zugewiesen wird, steht der dann auch automatisch in #STAT_Meldungen_to_Word[#j].%Xzz.
Ganz ohne weiteren Code.


Das Gleiche für die Störungen:
1701273317152.png


Für die beiden Variablen ohne das "to_Word" die Remanenz auf "Im IDB setzen" umstellen und dann bei den Variablen mit dem "to_Word" bei Datentyp (ohne den bereits vorhandenen Typ vorher zu löschen!) einfach nur ein AT eingeben und Enter.
Das AT wandert dann wie im Screenshot zu sehen nach vorne und der schon vorhandene Datentyp wird die Überlagerung.


PS:
Die BYTE-Stellung im WORD muss aufgrund des BigEndian beachtet werden.
Mit der Überlagerung wird z.B. aus #STAT_Meldungen[0] das #STAT_Meldungen_to_Word[0].%X8 (und nicht %X0)!
Da weiß ich gerade nicht, wie das bei GATHER ist.
 
Zuletzt bearbeitet:
PS:
Die BYTE-Stellung im WORD muss aufgrund des BigEndian beachtet werden.
Mit der Überlagerung wird z.B. aus #STAT_Meldungen[0] das #STAT_Meldungen_to_Word[0].%X8 (und nicht %X0)!
Da weiß ich gerade nicht, wie das bei GATHER ist.
Gather beachtet die BYTE-Reihenfolge im WORD.
Somit wird #STAT_Meldungen[0] also zu #STAT_Meldungen_to_Word[0].%X0.

Das ist beim Überlagern logischerweise nicht der Fall, da es ja die selben Bits/Daten sind wie das überlagerte BOOL-Array.
 
Gather beachtet die BYTE-Reihenfolge im WORD.
Somit wird #STAT_Meldungen[0] also zu #STAT_Meldungen_to_Word[0].%X0.

Das ist beim Überlagern logischerweise nicht der Fall, da es ja die selben Bits/Daten sind wie das überlagerte BOOL-Array.
das bedeutet sozusagen das, dass Low- und High- Byte vertauscht sind!
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich persönlich würde die Überlagerung nutzen, weil Du eh' einen FB hast:
Anhang anzeigen 73373

Dann kannt Du unabhängig von der Firmware diese beiden Regionen komplett rauswerfen:
Anhang anzeigen 73374

Wann immer #STAT_Meldungen[#i] ein Wert zugewiesen wird, steht der dann auch automatisch in #STAT_Meldungen_to_Word[#j].%Xzz.
Ganz ohne weiteren Code.


Das Gleiche für die Störungen:
Anhang anzeigen 73376


Für die beiden Variablen ohne das "to_Word" die Remanenz auf "Im IDB setzen" umstellen und dann bei den Variablen mit dem "to_Word" bei Datentyp (ohne den bereits vorhandenen Typ vorher zu löschen!) einfach nur ein AT eingeben und Enter.
Das AT wandert dann wie im Screenshot zu sehen nach vorne und der schon vorhandene Datentyp wird die Überlagerung.


PS:
Die BYTE-Stellung im WORD muss aufgrund des BigEndian beachtet werden.
Mit der Überlagerung wird z.B. aus #STAT_Meldungen[0] das #STAT_Meldungen_to_Word[0].%X8 (und nicht %X0)!
Da weiß ich gerade nicht, wie das bei GATHER ist.

Habe das jetzt ausprobiert - hat funktioniert. Danke für die Hilfe (an Alle)
 
So habe noch ein anderes Problem!
Anhand des Bildes ist zu sehen das ich zum Schluss mit Rotiere Rechts (ROR) das Low- und Highbyte tausche.
Soweit funktioniert es, aber wenn z.B. die Störung 1 ansteht werden alle anderen Störungen (2-10) nicht mehr angezeigt.
Andersrum wenn z.B. die Störung 10 ansteht und es kommen die unteren Störungen (9-1) dann funktioniert es.
Ich weiß schon das es an der ROR Funktion liegt aber finde keine elegantere Lösung dazu.
Schwierigkeit ist immer noch das sich die Anzahl der Wörter (in Verbindung mit der Anzahl der Störmeldungen) verändern kann - daher auch die FOR - Schleife!
Zusätzlich wäre das "AT" in der Schnitstelle zu beachten!!!
Ich könnte auch das mit dem Low-Highbyte tauschen sein lassen, aber ich weiß das irgend wann ein Kollege nicht klar kommt damit 😅
Daher will ich es so einfach wie möglich für die weniger erfahrenen Kollegen gestalten.
 

Anhänge

  • Low_High_Byte.jpg
    Low_High_Byte.jpg
    681,5 KB · Aufrufe: 23
Moin Smarty160484,

warum liegt das Problem am ROR? Das habe ich noch nicht ganz verstanden.

Davon abgesehen noch zwei Tipps für einen "eleganteren" Code:

IF:
Code:
IF #boolBedinung = TRUE THEN // nicht elegant
    doSomething;
END_IF;

// besser:
IF #boolBedingung THEN
    doSomething;
END_IF;

// negiert:
IF NOT #boolBedingung THEN
    doSomething;
END_IF;

FOR:
Code:
FOR #i := 0 TO 9 BY 1 DO // nicht elegent
    #doSomething[#i] := TRUE;
END_FOR;   

// "BY 1" ist in einer FOR-Schleife die default-Schrittweite.
// Deshalb kann es entfallen.
FOR #i := 0 TO 9 DO
    #doSomething[#i] := TRUE;
END_FOR;
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Soweit funktioniert es, aber wenn z.B. die Störung 1 ansteht werden alle anderen Störungen (2-10) nicht mehr angezeigt.

Weil du die Schleife verlässt.

Die darf nicht verlassen werden. Allerdings musst du dann die OUT_Störung_aktiv ändern. Vor der Schleife ein Bool mit False initialisieren. An der Stelle, wo OUT_Störung_aktiv gesetzt wird das Bool auf True setzen (aber nicht auf False im Else Zweig). Nach der Schleife auf das Bool schauen und damit dann OUT_Störung_aktiv setzen.
 
Weil du die Schleife verlässt.

Die darf nicht verlassen werden. Allerdings musst du dann die OUT_Störung_aktiv ändern. Vor der Schleife ein Bool mit False initialisieren. An der Stelle, wo OUT_Störung_aktiv gesetzt wird das Bool auf True setzen (aber nicht auf False im Else Zweig). Nach der Schleife auf das Bool schauen und damit dann OUT_Störung_aktiv setzen.
ok, gucke ich mir mal an. Danke erstmal 🙋🏼‍♂️
 
Weil du die Schleife verlässt.

Die darf nicht verlassen werden. Allerdings musst du dann die OUT_Störung_aktiv ändern. Vor der Schleife ein Bool mit False initialisieren. An der Stelle, wo OUT_Störung_aktiv gesetzt wird das Bool auf True setzen (aber nicht auf False im Else Zweig). Nach der Schleife auf das Bool schauen und damit dann OUT_Störung_aktiv setzen.
kannst du das noch mal detaillierter schreiben?

bzw. zeigen?

FOR #TEMP_Index_Störung := 0 TO #Anzahl_Störungen BY 1 DO

IF #STAT_Störungen[#TEMP_Index_Störung] = TRUE
THEN
#STAT_Störungen_gespeichert[#TEMP_Index_Störung] := TRUE;
#OUT_Störung_aktiv := TRUE;
#OUT_Störung_aktuell := #TEMP_Index_Störung;
EXIT;
ELSE
#OUT_Störung_aktiv := false;
#OUT_Störung_aktuell := 0;
END_IF;

IF #IN_Quit = TRUE
THEN
#STAT_Störungen_gespeichert[#TEMP_Index_Störung] := FALSE;
END_IF;

FOR #TEMP_index_Störungen_Word := 0 TO #Anzahl_Störungen_to_Word BY 1 DO
#STAT_Sörungen_Word [#TEMP_index_Störungen_Word] := ROL(IN := #STAT_Störungen_to_Word [#TEMP_index_Störungen_Word], N := 8);
END_FOR;

END_FOR;
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Moin Smarty160484,

warum liegt das Problem am ROR? Das habe ich noch nicht ganz verstanden.

Davon abgesehen noch zwei Tipps für einen "eleganteren" Code:

IF:
Code:
IF #boolBedinung = TRUE THEN // nicht elegant
    doSomething;
END_IF;

// besser:
IF #boolBedingung THEN
    doSomething;
END_IF;

// negiert:
IF NOT #boolBedingung THEN
    doSomething;
END_IF;

FOR:
Code:
FOR #i := 0 TO 9 BY 1 DO // nicht elegent
    #doSomething[#i] := TRUE;
END_FOR;  

// "BY 1" ist in einer FOR-Schleife die default-Schrittweite.
// Deshalb kann es entfallen.
FOR #i := 0 TO 9 DO
    #doSomething[#i] := TRUE;
END_FOR;
Das stimmt das man einiges weglassen kann, aber es ist für meine Kollegen ersichtlicher und verständlicher.
Man bedenke, das ich der einzige bin der sich zur Zeit mit SCL beschäftigt bzw. Programmiert und unserer jungen Kollegen sind noch nicht so weit!😅
 
Hab es jetzt herausgefunden - der "EXIT" Befehl war der Krösus Knaktus 🫣
Ohne dem "EXIT" macht der Baustein was er soll!🥳

FOR #TEMP_Index_Störung := 0 TO #Anzahl_Störungen BY 1 DO

IF #STAT_Störungen[#TEMP_Index_Störung] = TRUE
THEN
#STAT_Störungen_gespeichert[#TEMP_Index_Störung] := TRUE;
#OUT_Störung_aktiv := TRUE;
#OUT_Störung_aktuell := #TEMP_Index_Störung;
EXIT;
ELSE
#OUT_Störung_aktiv := FALSE;
#OUT_Störung_aktuell := 0;
END_IF;

IF #IN_Quit = TRUE
THEN
#STAT_Störungen_gespeichert[#TEMP_Index_Störung] := FALSE;
END_IF;

FOR #TEMP_index_Störungen_Word := 0 TO #Anzahl_Störungen_to_Word BY 1 DO
#STAT_Sörungen_Word [#TEMP_index_Störungen_Word] := ROL(IN := #STAT_Störungen_to_Word [#TEMP_index_Störungen_Word], N := 8);
END_FOR;

END_FOR;
 
Das mit dem #OUR_Störung_aktiv funktioniert aber damit noch nicht. Es wird so nur dann gesetzt, sofern das oberste Bit gesetzt ist. Zudem hast du noch eine Schleife in der Schleife, das soll wohl auch nicht so sein? Wenn du den Code als Code postest gehen auch die Einrückungen nicht verloren. #OUT_Störung_aktuell soll ja immer die erste Störung darstellen? Dann darf die auch nur bei der ersten Störung beschrieben werden. So ungefähr:

Code:
#TempBool := FALSE;

FOR #TEMP_Index_Störung := 0 TO #Anzahl_Störungen DO
    IF #STAT_Störungen[#TEMP_Index_Störung] THEN
        #STAT_Störungen_gespeichert[#TEMP_Index_Störung] := TRUE;
        //#OUT_Störung_aktiv := TRUE;
       IF NOT #TempBool THEN
               #OUT_Störung_aktuell := #TEMP_Index_Störung;
       END_IF;
        #TempBool := TRUE;
        //EXIT;
    ELSE
        //#OUT_Störung_aktiv := false;
        //#OUT_Störung_aktuell := 0;
    END_IF;
    IF #IN_Quit THEN
        #STAT_Störungen_gespeichert[#TEMP_Index_Störung] := FALSE;
    END_IF;
END_FOR;

#OUT_Störung_aktiv := #TempBool;

FOR #TEMP_index_Störungen_Word := 0 TO #Anzahl_Störungen_to_Word DO
    #STAT_Sörungen_Word [#TEMP_index_Störungen_Word] := ROL(IN := #STAT_Störungen_to_Word [#TEMP_index_Störungen_Word], N := 8);
END_FOR;
 
Zurück
Oben