在 python 中即时解析二进制串行数据

Posted

技术标签:

【中文标题】在 python 中即时解析二进制串行数据【英文标题】:on-the-fly parsing of binary serial data in python 【发布时间】:2017-01-29 18:48:05 【问题描述】:

我是使用 Python3 进行数据采集的新手。我正在尝试找到一种方法来从 Linux 上的串行端口解析二进制数据。

import serial

ser = serial.Serial(   
    port='/dev/ttyS0',
    baudrate = 9600,
    parity=serial.PARITY_NONE,
    stopbits=serial.STOPBITS_ONE,
    bytesize=serial.EIGHTBITS,
    timeout=1)
counter = 0

while 1:
    x = ser.read(31)
    print (x)

这给了我一个我不确定格式的字符串:

x='\x00\x00\x91\x00\x02\x88BM\x00\x1c\x00\x00\x00\x01\x00\x01\x00\x00\x00\x01\x00\x01\x00\xe1\x00K\x00\x1a\x00\x02\x00\x00'

使用

x.encode('hex')

给出一串十六进制值

x='000091000288**424d**001c00000001000100000001000100e1004b001a00020000'

其中0x42 是消息的结尾,0x4d 是消息的开头。

我可以使用

将其转换为以 10 为底的列表
y = map(ord,x)
print(y)

然后我有一种方法可以使用索引重新排序消息,但肯定有更简洁的方法吗?如何创建一个以 0x4d 开头的列表进行解析?

【问题讨论】:

【参考方案1】:

如果您使用的是 python3,这可能已经是字节:

x='\x00\x00\x91\x00\x02\x88BM\x00\x1c\x00\x00\x00\x01\x00\x01\x00\x00\x00\x01\x00\x01\x00\xe1\x00K\x00\x1a\x00\x02\x00\x00'

它可能看起来是这样的,因为 Python 为您打印了它,并且所有非 ascii 字符都以十六进制显示。您的消息开头在0x42, 0x4d 中,即ascii 中的BM,可以在0x880x00 之间的上述数据中看到\x88BM\x00

我建议只遍历 x 中的字节数组来进行解析。应该不需要编码和映射。

for b in x:
    if b == 0x4d:
        found_byte1 = True
    ...  # etc

【讨论】:

嗨,我首先尝试了这个,如果你查看编码的十六进制字符串 0x4d 是否存在,但在第一次打印输出中它已被替换为 \x88BM,我假设它包括 0x88,但总和如何合并 0x42和 0x4d 与 BM。 \x88BM 是三个单独的字节。 0x88 (\x88), 0x42 (B) & 0x4d (M) 好的,这是有道理的,所以要使用十六进制,需要先编码为十六进制?你如何获得一个十六进制列表? 我认为你不需要编码。 type返回的对象是什么ser.read()

以上是关于在 python 中即时解析二进制串行数据的主要内容,如果未能解决你的问题,请参考以下文章

二进制串行通信协议 - 得到意外响应

为串行设备创建/格式化十六进制值字符串

python struct.pack() 二进制文件,文件中打包二进制数据的存储与解析

从串行端口发送十六进制数据的问题

php的对象串行化

用于解析包含数组格式的 protobuf 数据的二进制文件的 Python API