# Float aus Byte-Array auslesen



## Joe (5 Juli 2008)

Servus zusammen.
Ich lese mit WinCC Rohdaten aus einem DB. Die Daten will ich dann in einem Skript wieder "extrahieren" und in lokale Variablen schreiben.
Jetzt liefert mir die Rohdatenvariable aber nur Byte-Arrays, was mit den Integern ja kein problem ist: (Byte_0 * 256 + Byte_1). Mit meinen Realzahlen habe ich aber ein Problem. Mein Anfang war bisher so, dass ich das selbe prinzip verwende wie mit den Integer-Zahlen; dann habe ich schonmal meine Nullen wieder drin und der angezeigte Wert ist auch der selbe, den Step7 anzeigt, wenn ich eine Realzahl als Dezimalzahl betrachte.
Jetzt zur konkreten Frage: gibt es eine Funktion, mit der ich den Dezimalwert wieder in einen Realwert wandeln kann, oder kann ich die Arrays vielleicht anders auslesen?
Ware euch für Antworten sehr dankbar, auch für andere Lösungswege, falls jemand eine idee hat.
PS: bisher habe ich das ganze in ANSI-C gemacht...

MfG Joe


----------



## Thomas_v2.1 (6 Juli 2008)

Hi,
ich würde es mit einer union machen:


```
typedef union f_un
    {
        float val;
        unsigned char byte[4];
    };
```
Damit lassen sich dann die einzelnen Bytes auslesen oder schreiben, z.b. mit 


```
f_un fu;    
    fu.byte[0] = 0x00;
    fu.byte[1] = 0x00;
    fu.byte[2] = 0x00;
    fu.byte[3] = 0x00;
    printf("fu.val= %f\n", fu.val);
```
Musst dann nur noch auf die Bytedreher achten wenn sie aus der Siemens-Steuerung kommen.

Falls die Reihenfolge der Bytes korrekt ist würde es auch direkt so gehen:

```
char myArr[10];
    myArr[0] = 0x00; // 123.0
    myArr[1] = 0x00;
    myArr[2] = 0xF6;
    myArr[3] = 0x42;
    myArr[4] = 0x00; // 456.0
    myArr[5] = 0x00;
    myArr[6] = 0xE4;
    myArr[7] = 0x43;    
    
    float f1 = *((float*) &myArr[0]);
    float f2 = *((float*) &myArr[4]);
    printf("f1=%f\n", f1);
    printf("f2=%f\n", f2);
```
Gruß


----------



## Grubba (6 Juli 2008)

Wenn ichs richtig verstanden habe, schreibst Du auf der S7 Seite einen Realwert in z.B. einen DB. Die Adresse an die Du diesen Real Wert schreibst, ist kein Real sondern irgendwo in einem Byte Array. Also bekommst Du dann auf der WinCC Seite keinen Real Wert, sondern den Real Wert als S7 Notation (nach IEC-Schlag-Mich-Tot mit Exponent, Mantisse etc).

Wenns so ist:

Habe mir mal für Delphi, also Pascal einen FC geschrieben, der mir diese Bitkombination aufschlüsselt und in einen Real-Wert zurückwandelt (Und umgekehrt) Das könnte ich Dir zukommen lassen. Allerdings hast Du das ja schon mal in C gemacht. 

Aber wenns Dir helfen würde.... sag Bescheid.


----------



## Rainer Hönle (6 Juli 2008)

Hallo Joe,
steht dir in deinem Ansi-C die Funktion htonl() zur Verfügung? Wenn ja, dann diese mit entsprechenden casts anwenden. Wenn nicht ist die Frage, wo läuft das Ganze? Auf einem PC oder einem CE-Panel ggf. mit anderer Byteorientierung? Auf dem PC ist es relativ einfach: Einfach die Union von Thomas verwenden und die Bytes über Kreuz zuweisen. Dann kannst du ohne weiteres direkt auf den float-Wert zugreifen. Eine Wandlung ist jetzt nicht mehr notwendig, der Wert steht schon richtig da. Habe ich mich verständlich und umsetzbar ausgdrückt?


----------



## Joe (6 Juli 2008)

erstmal ein Dankeschön.
@Grubba: ln den DB beschreibe ich schon eine Real-Variable, nur beim auslesen bekomme ich nur ein Byte-Array.

@Thomas & Rainer: Dann werde ich mich mit den „Unions" mal ein Wenig vertraut machen.
Die Funktion htonl() ist mir jetzt nicht aufgefallen. lch schaue abergleich Morgen früh nochmal nach. lch gebe dann nochmal bescheid.


----------



## Joe (7 Juli 2008)

Das mit der Union funktioniert super.

Danke euch nochmal...


----------

