正确解释十六进制字节,将其转换为浮点数



我目前正试图通过RS485连接到电表。到目前为止,它工作得很好,除了我有问题读取仪表在RS485线上写回的内容。

我知道电表的数据是正确的,因为我可以用Docklight和制造商的内部程序读取它。

所以我唯一的问题是十六进制字节的转换,我得到返回。

我正在接收

>>> b'x01x03x04Ce/xecxe2'

应该是8或9个十六进制字节。我希望收到类似

的内容
>>> b'x01x03x04x43x67x81xECx43x68'

问题似乎是python在"ASCII"中尽可能地解释它,并且由于非十六进制数字,我无法进一步转换它。我得到的错误是

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

从另一个角度看是等价的。我正在发送

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

显示为

>>> bytearray(b'x01x03J8x00x02Sxde')

当我打印它

那么我如何告诉python-3我想看到8十六进制字节,而不是他自动做出的一些解释?我相信我错过了一些很容易的东西,一旦你知道去哪里找。

我想把字节4,5,6,7转换成浮点数。但由于它显示的是非十六进制数字,所以我不能这样做

您可以使用struct.unpack()从数据中获取数字。方法如下:

In [171]: import struct
In [190]: b2
Out[190]: b'x01x03J8x00x02Sxde'
In [191]: struct.unpack('B'*len(b2), b2)
Out[191]: (1, 3, 74, 56, 0, 2, 83, 222)
In [192]: [*map(hex, struct.unpack('B'*len(b2), b2))]
Out[192]: ['0x1', '0x3', '0x4a', '0x38', '0x0', '0x2', '0x53', '0xde']

Ce/也是字节;它们是ASCII字符,所以不需要用x..十六进制转义来显示。

你也不需要解码x..十六进制转义,它们只是Python为你提供bytes对象的调试表示的方式;每个字节要么显示为转义序列,要么显示为可打印的ASCII字母。

同样发生在上,例如示例:

>>> b'x01x03x04x43x67x81xECx43x68'
b'x01x03x04Cgx81xecCh'

这是完全相同的值,但x68是ASCII字母h,等等。

输出为bytes对象默认的repr()输出。这是无法改变的。如果你需要不同的输出,你必须自己编写代码。

您可以使用binascii.hexlify()函数将所有字节显示为十六进制,例如:

>>> import binascii
>>> binascii.hexlify(b'x01x03x04x43x67x81xECx43x68')
b'010304436781ec4368'
现在您有一个十六进制字符bytes字符串。或者您可以使用str.join()函数,将每个字节转换为十六进制,并使用x文本前缀:

>>> ''.join(r'x{:02x}'.format(byte) for byte in b'x01x03x04x43x67x81xECx43x68')

' x01 x03 x04 x43 x67 x81 xec x43 x68"

>>> print(''.join(r'x{:02x}'.format(byte) for byte in b'x01x03x04x43x67x81xECx43x68'))
x01x03x04x43x67x81xecx43x68

这是一个str对象,, x和十六进制数字作为字符。

注意,这只是显示值。值没有改变;不管你怎么显示,字节都在那里。如果您需要将4个字节转换为浮点数,那么只需转换这4个字节:

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

使用struct模块直接使用字节。不需要十六进制表示:

>>> import struct
>>> struct.unpack('f', b'x01x03x04Ce/xecxe2'[:4])
(132.01173400878906,)

相关内容

  • 没有找到相关文章

最新更新