我有一個串行設備,我試圖從中讀取輸入。我向它發送了一個字符串「ID \ r」,並且它返回「ID XX \ r」(其中\ r是一個ASCII回車,十六進制0x0d)。線路緩衝串行輸入
由於不再支持serial.readline上的eol選項,我使用TextIOWrapper從串行端口讀取並一次返回一行。
我的問題是,一旦它看到回車,而不是返回我的字符串,它會等到我打開串口時設置的兩倍超時。我希望它在讀取整行時立即返回字符串,因爲我可能會有數百個這樣的命令發送到設備,而且我不想每次都等待超時。如果我將超時設置爲0,則根本沒有輸出(大概是因爲我的腳本在設備有機會輸出任何內容之前停止等待),並且如果將超時設置爲無,腳本將永遠阻塞。
這裏有一個簡單的測試腳本:
import serial
import io
import time
ser = serial.Serial("/dev/ttyUSB0", baudrate=9600,
bytesize=8, parity='N', stopbits=1,
xonxoff=0, rtscts=1, timeout=5)
sio = io.TextIOWrapper(io.BufferedRWPair(ser, ser),
newline=None)
sio.write(unicode("ID\r"))
sio.flush()
print "reading..."
x = sio.readline()
print len(x)
print x
腳本總是需要10秒,從它說:「讀」,直到它打印「ID XX」的字符串,它從串口讀取時間。
我敢肯定,該設備輸出回車,因爲我用strace的觀看寫着:
select(4, [3], [], [], {5, 0}) = 1 (in [3], left {4, 991704})
read(3, "I", 8192) = 1
select(4, [3], [], [], {5, 0}) = 1 (in [3], left {4, 999267})
read(3, "D", 8191) = 1
select(4, [3], [], [], {5, 0}) = 1 (in [3], left {4, 999420})
read(3, " ", 8190) = 1
select(4, [3], [], [], {5, 0}) = 1 (in [3], left {4, 999321})
read(3, "X", 8189) = 1
select(4, [3], [], [], {5, 0}) = 1 (in [3], left {4, 999355})
read(3, "X", 8188) = 1
select(4, [3], [], [], {5, 0}) = 1 (in [3], left {4, 999171})
read(3, "\r", 8187) = 1
select(4, [3], [], [], {5, 0}) = 0 (Timeout)
select(4, [3], [], [], {5, 0}) = 0 (Timeout)
你可以看到2選擇()超時,讓10秒延遲,但您也可以清楚地看到正在讀取的回車。我嘗試將newline參數設置爲'None'和''(它應該自動允許\ r,\ n和\ r \ n),並設置爲'\ r',但每次都有相同的結果。
我也嘗試將BufferedRWPair()調用中的buffer_size設置爲'1',以防止緩衝輸入,但這沒有什麼區別。
任何想法我做錯了什麼?
如果我不能得到這個工作,我的下一步將是使用serial.read()來一次讀取一個字符,並做我自己的行緩衝,但我想嘗試做到這一點「右「先用textiowrapper的方式。
您確定打印語句是不是觸發輸出緩衝?嘗試使用-u運行它 – 2012-04-19 07:18:19