TIA 4 Byte OW -> Real in SCL

volker

Supermoderator
Teammitglied
Beiträge
5.891
Reaktionspunkte
1.063
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo

Habe hier folgendes Problem.
Bekomme von einem IO-Link Device diverse Daten. U.a auch Werte vom Typ Real.
Die 4 Byte verknüpfe ich mit OW.
In AWL und FUP funktioniert das tadellos.
In SCL nicht.
Der Compiler meint wohl besser zu wissen was ich will. 🤧
Jedenfalls meint er das währe ein DINT

Jemand ne Idee wie ich das auch in SCL bewerkstellige?
1660127883395.png

EDIT:
TIA 15.1 mit einer 1516F
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
PS: Man muss das zusammenbasteln der 4 Bytes zu REAL nicht so überaus umständlich machen. Effizienter geht es so:
REAL aus 4 Bytes zusammenbauen
(...)
So ist recht effizient jede beliebige Byte-Reihenfolge möglich:
Code:
#tmpDword.%B3 := #Byte_1;
#tmpDword.%B2 := #Byte_2;
#tmpDword.%B1 := #Byte_3;
#tmpDword.%B0 := #Byte_4;
#MyReal := DWORD_TO_REAL(#tmpDword);

Mit Deinen Variablen:
Code:
#tmpDword.%B3 := "IOL_Record_DB".Data[0];
#tmpDword.%B2 := "IOL_Record_DB".Data[1];
#tmpDword.%B1 := "IOL_Record_DB".Data[2];
#tmpDword.%B0 := "IOL_Record_DB".Data[3];
#Wert_Real := DWORD_TO_REAL(#tmpDword);

Harald
 
U.a auch Werte vom Typ Real. Die 4 Byte verknüpfe ich mit OW.
In AWL und FUP funktioniert das tadellos.
In SCL nicht.
Aus reiner Neugier: darf man erfahren, wozu Du die 4 Bytes einer RealZahl per ODER miteinander verknüpfen willst?
Ich kann in dieser Übung leider keinen "Nährwert" erkennen. Das Ergebnis könnte man allenfalls erfolgreich mit 0 vergleichen und könnte erfahren, ob die so "komprimierte" Zahl = 0 ist oder nicht. Aber das kann man doch auch viel einfacher haben ...
 
volker bekommt per Kommunikation 4 (oder mehr) Bytes rein. 4 Bytes davon sind ein REAL-Wert. Er will oder kann die 4 Bytes nicht direkt als REAL deklarieren (möglicherweise ist da wechselnder Inhalt drin), deshalb muß er die 4 Bytes zu einem REAL zusammenbasteln - also erst 4 Bytes zu 32 Bit DWORD zusammenstellen und dann das Bitmuster des DWORD in eine REAL-Variable schreiben.

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Aus reiner Neugier: darf man erfahren, wozu Du die 4 Bytes einer RealZahl per ODER miteinander verknüpfen willst?
Ich kann in dieser Übung leider keinen "Nährwert" erkennen. Das Ergebnis könnte man allenfalls erfolgreich mit 0 vergleichen und könnte erfahren, ob die so "komprimierte" Zahl = 0 ist oder nicht. Aber das kann man doch auch viel einfacher haben ...
Die ODER wird pro bit aufgeführt. Nicht als ein einzelne BOOL. Man nennt das 'Word-Logik' (in diesen Fall 'Byte-Logik' ?).
Volker's verfahren sollte funktionieren.
Harald's verfahren ist viel einfacher.

Kann die IO-Link daten nicht als REAL deklariert werden, anstatt als 4 BYTEs ? Oder ist die BYTE Reihenfolge vertauscht ?
 
