我在这里有一小段代码可以正常工作,但我有摆脱硬编码部分的问题。
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循环。
有更稳定/动态的方法吗?如果请求太长或者在没有完整数据传输的情况下我可以破坏我的读缓冲区,我可能会用完时间。另一方面,增加计时器意味着我的请求速率将减慢(但是增加读缓冲区没有问题)。
答案 0 :(得分:0)
如果回复的标题包含长度字段,您可以使用固定大小的read()
来获取标题,然后使用变量read()
来获取其余内容...
如果真的没有办法告诉回复有多大,那么超时是唯一可以想到的解决方案。但是,您显然错过了PySerial有两个不同超时值的细节:一个适用于整个操作,另一个适用于字符之间的间隙。您可以将timeout
设置为多秒,这样您就不会过早地结束有效回复,并将inter_byte_timeout
(旧版本中为interCharTimeout
)设置为0.1秒,这样您的{{{一旦设备停止发送数据,1}}几乎会立即结束。 (这假设设备在发送回复的过程中从不插入暂停。)
答案 1 :(得分:0)
如果响应(从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