2 Byte FP in single umwandeln

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
DL3AD
Beiträge: 478
Registriert: Fr 13. Sep 2013, 12:07
OS, Lazarus, FPC: Debian Bullseye (L 2.2.0)
CPU-Target: 64Bit
Wohnort: Rügen

2 Byte FP in single umwandeln

Beitrag von DL3AD »

Hallo,
ich habe Temperaturrohdaten von einem KNX Bus im Format EIS5 (2 Byte Floatpoint) und möchte die natürlich in eine Singel umwandeln.
z.B. $14 $23 sind -8.6°C oder $19 $1D sind um die 22°C

wie mache ich aus den Byte eine verwertbare Temperatur ?

Für EIS9 mit 4 Byte habe ich es hinbekommen

Code: Alles auswählen

//EIS9 (4 Byte FP) nach SingleString konvertieren ==============================
function Eis9ToFloat(B0,B1,B2,B3: string):string;
var
  Data: array[0..3] of byte;
  Sval: Single absolute Data;
begin
  Data[3]:= Hex2Dec(B0);
  Data[2]:= Hex2Dec(B1);
  Data[1]:= Hex2Dec(B2);
  Data[0]:= Hex2Dec(B3);
  Result:= FloatToStr(Sval);
end;
Mit der EIS5 2 Byte stehe ich auf dem Schlauch

Gruß Frank

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: 2 Byte FP in single umwandeln

Beitrag von Winni »

Hallo!

Wenn ich mich dunkel recht erinnere, dann sind die 16 Bits von EIS5 folgendermaßen definiert

Bit0 : Vorzeichen
Bit1..Bit5: Exponent
Bit6..Bit15: Mantisse

Das ist die Definition von IEEE 754, wobei die 16 Bit dort recht dürftig behandelt werden.

Musst Du mal nachlesen.

Winni

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: 2 Byte FP in single umwandeln

Beitrag von wp_xyz »

Code: Alles auswählen

function Eis9ToFloat(B0,B1,B2,B3: string):string;
var
  Data: array[0..3] of byte;
  Sval: Single absolute Data;
begin
  Data[3]:= Hex2Dec(B0);
  Data[2]:= Hex2Dec(B1);
  Data[1]:= Hex2Dec(B2);
  Data[0]:= Hex2Dec(B3);
  Result:= FloatToStr(Sval);
end;
Wenn du die Funktion Eis9ToFloat nennst erwarte ich eigentlich, dass ihr Ergebnis ein single ist, kein String. Wenn du später den String brauchst, kannst du den immer noch mit FloatToStr erzeugen. Außerdem würde ich die Parameter B0..B3 nicht als String übergeben, sondern gleich als Byte, denn so erhältst du sie ja auch, und du kannst dir die Stringkonversion sparen:

Code: Alles auswählen

function Eis9ToFloat(B0,B1,B2,B3: byte):single;
var
  Data: array[0..3] of byte;
  Sval: Single absolute Data;
begin
  Data[3]:= B0;
  Data[2]:= B1;
  Data[1]:= B2;
  Data[0]:= B3;
  Result:= Sval;
end;

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: 2 Byte FP in single umwandeln

Beitrag von Winni »

Hi!

Du arbeitest mit EIS9. Das ist 32 Bit und trivial.

EIS5 ist 16 Bit, nämlich die erwähnten 2 Byte.

Winni

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: 2 Byte FP in single umwandeln

Beitrag von wp_xyz »

DL3AD hat geschrieben:
Do 8. Dez 2022, 18:21
Mit der EIS5 2 Byte stehe ich auf dem Schlauch
Der Link enthält die Definition eines 2-Byte-Float-Datentyps (KNX). Vielleicht hilft dir das weiter.
Dateianhänge
knx_2octetfloat.png
knx_2octetfloat.png (42.22 KiB) 960 mal betrachtet

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: 2 Byte FP in single umwandeln

