自定义解码字节数组

Custom decoding a byte array

我有一个 python 代码正在读取串行数据。它的格式是:

e\x00\x01\x01\xff\xff\xff

这里实际上应该存储的是在我通过串行访问的硬件设备上选择的特定组件的 id。我认为 id 的类型是整数,因为它是自动生成的,我无法更改它并且它为每个组件获取 1、2、3 等值... (按钮)。

我的串口是这样配置的:

ser = serial.Serial(port='/dev/serial0',baudrate=9600,timeout=1.0)

所以,如果我点击一个 ID 为 1 的按钮,我会得到 => e\x00\x01\x01\xff\xff\xff

如果我点击了一个 id 为 2 的按钮 => e\x00\x02\x01\xff\xff\xff

如果 id 是 10 => e\x00\x0A\x01\xff\xff\xff

结尾符号 \xff\xff\xff 始终存在,起始符号 e

我的问题是:我怎样才能以一致的方式读取这样的输入并提取整个数组中给我带来价值的这一点? 从我在互联网上看到的,我可以使用 Python 的 struct 包并解压这样的东西 (e\x00\x01\x01\xff\xff\xff) 但为了做到这一点,我需要以某种方式 know/define 它的格式。

我希望能够读取的是 e 之后的前两个整数(十六进制编码)。

也许这样的事情可以帮助你:

from struct import *
unpack('xbbbbbb','e\x00\x01\x01\xff\xff\xff')
(0, 1, 1, -1, -1, -1)

e\x00\x01\x01\xff\xff\xff 是一个 bytes 对象。初始化时请注意前导 b 。您不需要 struct 来访问它。

只需使用数组中的索引访问单个字符:

x = b'e\x00\x01\x01\xff\xff\xff'
print(x[0]) # this is the 'e', it's 101 in ascii
print(x[1])
print(x[2]) # this is the value of your button
print(x[3]) 
print(x[4]) 

x = b'e\x00\x0A\x01\xff\xff\xff'
print(x[2]) # now the value of the button is 10

如果它表示为一个字符串,或者您可以轻松地将其转换为一个,只需将其拆分为“\”字符并访问 [1] 和 [2] 索引即可获取它们。

s = r"e\x00\x01\x01\xff\xff\xff".split(r"\x") # r prefixed the string to avoid having to escape the backslashes
int1 = int(s[1], 16) # the second argument is the base, here, hexadecimal
int2 = int(s[2], 16)
print(int1) # 2
print(int2) # 1

如果它是一个字节对象,你已经可以用索引访问它了。刚刚

print(s[1])
print(s[2])

获取您需要的值

我认为@parasit 的想法是正确的,但我会将事情形式化一些并使用类似于以下的代码。 struct格式字符串中的首字母xformat characterDAT_FMT表示忽略数据的第一个字节(示例串口数据中的e)。

from __future__ import print_function
import struct

DAT_FMT = 'x6B'

for sample in (b'e\x00\x01\x01\xff\xff\xff',
               b'e\x00\x01\x02\xff\xff\xff',
               b'e\x00\x01\x0a\xff\xff\xff'):

    dat0, dat1, id, dat3, dat4, dat5 = struct.unpack(DAT_FMT, sample)
    print(dat0, dat1, id, dat3, dat4, dat5, sep=', ')

输出:

0, 1, 1, 255, 255, 255
0, 1, 2, 255, 255, 255
0, 1, 10, 255, 255, 255