TIA Variable Übergabe von Datentypen und deren Manipulation.

Tmbiz

Level-2
Beiträge
640
Reaktionspunkte
21
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,

ich würde gerne mal eure Meinung zu der folgenden Anforderung hören:

Ich muss eine Funktion erstellen, mit der ich verschiedene Bits in verschiedenen Datentypen manipulieren kann. Die UDTs sind entweder 8,16 oder 32 Bit lang und in Ihnen ist nur eine entsprechende Anzahl von booleschen Variablen. Also entweder 8, 16 oder 32 Bit. Ich möchte den Datentyp einlesen, einzelne Bit bearbeite und dann wieder in der neuen Form auf den gleichen Datentyp ausgeben (der Speicher ist natürlich ein anderer.

Als In- und Output der Funktion hatte ich z.B. an den Datentyp VARIANT gedacht. Also einlesen, umlegen, bearbeiten und wieder ausgeben. Die Frage ist, ob es noch andere "einfacherer" Möglichkeiten gibt? Wenn ich das mit VARIANT mache, was wäre die beste Möglichkeit die Daten zur Bearbeitung umzuwandeln?
 
Wie wäre es mit:

Variant In -> Datentyplesen -> auf den gleichen Datentyp als temp umlegen -> in die Bits zerlegen mit .%X0 -> temp Datentyp auf Variant Out schreiben

Und jeweils dann ein Flag setzen für den Datentyp vorhalten und bisschen IF.. Geballer machen
 
Oder gleich mit Binärmasken arbeiten und die Bits ein und ausblenden?Wortweise Verunden oder Verodern.Byte,Integer oder Doppelinteger müsste gehen.
Müsste im FUP gehen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wie wäre es mit:

Variant In -> Datentyplesen -> auf den gleichen Datentyp als temp umlegen -> in die Bits zerlegen mit .%X0 -> temp Datentyp auf Variant Out schreiben

Und jeweils dann ein Flag setzen für den Datentyp vorhalten und bisschen IF.. Geballer machen

Das Problem ist, dass jeder Datentyp einmalig ist. Der Name ist einmalig und die Infos darin auch. Identisch ist nur die Länge. Sie kann nur 8, 16 oder 32 Bit lang sein. Daher kann ich nicht (oder glaube es nicht zu können) die Funktion "Type of" verwenden. Ich könnte auch noch 3 Funktionen erstellen. Also eine für 8 Bit, eine für 16 und eine für 32. Das wäre auch kein Problem. Aber theoretisch müsste es alles mit einer zu machen sein.
 
Du kannst mit Bitmasken.KM#111000.. so in etwa Wortweise verunden oder verodern.
Ist jetzt aber s7 klassik.Weiss jetzt aber die Syntax nicht genau.Wenn du jetzt das Urspungswort nimmst und willst ein Bit rücksetzten
nimmst du Undwort und setzt dort das Bit in dem Muster auf Null.Alle anderen Bits müssen auf 1 bleiben.
Bei Oder umgekehrt nur die Bits die du setzen willst müssen auf 1.
Kannst natürlich auch mehrere Setzen bzw. Rücksetzen wenn die Bedingung die gleiche ist.
Muss jetzt aber weg.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Das Problem ist, dass jeder Datentyp einmalig ist. Der Name ist einmalig und die Infos darin auch. Identisch ist nur die Länge. Sie kann nur 8, 16 oder 32 Bit lang sein. Daher kann ich nicht (oder glaube es nicht zu können) die Funktion "Type of" verwenden.
Doch kannst du, geht so:
Code:
IF TypeOf(#IN_VARIANT) = UDT101 THEN
...
IF TypeOf(#IN_VARIANT) = UDT102 THEN
...
IF TypeOf(#IN_VARIANT) = UDT103 THEN
...
 
Wenn das wirklich so viele Verschiedene Datentypen und Anwendungen sind, muss es dann die Eierlegende Wollmichsau in Form eines Bausteins sein oder ist es vielleicht doch besser, wenn man mehrere Anwendungsspezifische Bausteine hat.

Irgendwer muss das Ganze auch im Betrieb mal anschauen und dann ist es halt immer nur so bedingt hilfreich, wenn da ein Baustein x-fach aufgerufen wird, aber immer nur 2 Zeilen Code von hunderten relevant sind - ist aber wohl ansichtssache.
 
Doch kannst du, geht so:
Code:
IF TypeOf(#IN_VARIANT) = UDT101 THEN
...
IF TypeOf(#IN_VARIANT) = UDT102 THEN
...
IF TypeOf(#IN_VARIANT) = UDT103 THEN
...
Bist du sicher? Oder reden wir hier an einander vorbei? Ich habe 60 oder 79 UDT's. Sie haben nur gemeinsam, dass sie entweder 8, 16 oder 32 Bit lang sind. Ich müsste also für jedes mögliche UDT eine IF Abfrage erstellen. Oder kann ich einfach nur die Länge des UDT auslesen?

Wenn das wirklich so viele Verschiedene Datentypen und Anwendungen sind, muss es dann die Eierlegende Wollmichsau in Form eines Bausteins sein oder ist es vielleicht doch besser, wenn man mehrere Anwendungsspezifische Bausteine hat.

Irgendwer muss das Ganze auch im Betrieb mal anschauen und dann ist es halt immer nur so bedingt hilfreich, wenn da ein Baustein x-fach aufgerufen wird, aber immer nur 2 Zeilen Code von hunderten relevant sind - ist aber wohl ansichtssache.
Die Funktion in dem Baustein ist ganz einfach. Er soll nur einzelne Bit bei bedarf manipulieren. Also entweder dauerhaft auf "TRUE" oder "FALSE" setzen. Ich kann auch eine Funktion für 8 Bit, eine für 16 und eine für 32 erstellen. Aber es bleibt die Problematik, dass ich über VariantGet die Infos aus der Variable des Typ VARIANT nicht umwandeln kann. Aber ich kann nicht erkennen, warum es nicht geht.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Kannst du vielleicht von ein paar UDTS (gerne mit gleicher Bitlänge) mal ein Beispiel geben? Im Idealfall auch gerne mit Bitmuster vor und nach deinem Baustein (und soll in dem Baustein die aktuellen Daten gewandelt werden oder soll in einen zweiten Speicherbereich das gewandelte abgelegt werden?).
 
Kannst du vielleicht von ein paar UDTS (gerne mit gleicher Bitlänge) mal ein Beispiel geben? Im Idealfall auch gerne mit Bitmuster vor und nach deinem Baustein (und soll in dem Baustein die aktuellen Daten gewandelt werden oder soll in einen zweiten Speicherbereich das gewandelte abgelegt werden?).
Mal angenommen man übergibt die 8 Bit einer Eingangskarte (ET200) auf einen Speicherbereich von Type "typeIO_DI_10". Die zweite Eingangskarte auf "typeIO_DI11" usw. Alle UDT's sind 8 Bit lang. Also alle Eingänge der SPS werden übergeben und in der Funktion gibt es die Möglichkeit verschieden einzelne Bit zu manipulieren.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wie wärs mit Serialize auf ein Byte-Array zu schreiben und die Länge dann bei Pos(?) abzulesen?
So mache ich das in Ermangelung einer Alternativen Methode.
Habe ich tatsächlich auch schon temporär eingesetzt, um die Länge eines Arrays zu ermitteln und danach wieder gelöscht.

@Siemens: die Serialize-Funktion zeigt ja, dass es möglich ist die Arraylänge zu ermitteln und es sogar schon umgesetzt wurde. Könnt ihr da nicht einen einfachen Baustein für schreiben?
 
Was mir noch nicht klar ist bei der Aufgabe.Du schreibst du willst einzelne Bits manipulieren.
Dann must du ja von aussen diese Bits vorgeben die du manipulieren willst?
Würde ja bedeuten du musst im programmcode immer was ändern, wenn andere Bits manipuliert werden sollen.
Oder verstehe ich das falsch?

Wenn TIA diese Wortverknüpfungen zulässt bei Integer,Doppelinteger,Byte kannst du das Wort übergeben das manipuliert werden soll..
Von aussen ein Bitmuster setzen,Bitmuster rücksetzen, die Bedingung für den Setz/Rücksetzvorgang und die Ausgabe.
Mir erschliesst sich noch nicht der Sinn eines Bausteins, wenn du nicht immer die gleichen Bits anlangst.
Das man dann 3 Bausteine hat finde ich jetzt nicht so kriegsentscheidend.Gerade der Sinn in der Funktion was zu manipulieren verstehe ich nicht.
Das muss doch alles von aussen kommen.
 
Ich habe 60 oder 79 UDT's. Sie haben nur gemeinsam, dass sie entweder 8, 16 oder 32 Bit lang sind. Ich müsste also für jedes mögliche UDT eine IF Abfrage erstellen.
Man muss ja nicht für jedes Eingangsbyte einen eigenen UDT erstellen ... oder braucht halt für jeden UDT einen eigenen Manipulations-Baustein, oder eigene Konvertierungs-Methoden, die die UDT von/zu DWORD konvertieren.
Der Sinn deines Monster-Alleskönner-Bausteins erschließt sich mir auch nicht. Da soll jetzt mit riesen Aufwand ein Baustein geschaffen werden, der wegen Konzeptfehlern mit allen möglichen Datentypen umgehen können soll, den am Ende höchstens nur noch du selber verstehst ...
Das "schöne" an Variant ist, dass Siemens damit eine Möglichkeit geschaffen hat, die die früher üblichen wilden ANY-Pointer-Basteleien wirksam verhindert.
 
Sehe das ähnlich, vom Konzept her kann man doch mit einem Byte genug Kombinationen erfassen, wenn man eine eigene
Zustandsvariable generiert.(256).
Die könnte man dann sogar mit Bit 0..7 am Eingang es Bausteins setzen(1) und rücksetzen(0).
8 Eingänge am Baustein sind darstellbar.Aus Bits ein Byte machen und das wars.
Das Problem ist das man bei solchen Anfragen nie genau weiss, was gemacht werden soll.
 
Hallo zusammen,

danke euch für die Unterstützung. Ich habe noch einmal intensiv mit verschiedenen Kollegen und Verantwortlichen gesprochen. Nun zeigt sich, dass ich nicht grundsätzlich jedes Bits manipulieren muss, sondern nur ganz bestimmte. Daher brauch ich auch nicht mehr die beschriebene Funktion. Aber grundsätzlich ist es so, dass man zwar von einem in das andere UDT schreiben kann, wenn sie gleich aufgebaut sind aber nicht wenn man über VARIANT geht. Dann muss es das identische UDT sein.
 
Zurück
Oben