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