Python:使用PySerial发送状态位和时间戳的最佳方式是什么
我搜索和阅读了很多内容,但还没有找到一个明确的答案。我正在制作一个Python应用程序,它会通过串口与另一个应用程序进行通信。我使用了PySerial来实现这个功能。我想发送的数据包类型包括状态信息和数据读数。
我打算将我的数据包格式设计成这样:
[ Start Byte ][ Length ][ Message ][ End Byte ][ Checksum ]
不过我觉得我不需要结束字节,因为里面已经有长度信息了。我这样想对吗?
我考虑将数据包中的“消息”部分设计成状态信息,像这样:
[ MsgTypeID ][ PacketID ][ Status Bits ][ Timestamp ]
这里的消息ID只是用来区分这是一个状态包,而不是数据包。状态信息本身由16位组成,表示发送应用程序中多个子系统的状态。对于某些子系统,一个位就能提供足够的信息('0'表示子系统关闭/低/假,'1'表示开启/高/真)。其他的子系统可能需要2或3个位来表示状态等。为了原型测试,我只是简单地将这些位拼接成一个字符串,比如'1001110101101100'
,然后通过串口发送出去,校验和是状态位的模256。
我对Python和串口通信还很陌生,但我知道这样可能会浪费带宽。我知道PySerial需要发送字符串,但像这样将每个位表示为'0'或'1',实际上是为每个位都使用了完整的字符串表示。我在想,有什么更好的方法可以发送这些位,以减少带宽的使用呢?
比如,我是否可以将每8个位转换成十六进制,然后发送拼接的十六进制字节,像这样:
'10011101' + '01101100'
表示为
'\x9d' + '\x6c'
或者我应该将它们作为ASCII发送?我还看到有人提到Struct模块。我是否应该走这条路呢?
我还在想如何表示消息中的时间戳部分。
如果你能给我一些帮助或建议,我将非常感激。
非常感谢 :)
2 个回答
你打算多频繁地发送这些更新呢?如果你发送更新的频率乘以消息的长度,远远小于串口连接的数据传输速度,那就没必要太担心数据编码的效率了。其实你甚至可以考虑把内容弄得更容易让人看懂,特别是在你刚开始的时候。
显然,每发送一个字符需要一个字节,所以如果你能把数据编码成ASCII字符串(在Python 2中是str
,在Python 3中是bytes
),那就是最有效的方式。
struct模块绝对是个好主意:它可以把Python的数据打包成字符串(然后在另一端解包)。这对于你的时间戳是有效的;你可以把它们打包成合适的整数类型(可以查看链接的文档了解你的选择)。
不过,struct模块不处理单独的位,所以你得自己来做。我之前做过一个字典,用来把字符转换成八个True
/False
值的组合:
要解码的话:
pot = [2**x for x in range(8)] # Powers of 2 (bytes with one 1 and seven 0s)
bitvalues = {}
for x in range(256):
bitvalues[chr(x)] = [(x & y) != 0 for y in pot]
如果你想要创建一个编码用的字典,可以把最后一行替换成:
bitvalues[tuple((x & y) != 0 for y in pot)] = chr(x)
如果你想从1和0的字符串进行编码/解码,可以把生成列表/元组的位替换成:
"".join("1" if (x&y) else "0" for y in pot)