Wejście szeregowe buforowane liniowo

Mam urządzenie szeregowe, z którego próbuję odczytać dane wejściowe. Wysłałem mu ciąg „ID” i zwraca „ID XX r” (gdzie r jest znakiem powrotu karetki ASCII, szesnastkowym 0x0d).

Ponieważ opcja eol w serial.readline nie jest już obsługiwana, używam TextIOWrapper do odczytu z portu szeregowego i zwracania linii na raz.

Moim problemem jest to, że zamiast zwracać mój łańcuch, gdy tylko zobaczy powrót karetki, czeka aż do dwukrotnego przekroczenia limitu czasu ustawionego po otwarciu portu szeregowego. Chciałbym, aby natychmiast zwrócił łańcuch, gdy tylko odczyta całą linię, ponieważ mogę mieć setki tych poleceń do wysłania do urządzenia i nie chcę za każdym razem czekać na limit czasu. Jeśli ustawię limit czasu na 0, to nie otrzymam żadnego wyjścia (prawdopodobnie dlatego, że mój skrypt przestaje czekać, zanim urządzenie będzie miało szansę na wyjście), a jeśli ustawię limit czasu na Brak, skrypt blokuje się na zawsze.

Oto prosty skrypt testowy:

<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>

Skrypt zawsze zajmuje 10 sekund od chwili, gdy mówi „czytanie”, dopóki nie wydrukuje ciągu „ID XX”, który odczytał z portu szeregowego.

Jestem pewien, że urządzenie wysyła znak powrotu karetki, ponieważ użyłem strace do oglądania odczytów:

<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>

Możesz zobaczyć 2 limity czasu (), które dają 10-sekundowe opóźnienie, ale możesz również wyraźnie odczytać odczyt karetki. Próbowałem ustawić parametr newline na „None” i „” (co powinno automatycznie zezwalać na r, n i r) oraz na „r”, ale za każdym razem z takim samym wynikiem.

Próbowałem też ustawić parametr buffer_size w wywołaniu BufferedRWPair () na „1”, aby nie wpływać na buforowanie, ale to nie robiło różnicy.

Jakiś pomysł, co robię źle?

Jeśli nie uda mi się tego uzyskać, następnym krokiem będzie użycie serial.read () do odczytania znaku na raz i zrobienia własnego buforowania linii, ale chciałem spróbować zrobić to w odpowiedni sposób z textiowrapper pierwszy.

questionAnswers(4)

yourAnswerToTheQuestion