自定义解码字节数组

时间:2018-10-05 12:44:41

标签: python struct decode python-2.x pyserial

我有一个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),但为此,我需要以某种方式知道/定义其格式。

我想看的是e之后的前两个整数(十六进制编码)。

4 个答案:

答案 0 :(得分:0)

也许这样可以帮助您:

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

答案 1 :(得分:0)

e\x00\x01\x01\xff\xff\xffbytes对象。初始化前请注意前导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

答案 2 :(得分:0)

如果将其表示为字符串,或者您可以轻松地将其转换为一个字符串,只需将其用'\'字符分割,然后访问[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])

获取所需的值

答案 3 :(得分:0)

我认为@parasit的想法正确,但是我会形式化一些事情,并使用类似于以下代码。 x格式字符串struct中的初始DAT_FMT format character表示忽略数据的第一个字节(样本串行数据中的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
相关问题