# Vier Bytes in Float (ST) TwinCat 3



## SPS_Fragekatalog (28 August 2015)

Hallo alle zusammen!

ich lesen vier Bytes mit der Klemme EL6001 ein. Diese möchte ich wieder in mein Float-Wert zurück wandeln.

Zuvor habe ich ein Int-Wert (-1225) gesendet und empfangen (LowByte = 55 , HighByte = 251). Diese wollte ich mit folgender Zeile zurück in den Int-Wert wandeln:

intValue    := (HighByte *255 + LowByte);

Hat nicht geklappt. Wundert mich nicht, da 255* 251 schon viel zu groß ist, jedoch habe ich den Ansatz im Internet gefunden.


Ich danke Euch für Eure Unterstützung! 

Gruß
Fragekatalog


----------



## PN/DP (28 August 2015)

Wenn Du die richtige Formel benutzt und richtig rechnest dann kommst Du auch auf das richtige Ergebnis:

```
intValue := (HighByte*256 + LowByte);
   -1225 :=      -5 * 256 + 55
```

Einfacher ist aber, die einzelnen Bytes so zusammenzusetzen:

```
intValue := WORD_TO_INT(SHL(BYTE_TO_WORD(HighByte), 8) OR LowByte));
```

Was hat das aber nun mit Float zu tun bzw. wie ist jetzt Deine Frage?

Harald


----------



## PN/DP (28 August 2015)

Falls Du 4 Bytes zu einem REAL-Wert zusammensetzen willst, dann kannst Du hier die ersten beiden Varianten von RONIN als Vorlage nehmen: SCL: 4 Byte TO Real
Oder den Code aus dem ersten Beitrag, der ist in Beckhoff-Style ST.

Harald


----------



## Ralle (28 August 2015)

Ich würde das mit memcpy machen, in etwa wie hier (letzter Post des Threads): http://forum.codesys.com/viewtopic.php?f=11&t=5623

Dort wird es mit einem Array of 2 Word gezeigt, geht auch mit einem Array of 4 Byte.


----------



## SPS_Fragekatalog (31 August 2015)

Guten Morgen alle zusammen!

Vielen Dank für Eure Antworten! 

Ich möchte in ST vier Bytes zurück in ein Float umwandeln. Die vier Bytes lese ich über die EL6001 Klemme ein.

Gruß
Fragekatalog


----------



## SPS_Fragekatalog (31 August 2015)

@ Harald:

Vllt. blöde Frage aber wie kommt Du auf "-5" für HighByte von "-1225"? Ich erhalte "251".

Gruß
Fragekatalog


----------



## PN/DP (31 August 2015)

Guten Morgen.
Hast Du die genannten Beispiele ausprobiert? Funktioniert keins?

Wie sind die 4 Bytes codiert? (Wo kommen die her?) Hast Du ein Beispiel, welche 4 Bytes welchen Wert ergeben sollen?
Um ganz sicher zu gehen: mit Float meinst Du 32-Bit REAL?

Harald


----------



## SPS_Fragekatalog (31 August 2015)

Bin gerade dabei die Beispiele durch zu sehen und auszuprobieren. 
Nur ist mir sofort aufgefallen, dass Du einen anderen Wert für das HighByte erhalten hast.
Die Bytes kommen aus einem µC. 
Beispiel: 
Float-Wert: 1234.56
Byte 1: 236
Byte 2: 81
Byte 3: 154
Byte 4: 68

Diese Bytes möchte ich nun zurück in den Float-Wert umwandeln.

Bin in ST noch nicht ganz sicher unterwegs. Mit Float meine ich 32 Bit. Bereich: 3.4028235E+38 bis -3.4028235E+38.
Wenn das 32Bit-REAL entspricht meine ich das. 
In der Tat ich muss sicher sein wie der µC die Bytes codiert und dementsprechend in ST decodieren.
Die vier Bytes, die den Float-Wert repräsentieren, liegen im Bereich 0-255 (8Bit).


Danke für Deine schnelle Antwort. 

Gruß
Fragekatalog


----------



## PN/DP (31 August 2015)

SPS_Fragekatalog schrieb:


> Beispiel:
> Float-Wert: 1234.56
> Byte 1: 236
> Byte 2: 81
> ...


Byte 1 ist das LSB ... Byte 4 ist das MSB --> Du mußst beim Zusammensetzen die Byte-Reihenfolge 1 2 3 4 beibehalten, kannst also per Pointer oder memcpy direkt die 4 Byte auf eine REAL-Variable kopieren.
Das TwinCAT-SPS-System arbeitet mit dem Little-Endian-Format (INTEL).

