2017-05-25 266 views
0

我在这里有这个简短的代码片段,工作正常,但我有摆脱硬编码部分的问题。PySerial超时和回调

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

发送响应的设备会一次发送答复,还是会在数据中出现时间差?真的,通过串行链路发送数据的设备应该提供某种分组。 – quamrana

回答

0

如果答复包含长度字段标题,你可以做一个固定大小的read()拿到头,然后一个变量read()得到休息...

如果真的没有办法告诉回复有多大,然后超时是唯一可以想到的解决方案。但是,您显然错过了PySerial具有两个不同的超时值的细节:一个适用于整体操作,另一个适用于字符之间的间隙。您可以将timeout设置为多秒,以便永不过早结束有效回复,并将inter_byte_timeout(旧版本中为interCharTimeout)设置为大约0.1秒,以便一旦设备停止发送数据,您的read()就会立即结束。 (这假设设备从不在发送应答的过程中插入暂停)。

+0

我不知道inter_byte _timeout值。我可以将timout设置为3秒,inter_byte设置为0.1。设备在回复过程中不会暂停。 固定大小的读取也可以工作。但是,在可变长度内存在可变长度,因此编码有点奇怪! – Slylandro

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 
+0

虽然此解决方案是可行的。我喜欢jasonharper提出的解决方案的优雅。 – Slylandro