2017-05-25 268 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