..., deshalb muß er die 4 Bytes zu einem REAL zusammenbasteln - also erst 4 Bytes zu 32 Bit DWORD zusammenstellen und dann das Bitmuster des DWORD in eine REAL-Variable schreiben.
Ja, das macht allerdings Sinn. Nur das hatte ich anfangs aus der Aufgabenstellung nicht herausgelesen. Ich hatte die SCL-Variante mit der Schieberei einfach ignoriert und im AWL-Code keinerlei Schieberei gesehen (man sieht lediglich an den Werten, dass sie bereits passend geschoben sind).
Bin ausserdem voll auf die VariablenNamen hereingefallen, die nicht gerade das aussagen, was die Variablen beinhalten/bedeuten und man sieht die Deklaration der Variablen nicht.
Anscheinend hatte der Compiler ähnliche Probleme damit, was das Erraten der erforderlichen, impliziten DatenTypWandlungen betrifft. ;)
Die ODER wird pro bit aufgeführt. Nicht als ein einzelne BOOL. Man nennt das 'Word-Logik' (in diesen Fall 'Byte-Logik' ?).
Ja, das kenne ich zur Genüge. Das nennt man (für meine Begriffe irreführenderweise) "bitweise Verknüpfung".
In diesem Fall also weder Byte-Logik noch Word-Logik, sondern DoppelWortLogik.
Volker's verfahren sollte funktionieren.
Im Prinzip ja, wenn die nicht gezeigten Befehle tatsächlich vorhanden sind und wenn nicht die entsprechenden DatenTypKonvertierungen fehlen würden.
Harald's verfahren ist viel einfacher.
Ja, weil er Schreibweisen nutzt, die aber nicht jeder Compiler kennt. Die Schöpfer der Compiler haben mittlerweile anscheinend eingesehen, dass ein Bedarf dafür herrscht, aber leider unterschiedliche Lösungswege realisiert.
Kann die IO-Link daten nicht als REAL deklariert werden, anstatt als 4 BYTEs ? Oder ist die BYTE Reihenfolge vertauscht ?
Kann man (z.B. per UDT), aber wahrscheinlich muss Volker trotzdem selbst vorher dafür sorgen, dass die Bytes auch dort landen, wo sie hingehören.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Harald's verfahren ist viel einfacher.
Ja, weil er Schreibweisen nutzt, die aber nicht jeder Compiler kennt. Die Schöpfer der Compiler haben mittlerweile anscheinend eingesehen, dass ein Bedarf dafür herrscht, aber leider unterschiedliche Lösungswege realisiert.
Die Slice-Adressierung kennt TIA und vermutlich auch Codesys (???, kennt zumindest Bitzugriff). Ist also bei SPS-Programmierung gar nicht so exotisch.

SPS-Programmierer verwenden allerdings lieber Verfahren, die es schon länger als 20 Jahre gibt - die kann man in der Regel bei anderen Programmierern oder Projekten abschreiben, wenn man es nicht selbst hinbekommt. ;)

Für das Verfahren des scheibchenweisen ("slice") zusammenbasteln von Bytes zu größeren Datentypen nutzt man eigentlich allgemein UNIONs, die in TIA/SCL per AT-Sicht realisierbar sind. Allerdings erlaubt TIA die Verwendung von AT im Zusammenhang mit "optimiertem" Speicher nicht. Daher ist die Slice-Adressierung wohl das effizienteste Verfahren, das das Basteln im Speicher dem Compiler überlässt.

Harald
 
Zuletzt bearbeitet:
Was ist denn eigentlich gewollt ?
In AWL und FUP funktioniert das tadellos.
Du bekommst aber unterschiedliche Ergebnisse.
in AWL bekommst du den DINT Zahlenwert "1 121 823 616" bzw. REAL "1.121824+E9".
In FUP bekommst du den REAL "110.8354".
Sollen die BYTEs bitweise in ein doppelwort gesammelt werden und als DINT dargestellt werden ?
Oder sollen die BYTEs bitweise in ein doppelwort gesammelt werden und als REAL dargestellt werden ? edit: In diesen Fall ohne Konvertierung von DINT nach REAL.

Ist die IO Link Modul ein Zähler oder ein Analogwertgeber, oder .. ?
Die Mantissa von ein REAL ist nur 7 Ziffern. Damit gelangt man schnell in die Grenzen wenn man zählt.
 
Was ist denn eigentlich gewollt ?

Du bekommst aber unterschiedliche Ergebnisse.
in AWL bekommst du den DINT Zahlenwert "1 121 823 616" bzw. REAL "1.121824+E9".
In FUP bekommst du den REAL "110.8354".
Sollen die BYTEs bitweise in ein doppelwort gesammelt werden und als DINT dargestellt werden ?
Oder sollen die BYTEs bitweise in ein doppelwort gesammelt werden und als REAL dargestellt werden ? edit: In diesen Fall ohne Konvertierung von DINT nach REAL.

Ist die IO Link Modul ein Zähler oder ein Analogwertgeber, oder .. ?
Die Mantissa von ein REAL ist nur 7 Ziffern. Damit gelangt man schnell in die Grenzen wenn man zählt.
hier nur kurz. rest schau ich mir morgen genauer an

