TIA Referenz von UDT an Funktion übergeben

worst_case

Level-2
Beiträge
10
Reaktionspunkte
3
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

ich habe in einem DB ein UDT das bool Variablen (High/Low Byte verdreht) beinhaltet.

Meine Variablen heißen dann z.B. ST_mem.message.nr_1, ST_mem.message.nr_2, ST_mem.message.nr_3, ST_mem.message.nr_x,

Jetzt muss eine Funktion her, die Anhand von einer übergebenen Nummer z.B. 123, das 123 Bit in diesem DB/UDT setzt.
Die Adresse des DB/UDT ändert sich während des Programms nicht und der DB ist nicht speicheroptimiert.

Ich habe dazu POKE_BOOL gefunden, sollte das richtige sein, ändert aber nicht das richtige Bit, da er nur auf den Speicher sieht und nicht das UDT erkennt.

Meine Frage ist, wie kann ich die Adresse oder Referenz des DB/UDT so an den FC übergeben ?
Sollte ich im FC das UDT auf TEMP kopieren, dann das Bit setzen/löschen und wieder komplett zurückkopieren ??
Kann ich die slice Anweisung dynamisch machen DB.WORD.%xxxx ?

Hier bräuchte ich einen, oder mehrere Denkanstöße ... ;-)

Danke !!

CPU: S71200
TIA: V19
Sprache: SCL
 
die Struktur per AT mit einem Bool-Array überlagern, dann kannst du auf Array[#Nr] zugreifen

Was heisst "nicht das richtige Bit ändert"?

Falls High/Low-Bytes noch unpassend vertauscht sind, dann nusst du ggf. #Nr erst noch passend umrechnen.

Slice geht nicht mit variablem %x

Vom Smartphone gesendet
 
Falls High/Low-Bytes noch unpassend vertauscht sind, dann musst du ggf. #Nr erst noch passend umrechnen.
etwa so (ungetestet):
Code:
IF ((#Nr / 8) AND 1) <> 0 THEN //Byte-Adresse ungerade?
  #Index := #Nr - 8; //dann Index in das vorherige Byte
ELSE
  #Index := #Nr + 8; //sonst Index in das nächste Byte
END_IF;

#ioArray[#Index] := TRUE;
Frisst TIA die IF-Zeile ohne meckern?
ggf. so formulieren:
Code:
IF (INT_TO_WORD(#Nr / 8) AND 1) <> 0 THEN //Byte-Adresse ungerade?

Für den Fall, dass die Nr per Referenz am FC-Input übergeben wird, die Nr wegen Multitasking vorsichtshalber nur einmal lesen und umkopieren: #Nr := #InNr;

die Formel geht bestimmt auch ohne IF..THEN..ELSE, ist dann aber unverständlicher (und vermutlich uneffizienter?)
 
In SCL mit Ref_To() und Ref(), könnte man so etwas doch bewerkstelligen.
Zum Zugriff dann Dereferenzieren.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

vielen Dank für eure Anregungen. TIA/SCL ist nicht so mein Freund, andere Hochsprachen oder AWL liegen mir besser.
Aber es ist nun mal die S71200.

Eine Kombination aus allem euren Vorschlägen stelle ich mir vor.
Ich denke mal laut, keine Ahnung ob es so, oder ob es überhaupt geht ... ;-)

1. Ich übergebe dem Baustein eine Referenz/Pointer von dem besagten UDT im DB. So eine Art Referenz/Pointer of Byte
2. Da das UDT unterschiedlich groß sein kann (ändert sich nicht zur Laufzeit), 16Bit (2 Byte) -> 128Bit (16 Byte) muss ich den Referenzbereich auf
seine Größe überprüfen, damit ich nicht zu weit schreibe ... geht so etwas überhaupt ?????
3. Anhand der übergebenen Nummer, das "passende" Byte mittels Berechnung Pointeradresse hochzählen.
4. Das Byte auf ein Temp kopieren (AT Bool Array)
5. Das passende Bit setzen und wieder von Temp zurückkopieren in die passende Adresse aus Punkt 3

Hört sich das gut an, dann hätte ich wenigstens einen Plan. ;)

Bitte um Anregungen, ich denke der Punkt 1 gibt vor, ob es überhaupt möglich ist. Je nachdem wie ich es übergebe ... natürlich INOUT.

Vielen Dank
 
Mir würde da folgendes einfallen:

1. Den In/Out als Variant deklarieren.
2. Mit "TypeOf" Prüfen, welche UDT an dem Baustein parametriert wurden.
3. Mit "GetVariant" die Daten zur Bearbeitung ein die entsprechende Struktur im Baustein übergeben.
4. Am Ende der Bearbeitung die Daten über "VariantPut" zurück schreiben.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich würde das Problem wie von The Quest beschrieben mit dem Datentyp Variant und Referenzierung lösen.
Dem Bausteinparameter (Variant) wird die Referenz mittels Ref() übergeben. Im Baustein selbst erfolgt die Verarbeitung dann mit VariantGet (lesen) und VariantPut (beschrieben).

Bei einem Array mit unterschiedlichen Größen kann die Größe über die Funktion TypeOfElements() bestimmt werden. Anschließend können die Daten mit MOVE_BLK_VARIANT umkopiert und verarbeitet werden.

Intern könnte man sich die verschiedenen Strukturen per REF_TO "Struct_Name_xy" anlegen und über #Ref_Struct_Name_xy ?= #Input_Struct; zuweisen und prüfen (IF #Ref_Struct_Name<>NULL ) ob die Referenz erzeugt wurde und dann verarbeiten.
Wäre ein klassische ELSEIF Geschichte.


Code:
 VAR_IN_OUT 
      Input_Data : Variant;
   END_VAR

VAR_TEMP
Ref_Struct_2byte : REF_TO "type2byte";
Ref_Struct_4byte : REF_TO "type4byte";
Ref_Struct_8byte : REF_TO "type8byte";
Ref_Struct_16byte : REF_TO "type16byte";
END_VAR



END_VAR

#Ref_Struct_2byte ?= #Input_Data;   //Input Data Typ Variant
#Ref_Struct_4byte ?= #Input_Data;


IF #Ref_Struct_2byte <> NULL THEN
 ;   //Verabeiten bei 2 Byte Struktur 1
ELSIF #Ref_Struct_4byte <> NULL THEN
 ;   //Verabeiten bei 4 Byte Struktur 1
ELSE
 ;
ENDIF
 
Zuletzt bearbeitet:
Zurück
Oben