I am currently trying to connect to an electric meter via RS485.

It works quite well so far, except that I have problems reading what the meter is writing back on the RS485 line.

I know that the data from the electric meter is correct since I can read it with Docklight and the internal programm of the manufacturer.

So my only problem is the conversion of hex bytes that I am getting back.

I am receiving

>>> b'\x01\x03\x04Ce/\xec\xe2'

This should be 8 or 9 hex bytes.

I expect to receive something like

>>> b'\x01\x03\x04\x43\x67\x81\xEC\x43\x68'

The problem seems to be that python interprets it in "ASCII" whereever it can and I cannot convert it furthermore because of the non-hexadecimal digits.

And the error I get is

>>> binascii.Error: Non-hexadecimal digit found`

The equivalent when I look at it from the other side.

I am sending

>>> data=bytearray([0x01,0x03,0x4A,0x38,0x00,0x02,0x53,0xDE])

which is displayed as

>>> bytearray(b'\x01\x03J8\x00\x02S\xde')

when I print it

So how can I tell python-3 that I want to see the 8 hex bytes and not some interpretation that he automatically makes? I believe I am missing on something that is really easy once you know where to look for.

I want to convert bytes 4,5,6,7 into float. But since it is showing me non-hexadecimal digits I cannot do that.


C, e and / are bytes too; they are ASCII characters so don't need to be displayed with \x.. hex escapes.

You don't need to decode the \x.. hex escapes either, they are just how Python gives you the debugging representation of a bytes object; each byte is either displayed as an escape sequence or a printable ASCII letter.

The same happens to your something like this example:

>>> b'\x01\x03\x04\x43\x67\x81\xEC\x43\x68'


That's the exact same value, but \x68 is the ASCII letter h, etc.

The output is the default repr() output for bytes objects. It can't be changed. You'll have to write your own code if you need different output.

You could display all bytes as hex with the binascii.hexlify() function, for example:

>>> import binascii

>>> binascii.hexlify(b'\x01\x03\x04\x43\x67\x81\xEC\x43\x68')


Now you have a bytes string with hex characters. Or you could use a str.join() function with each individual byte converted to hex with a \x literal text prefixed:

>>> ''.join(r'\x{:02x}'.format(byte) for byte in b'\x01\x03\x04\x43\x67\x81\xEC\x43\x68')


>>> print(''.join(r'\x{:02x}'.format(byte) for byte in b'\x01\x03\x04\x43\x67\x81\xEC\x43\x68'))


That's a str object with \, x and hex digits as characters.

Note that this is all just displaying the value. The value didn't change; the bytes are all there however you display them. If you need to convert 4 bytes to a float, then just convert those 4 bytes:

struct.unpack('f', yourbytes[4:]) # 4 bytes for C float in native order

This uses the struct module to use the bytes directly. No hexadecimal representation needed:

>>> import struct

>>> struct.unpack('f', b'\x01\x03\x04Ce/\xec\xe2'[:4])


< <上一篇