PySerial 超时和回调

PySerial timeout and callback

我这里有一小段代码可以正常工作,但我遇到了删除硬编码部分的问题。

ser = serial.Serial()
ser.baudrate = 38400 
ser.port = '/dev/ttyUSB0'
ser.parity = serial.PARITY_EVEN
ser.timeout = 1

ser.open()
ser.flushInput()
ser.write(command) #command here is a simple request for data to my device 
msg = ser.read(200)
ser.close()

虽然这工作正常,但我遇到的问题是这个。返回消息的长度可以从 8 字节到近 200 字节不等,具体取决于注册的内容。通过使用超时,我可以防止我的读取命令在未收到 200 个字节时停止。我也不知道返回消息的长度,因此我无法动态更改 ser.read。此外,传输结束时没有常量结束行或常量字符可锁定在 while 循环中。

有没有更多的stable/dynamic方法来做到这一点?如果请求太长,我可能会 运行 超时,或者我可能会在没有完成数据传输的情况下破坏我的读取缓冲区。另一方面,增加定时器意味着我的请求速率会变慢(但是增加读取缓冲区没有问题)。

如果回复有一个包含长度字段的 header,您可以执行 fixed-size read() 来获取 header,然后一个变量 read() 得到其余的...

如果实在无法判断回复有多大,那么超时是唯一可以想到的解决方案。但是,您显然错过了 PySerial 有两种不同超时值的细节:一种适用于整体操作,另一种适用于字符之间的间隙。您可以将 timeout 设置为多秒,这样您就不会过早地结束有效回复,并将 inter_byte_timeout(旧版本中的 interCharTimeout)设置为 0.1 秒,这样您的 read() 将在设备停止发送数据后几乎立即结束。 (这假设设备从不在发送回复的过程中插入暂停。)

如果响应(从 8 字节到 200 字节)是连续的,那么您可以有一个循环,它将从对 ser.read(200) 的调用接收到的字节连接起来,但将超时设置为 1/100 秒.然后当你连续两次超时没有收到任何字节时,你就知道你在消息的末尾。

exit = 0
while exit < 2:
    more = ser.read(200)
    msg += more
    if len(more) == 0:
        exit += 1
    else:
        exit = 0