das io-link device liefert seine daten halt in einem array von [0..231] of byte. inlc der länge (anzahl bytes) des parameters.
der korrekte wert für die variable wäre 110.83...
in diesem fall ist das ein sensor von ifm sa4100. aber das ist hier zweitrangig.

fakt ist, dass die ow-verknüpfung in scl nicht so läuft wie in awl/fup (hier korrektte verknüpfung ohne wenn und aber)
kann man deutlich im ersten scrennshot sehen.

t_byte_x sind temp-var und als dword deklariert
wert_real ist eine temp-var vom typ real
wert_dint ist eine temp-var vom typ dint
 
Zuviel Werbung?
-> Hier kostenlos registrieren
fakt ist, dass die ow-verknüpfung in scl nicht so läuft wie in awl/fup (hier korrektte verknüpfung ohne wenn und aber)
Fakt ist, die DWORD-OR-Verknüpfung funktioniert in SCL genauso wie in FUP und AWL.
ABER: SCL prüft die Datentypen und meckert, daß Wordverknüpfungen mit REAL-Datentypen nicht erlaubt sind. Da muß der Programmierer dem SCL zeigen daß er weiß was er tut, indem er die Wordverknüpfung mit DWORDs macht und danach explizit DWORD_TO_REAL(...) verwendet.

Bei FUP und AWL sind dem Compiler die Datentypen der Variablen scheixxegal. Da darf der Programmierer alles mögliche anstellen was ihm einfällt.

Harald
 
fakt ist, dass die ow-verknüpfung in scl nicht so läuft wie in awl/fup (hier korrektte verknüpfung ohne wenn und aber)
kann man deutlich im ersten scrennshot sehen.

t_byte_x sind temp-var und als dword deklariert
wert_real ist eine temp-var vom typ real
wert_dint ist eine temp-var vom typ dint
Fakt ist ...
Im ScreenShot kann man sehen, dass die 4 Bytes anscheinend korrekt geschoben werden.
Im ScreenShot kann man aber nicht ohneweiteres nachvollziehen, ob die "ow-verknüpfung" (die ich viel lieber als OD-Verknüpfung bezeichnen würde) korrekt oder wie auch immer läuft, weil Du das Ergebnis nicht als DWORD abspeicherst, sondern als REAL.
Sonst wäre sicherlich das korrekte Ergebnis der ODER Verknüpfungen zu sehen gewesen, nämlich 16#42DD_ABB8.
Auf welchem Wege aber der angezeigte Wert 1.121824E+09 zustande kommt, kann ich mir nicht erklären.
Hier läuft etwas schief, aber was genau? Bastelt der Compiler evtl. DWORD_TO_REAL-Konvertierungen dazwischen bevor geodert wird?
aBytesOdern.jpg

Fakt ist, die DWORD-OR-Verknüpfung funktioniert in SCL genauso wie in FUP und AWL.
Davon gehe ich auch aus.
ABER: SCL prüft die Datentypen und meckert, daß Wordverknüpfungen mit REAL-Datentypen nicht erlaubt sind. Da muß der Programmierer dem SCL zeigen daß er weiß was er tut, indem er die Wordverknüpfung mit DWORDs macht und danach explizit DWORD_TO_REAL(...) verwendet.
Ich sehe in dem ScreenShot kein entsprechendes Meckern und auch keinen Grund für ein solches Meckern.
Ich sehe nur, dass die Zuweisung einer REAL-Variablen an eine DINT-Variable bemeckert wird. Die angezeigten Werte lassen aber keinen Grund für das Meckern erkennen. Wird hier einfach nur generell gewarnt, weil bei entsprechend hohen Werten eine BereichsÜberschreitung stattfinden könnte?
 
