Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert two raw values to 32-bit IEEE floating point number

I am attempting to decode some data from a Shark 100 Power Meter via TCP modbus. I have successfully pulled down the registers that I need, and am left with two raw values from the registers like so:

[17138, 59381]

From the manual, I know that I need to convert these two numbers into a 32bit IEEE floating-point number. I also know from the manual that "The lower-addressed register is the high order half (i.e., contains the exponent)." The first number in the list shown above is the lower-addressed register.

Using Python (any library will do if needed), how would I take these two values and make them into a 32 bit IEEE floating point value.

I have tried to use various online converters and calculators to figure out a non-programmatic way to do this, however, anything I have tried gets me a result that is way out of bounds (I am reading volts in this case so the end result should be around 120-122 from the supplied values above).

like image 271
Andrew Sclafani Avatar asked Dec 18 '25 21:12

Andrew Sclafani


2 Answers

Update for Python 3.6+ (f-strings).

I am not sure why the fill in @B.Go's answer was only 2. Also, since the byte order was big-endian, I hardcoded it as such.

import struct
a = 17138
b = 59381
struct.unpack('>f', bytes.fromhex(f"{a:0>4x}" + f"{b:0>4x}"))[0]

Output: 121.45304107666016

like image 163
Intrastellar Explorer Avatar answered Dec 21 '25 13:12

Intrastellar Explorer


The following code works:

import struct
a=17138
b=59381
struct.unpack('!f', bytes.fromhex('{0:02x}'.format(a) + '{0:02x}'.format(b)))

It gives

(121.45304107666016,)

Adapted from Convert hex to float and Integer to Hexadecimal Conversion in Python

like image 34
B. Go Avatar answered Dec 21 '25 13:12

B. Go