Harald


----------



## PN/DP (31 August 2015)

Hier eine weitere fertige Funktion:  Byte´s zu Real

Harald


----------



## SPS_Fragekatalog (31 August 2015)

Also nun hat es geklappt. 

Der Code aus dem ersten Beitrag, den Harald gepostet hat, hat mich zum Erfolg geführt!

Vielen Dank nochmal!


----------



## PN/DP (31 August 2015)

Hmm, Deine Erfolgsmeldung ist ein bisschen unscharf und mehrdeutig... Könntest Du vielleicht Deinen erfolgreichen Code noch hier posten, damit spätere Suchende schneller die Lösung finden?

Harald


----------



## hucki (31 August 2015)

SPS_Fragekatalog schrieb:


> @ Harald:
> 
> Vllt. blöde Frage aber wie kommt Du auf "-5" für HighByte von "-1225"? Ich erhalte "251".


Da wird das Problem liegen, in der Interpretation des höchsten Bits.
Das höchste Bit des HighBytes stellt hier das Minus dar, also Wert-128 macht hier 123-128=-5 anstatt 123+128=251.
Durch das Schieben in Haralds Code bleibt es erhalten, während es durch die Multiplikation des Bytes mit der impliziten Umwandlung in einen INT-Wert dagegen verloren geht.


----------



## SPS_Fragekatalog (1 September 2015)

Guten Morgen!

Na klar, ich habe den Code von "artofautomation", den Harald in seinem ersten Post verlinkt hat, 1 zu 1 übernommen. Dies klappte dann wunderbar.
http://www.sps-forum.de/simatic/78556-scl-4-byte-real-pointer-funktion.html


Vielen Dank!!!


----------



## PN/DP (1 September 2015)

SPS_Fragekatalog schrieb:


> ich habe den Code von "artofautomation", den Harald in seinem ersten Post verlinkt hat, 1 zu 1 übernommen. Dies klappte dann wunderbar.
> http://www.sps-forum.de/simatic/78556-scl-4-byte-real-pointer-funktion.html


Hmm, das ist aber merkwürdig. Der Code von artofautomation bringt die Bytes in die Reihenfolge 2 1 4 3

Gibst Du beim Aufruf der Function FC_4BYTE_TO_REAL die Bytes teilweise vertauscht an?
Oder speichert das TwinCAT-SPS-System einen 32-Bit-REAL nur wordweise in Little Endian?


Du hast angegeben, Du empfängst von dem µC

```
dez hex
Byte 1: 236  EC  LSB
Byte 2:  81  51
Byte 3: 154  9A
Byte 4:  68  44  MSB
```

1234.56 = 16#449A51EC

Das sollte so im Speicher liegen:

```
Big Endian (Motorola, Siemens)  : 44 9A 51 EC  (4 3 2 1)
Little Endian (Intel, TwinCAT)  : EC 51 9A 44  (1 2 3 4)

artofautomation FC_4BYTE_TO_REAL: 51 EC 44 9A  (2 1 4 3)
```

Hat jemand eine Erklärung dafür? Ich habe leider kein TwinCAT-SPS-System zum Testen.

Harald


----------



## SPS_Fragekatalog (1 September 2015)

Moin Harald,

so übergebe ich die gelesenen Bytes der Funktion:

floatZahl := FC_4BYTE_TO_REAL (BYTE2 , BYTE1, BYTE4 , BYTE3)

Hab dieses hier gefunden:  "TwinCAT-SPS-System arbeitet aber mit dem Little-Endian-Format (INTEL)."
http://infosys.beckhoff.de/index.ph...html/tcplclibutilities_addon_byteorder.htm&id=

Gruß
Fragekatalog


----------



## PN/DP (1 September 2015)

SPS_Fragekatalog schrieb:


> so übergebe ich die gelesenen Bytes der Funktion:
> 
> floatZahl := FC_4BYTE_TO_REAL (BYTE2 , BYTE1, BYTE4 , BYTE3)


Das erklärt, warum es funktioniert, da die Function die Bytes 2/1 und 4/3 wieder zurücktauscht.

Die 4 Bytes liegen schon in der richtigen Reihenfolge vor, Du hättest auch einfach mit memcpy oder mit einem Pointer aufs erste Byte die 4 Byte in eine FLOAT/REAL-Variable kopieren können.

Danke für die vollständig Aufklärung.

Harald


----------

