У меня есть последовательное устройство, с которого я пытаюсь считать входные данные. Я отправил ему строку «ID\r», и он возвращает «ID XX\r» (, где \r — это возврат каретки ASCII, шестнадцатеричный 0x0d).
Поскольку опция eol в serial.readline больше не поддерживается, я использую TextIOWrapper для чтения из последовательного порта и возврата строки за раз.
Моя проблема заключается в том, что вместо того, чтобы возвращать мою строку, как только она увидит возврат каретки, она ждет до тех пор, пока не удвоится время ожидания, которое я установил, когда открывал последовательный порт. Я бы хотел, чтобы он возвращал строку немедленно, как только он считывал всю строку, поскольку у меня могут быть сотни этих команд для отправки на устройство, и я не хочу каждый раз ждать тайм-аута. Если я установлю тайм-аут на 0, то я вообще не получу вывода (, предположительно потому, что мой скрипт перестанет ждать, прежде чем устройство сможет что-либо вывести ), а если я установлю тайм-аут на None, скрипт блокируется навсегда.
Вот простой тестовый сценарий.:
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 таймаута select(), которые дают 10-секундную задержку, но вы также ясно видеть, как читается возврат каретки. Я попытался установить для параметра новой строки значение «Нет» и '' (, что должно автоматически разрешать \r, \n и \r\n), и значение '\ r', но с тем же результатом каждый время.
Я также пытался установить размер буфера_в вызове BufferedRWPair()равным 1, чтобы предотвратить буферизацию ввода, но это не имело значения.
Есть идеи, что я делаю не так?
Если я не смогу заставить это работать,моим следующим шагом будет использование serial.read()для чтения символов за раз и выполнения собственной буферизации строк, но я хотел сначала попытаться сделать это «правильным» способом с textiowrapper.