Als implizite Typkonvertierung ist nur DINT_TO_REAL vorhanden. Vermutlich wird dann ein DWORD_TO_DINT und dann ein DINT_TO_REAL implizit eingefügt. So war es zumindest bei SCL in Step7 als Konvertierungsfunktionen Klasse A aufgelistet, und das würde auch zum gezeigten Verhalten passen. Ich würde darum empfehlen, die Option der IEC-Prüfung zu aktivieren, das deckt noch so manch anderen übersehenen Fehler schon beim Übersetzen auf, bzw. muss man dann explizite Konvertierungen setzen und spätestens dann macht man sich noch mal Gedanken darüber.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Vermutlich wird dann ein DWORD_TO_DINT und dann ein DINT_TO_REAL implizit eingefügt.
Stimmt! Das erklärt den angezeigten Wert. Danke, Thomas!
Es scheitert also nach wie vor an der fehlenden Angabe der DatenTypKonvertierung, wie bereits längst (seit Beitrag #2) angenommen.
Und es gibt keinen Grund ein Fehlverhalten der ODER-Verknüpferei zu unterstellen. Im Gegenteil: der ScreenShot "beweist", dass die DWORD-ODERei einwandfrei auch in SCL funktioniert hat.

Ich würde darum empfehlen, die Option der IEC-Prüfung zu aktivieren, ...
Würde das auch in FUP (s. Netzwerk 9 aus Beitrag #1) zu einer FehlerMeldung führen (obwohl hier sowieso schon wunschgemäss implizit konvertiert wird)?
 
Zuletzt bearbeitet:
Würde das auch in FUP (s. Netzwerk 9 aus Beitrag #1) zu einer FehlerMeldung führen (obwohl hier sowieso schon wunschgemäss implizit konvertiert wird)?
In FUP sähe man an der FUP Box bei einer impliziten Konvertierung ein kleines graues unscheinbares Kästchen, das ist hier nicht vorhanden. Wobei viele Dinge je nach TIA-Portal Version unterschiedlich sind. Wenn ich mich recht entsinne dann greift die IEC-Prüfung auch in FUP, aber warum hier unterschiedliche Konvertierungsregeln gelten, erschließt sich mir auch nicht. Nach meinem Ermessen dürfte die FUP Zuweisung ohne Hinweis-Kästchen für die implizite Konvertierung überhaupt nicht erlaubt sein. Außer in FUP gelten andere Regeln, vieles ist beim TIA-Portal zu den Sprachen meiner Meinung nach nicht vollständig dokumentiert, oder es ist zumindest sehr schwer aufzufinden. Die Hilfe zu SCL in Step7 ist dahingehend sehr vollständig, auch mit den Syntaxdiagrammen, formalisierter Sprache usw.
 
Hat zwar mit der Frage nix zu tun, aber wie kommst du auf 231 Byte Prozessdaten? Verwendest du irgendwelche Bausteine zum Einlesen? Laut Handbuch schickt der Sensor 4 Byte… die ersten beiden sind direkt der Prozesswert. Ich leg da einfach in der Symboltabelle an was ich erwarte und wandel das gegebenenfalls in den Datentyp mit dem ich arbeiten will…
 
Zuviel Werbung?
-> Hier kostenlos registrieren
ABER: SCL prüft die Datentypen und meckert, daß Wordverknüpfungen mit REAL-Datentypen nicht erlaubt sind. Da muß der Programmierer dem SCL zeigen daß er weiß was er tut, indem er die Wordverknüpfung mit DWORDs macht und danach explizit DWORD_TO_REAL(...) verwendet.
Ich sehe in dem ScreenShot kein entsprechendes Meckern und auch keinen Grund für ein solches Meckern.
Du hast recht. Danke fürs genaue hinschauen und nachdenken. :)
Ich hatte zu flüchtig hingesehen, weil mir sofort die notwendige korrekte Lösung klar war (siehe Beitrag #2). Ich hatte die gelbe gekräuselte Unterstreichung als Fehlermeldung angesehen, es ist aber nur eine Warnung (vermutlich "möglicher Genauigkeitsverlust" oder so ähnlich). Der SCL-Code wurde ja tatsächlich übersetzt. Allerdings falsch, weil die impliziten Konvertierungen eben nicht das waren was volker brauchte.

Harald
 
Hat zwar mit der Frage nix zu tun, aber wie kommst du auf 231 Byte Prozessdaten? Verwendest du irgendwelche Bausteine zum Einlesen? Laut Handbuch schickt der Sensor 4 Byte… die ersten beiden sind direkt der Prozesswert. Ich leg da einfach in der Symboltabelle an was ich erwarte und wandel das gegebenenfalls in den Datentyp mit dem ich arbeiten will…
Das ist fest vorgegeben durch den FB50001 IO_LINK_DEVICE (Siemens). Es geht nicht um die zyklischen Daten sondern um weitere Daten die per Index azyklisch gelesen werden können.

Die Lösung von PN/DP im Post#2 funktioniert.
Danke
 
Zurück
Oben