Search code examples
pythonfloating-pointieee-754modbuspymodbus

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).


Solution

  • 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