Beitrag von wp_xyz »

Probier's mal mit dieser Funktion, die aufgrund der Angaben in dem PDF entstand:

Code: Alles auswählen

function EIS5ToFloat(AValue: word): Single;
var
  isNeg: Boolean;
  exponent: Integer;
  Mantissa: Integer;
begin
  if AValue = $7FFF then
  begin
    Result := NaN;
    exit;
  end;

  isNeg    := (AValue and %1000000000000000) <> 0;
  exponent := (AValue and %0111100000000000) shr 11;
  mantissa := (AValue and %0000011111111111);
  if isNeg then
    mantissa := - (%0000011111111111 - mantissa + 1);
  mantissa := mantissa shl exponent;
  Result := 0.01 * mantissa;
end; 
In https://knx-professionals-forum.de/foru ... 11821.html wird erwähnt, dass der Wert $18D2 den Float-Wert 16.8 ergibt. Das macht meine Funktion auch.

Bei dem von dir angegebenen Wert $191D komme ich auf 22.8. Bei dem anderen Wert $1423, der -8.6 ergeben soll, muss etwas nicht stimmen, denn für eine negative Zahl würde ich erwarten, dass das Vorzeichen-Bit gesetzt ist, d.h. statt der 1 müsste etwas zwischen 8 und F stehen; meine Funktion ergibt 42.36.

DL3AD
Beiträge: 478
Registriert: Fr 13. Sep 2013, 12:07
OS, Lazarus, FPC: Debian Bullseye (L 2.2.0)
CPU-Target: 64Bit
Wohnort: Rügen

Re: 2 Byte FP in single umwandeln

Beitrag von DL3AD »

Hallo wp_xyz,
du hast mir die ganze Arbeit weggenommen :mrgreen:
DANKE!
Du hast recht mit den 42.36° - das ist der Fühler für Warmwasser und nicht der Außenfühler.

Gruß Frank

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: 2 Byte FP in single umwandeln

Beitrag von wp_xyz »

Hast du für mich vielleicht auch ein paar Wertepaare (EIS5-Wert und Single) mit negative Zahlen? Dann könnte ich auch die negativen Werte prüfen.

Benutzeravatar
theo
Beiträge: 10467
Registriert: Mo 11. Sep 2006, 19:01

Re: 2 Byte FP in single umwandeln

Beitrag von theo »

wp_xyz hat geschrieben:
Fr 9. Dez 2022, 12:39
Hast du für mich vielleicht auch ein paar Wertepaare (EIS5-Wert und Single) mit negative Zahlen? Dann könnte ich auch die negativen Werte prüfen.
Das sollte heute mit dem Außenfühler eigentlich kein Problem sein. :lol:
https://www.meteoblue.com/de/wetter/woc ... nd_2843325

DL3AD
Beiträge: 478
Registriert: Fr 13. Sep 2013, 12:07
OS, Lazarus, FPC: Debian Bullseye (L 2.2.0)
CPU-Target: 64Bit
Wohnort: Rügen

Re: 2 Byte FP in single umwandeln

Beitrag von DL3AD »

Hallo,
funktioniert auch mit negativen Temp -0.9°C auf dem Display
$9F $F5

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: 2 Byte FP in single umwandeln

Beitrag von wp_xyz »

Ich komme auf -0.88. Könnte stimmen? Hast du nur 1 Dezimalstelle in der Anzeige? Evtl. könntest du noch einen Wert später am Abend posten.

DL3AD
Beiträge: 478
Registriert: Fr 13. Sep 2013, 12:07
OS, Lazarus, FPC: Debian Bullseye (L 2.2.0)
CPU-Target: 64Bit
Wohnort: Rügen

Re: 2 Byte FP in single umwandeln

Beitrag von DL3AD »

... ja -0.88 ist richtig - habe in der Anzeige nur eine Dezimalstelle.

Antworten