Python:使用PySerial发送状态位和时间戳的最佳方法是什么

时间:2010-12-01 18:46:16

标签: python serial-port status 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 个答案:

答案 0 :(得分:0)

嗯,显然每个字符需要一个字节发送,所以如果你可以将你的数据编码为ascii字符串(Python 2中的str,Python 3中的bytes),这是最有效的。< / p>

struct模块绝对是一个好主意:它将Python数据打包成一个字符串(并在另一端解包)。那对你的时间戳有用;将它们打包为任何类型的int或long似乎合适(请参阅链接文档以获取选项)。

但是,

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)

如果你想用1s和0s的字符串进行编码/解码,用生成列表/元组的位代替:

"".join("1" if (x&y) else "0" for y in pot)

答案 1 :(得分:0)

您希望多久发送一次这些更新?如果update_frequency * length_of_message远远小于串行连接的数据速率,那么几乎没有理由担心数据编码的效率,甚至可能会考虑将内容扩展为更易于阅读的格式,尤其是当您'开始了。