Tôi có thiết bị nối tiếp mà tôi đang cố đọc đầu vào. Tôi đã gửi nó một chuỗi "ID \ r", và nó trả về "ID XX \ r" (trong đó \ r là một trở về vận chuyển ASCII, hex 0x0d).Đầu vào nối tiếp được lưu vào bộ đệm dòng
Vì tùy chọn eol trên serial.readline không còn được hỗ trợ, tôi đang sử dụng TextIOWrapper để đọc từ cổng nối tiếp và trả về một dòng tại một thời điểm.
Vấn đề của tôi là thay vì trả lại chuỗi của tôi ngay sau khi nó nhìn thấy vận chuyển trở lại, nó chờ đợi cho đến khi hai lần thời gian chờ tôi đặt khi tôi mở cổng nối tiếp. Tôi muốn nó trả về chuỗi ngay lập tức ngay khi nó đọc toàn bộ dòng vì tôi có thể có hàng trăm lệnh này để gửi tới thiết bị và tôi không muốn chờ thời gian chờ mỗi lần. Nếu tôi đặt thời gian chờ là 0, thì tôi không có đầu ra nào cả (có lẽ vì tập lệnh của tôi ngừng chờ trước khi thiết bị có cơ hội xuất bất kỳ thứ gì) và nếu tôi đặt thời gian chờ thành Không, tập lệnh sẽ chặn vĩnh viễn.
Dưới đây là một kịch bản thử nghiệm đơn giản:
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
Kịch bản luôn mất 10 giây kể từ khi nó nói "đọc" cho đến khi nó in "ID XX" chuỗi mà nó đọc từ cổng nối tiếp.
Tôi chắc chắn rằng thiết bị được xuất ra trở về vận chuyển, như tôi đã sử dụng strace để xem lần đọc:
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)
Bạn có thể thấy 2 lựa chọn() timeout mà cung cấp cho sự chậm trễ 10 giây , nhưng bạn cũng có thể thấy rõ sự trở lại của xe ngựa đang được đọc. Tôi đã thử đặt tham số dòng mới thành 'Không' và '' (sẽ tự động cho phép \ r, \ n và \ r \ n), và thành '\ r', nhưng với cùng một kết quả mỗi lần.
Tôi cũng đã thử thiết lập buffer_size trong lời gọi BufferedRWPair() thành '1' để giữ cho nó khỏi đầu vào đệm, nhưng điều đó không có sự khác biệt.
Bất kỳ ý tưởng nào tôi đang làm sai?
Nếu tôi không thể làm việc này, bước tiếp theo của tôi sẽ là sử dụng serial.read() để đọc một ký tự tại một thời điểm và làm theo dòng đệm của riêng tôi, nhưng tôi muốn cố gắng làm điều đó "cách với textiowrapper đầu tiên.
Bạn có chắc chắn lệnh in không kích hoạt bộ đệm đầu ra? Hãy thử chạy nó với -u –