Search code examples
pythonhexdata-conversion

Obtaining decimal from 2-Byte hex


I have a problem where we are given the barometric pressure (Hg/1000) as 2 Bytes. The data is from a serial readout and we are provided with the following information regarding that:

  • 8 data bits
  • 1 Start bit
  • 1 Stop bits
  • No Parity

I am trying to convert the bytes into valid pressure readings (between 20 and 32.5) in python, from the following example data:

1. ['0xf0', '0x73']
2. ['0xef', '0x73']
3. ['0xf1', '0x73']
4. ['0xf4', '0x73']
5. ['0xee', '0x73']
6. ['0xec', '0x73']

So far I have been able to get the value 351 for number 6 or 236,115 by converting to decimal and adding them although I'm not really sure where to go from here. I believe this is supposed to correlate to around 29.67Hg but I am unsure.


Solution

  • The data looks like it packed as int16 values in "little endian" format.

    You can unpack these values using int.from_bytes or struct.unpack

    Looking at the value you expect, the output from the conversion needs to be divided by 1000 to move the decimal place to be in the correct location.

    As the values are strings in the input data, you will need to turn them in to integers first. As they are representing hex values this can be done with int('0xce', 16).

    There are lots of ways you could do this. Below is one example:

    data = [['0xf0', '0x73'],
            ['0xef', '0x73'],
            ['0xf1', '0x73'],
            ['0xf4', '0x73'],
            ['0xee', '0x73'],
            ['0xec', '0x73']]
    for idx, reading in enumerate(data):
        value = int.from_bytes([int(x, 16) for x in reading], 'little') / 1000
        print(f"{idx + 1}. {reading} is {value:0.03f}")
    

    Which gives the following output:

    1. ['0xf0', '0x73'] is 29.680
    2. ['0xef', '0x73'] is 29.679
    3. ['0xf1', '0x73'] is 29.681
    4. ['0xf4', '0x73'] is 29.684
    5. ['0xee', '0x73'] is 29.678
    6. ['0xec', '0x73'] is 29.676