Línea de entrada serial con buffer

Tengo un dispositivo serie del que estoy tratando de leer la entrada. Le envié una cadena "ID \ r", y devuelve "ID XX \ r" (donde \ r es un retorno de carro ASCII, hex 0x0d).

Ya que la opción eol en serial.readline ya no es compatible, estoy usando TextIOWrapper para leer desde el puerto serial y devolver una línea a la vez.

Mi problema es que, en lugar de devolver mi cadena tan pronto como ve el retorno de carro, está esperando hasta el doble del tiempo de espera que configuré cuando abrí el puerto serie. Me gustaría que devuelva la cadena inmediatamente después de leer una línea completa, ya que puedo tener cientos de estos comandos para enviar al dispositivo y no quiero esperar el tiempo de espera cada vez. Si configuro el tiempo de espera en 0, no obtengo ninguna salida (presumiblemente porque mi script deja de esperar antes de que el dispositivo tenga la oportunidad de generar algo), y si configuro el tiempo de espera en Ninguno, el script se bloquea para siempre.

Aquí hay un script de prueba simple:

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

La secuencia de comandos siempre tarda 10 segundos desde el momento en que dice "leyendo" hasta que imprime la cadena "ID XX" que lee desde el puerto serie.

Estoy seguro de que el dispositivo está emitiendo el retorno de carro, ya que he usado strace para ver las lecturas:

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

Puede ver los 2 tiempos de espera de selección () que dan el retraso de 10 segundos, pero también puede ver claramente que se lee el retorno de carro. He intentado establecer el parámetro de nueva línea en 'Ninguno' y '' (que debería permitir automáticamente \ r, \ n, y \ r \ n), y en '\ r', pero con el mismo resultado cada vez.

También he intentado establecer el tamaño de búfer en la llamada BufferedRWPair () a '1' para evitar que se introduzca en el búfer, pero eso no hizo ninguna diferencia.

¿Alguna idea de lo que estoy haciendo mal?

Si no puedo hacer que esto funcione, mi siguiente paso será usar serial.read () para leer un carácter a la vez y hacer mi propio búfer de línea, pero quería intentar hacerlo de la manera "correcta" con textiowrapper primero.

Respuestas a la pregunta(4)

Su respuesta a la pregunta