读取ASCII /二进制混合的串行数据流-如何找到定界符?

时间:2019-06-11 13:47:12

标签: python

我正在尝试使用Python 3从一台以ASCII和二进制混合输出的设备中读取串行数据。

消息格式为:“ $ PASHR, msg类型二进制有效载荷校验和,\ r \ n”(减去引号) )

为了使它更有趣,有几种不同的消息类型,它们具有不同的有效载荷长度,因此我不能只读取X个字节(我可以根据消息类型推断有效载荷长度)。每20秒以115200波特的速度发送各种类型的可变数量消息(总共约15条)的顺序。

我可能无法通过serial.readline()读取此消息,可能是因为有效载荷中嵌入了换行符。

我认为,如果我可以将行尾字符设置为序列“ $ PASHR”,这将为我提供一种构造消息的方式-即,一个$ PASHR和下一个之间的所有内容都是一条消息,而在二进制有效载荷中看到序列的可能性为零。但是我无法使用serial.newline = b'$ PASHR'或readuntil(b'$ PASHR')使其工作-我仍然得到可变长度的读取。我怀疑serial.timeout设置会进入解决方案,但是我不确定如何。

这是我昨晚结束的最后一个版本:

     delimiter = b'$PASHR' 
     while True:
            if self.serial.in_waiting:
                message = self.serial.read_until(delimiter)

当给定的每个记录应具有相同的长度时,我尝试过的每个方法都给出了可变的响应长度。有没有办法将换行符设置为该多字符字符串,或者我应该使用其他/更好的方法吗?

谢谢!

1 个答案:

答案 0 :(得分:0)

我想我明白了。这似乎可以超时1秒:

self.serial.timeout = 1
delimiter = b'$PASHR'
if self.serial.in_waiting:
    message = self.serial.read_until(delimiter)
    if len(message) > 6: # ignore carryover PASHR'
        ***process message***

当我仔细查看可变长度返回值时,我发现第一个不完整周期之后的消息序列为:

b'$PASHR' (6 bytes)
b',MPC,*data**checksum*\r\n$PASHR' (108 bytes)
...
b',MPC,*data**checksum*\r\n' (102 bytes)
(delay)
b'$PASHR' (6 bytes)

该序列中最后一条消息的定界符被切掉,并在下一个序列的开头输出。我可以解决的。

我将尝试Deepstop关于inter_byte超时的想法,因为它可能比使用原始超时更为优雅,并且可能会解决部分消息问题。