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).Entrada serial con buffer de línea
Dado que la opción eol en serial.readline ya no es compatible, estoy usando TextIOWrapper para leer desde el puerto serie y devolver una línea a la vez.
Mi problema es que, en lugar de devolver la cadena tan pronto como ve el carro, está esperando hasta el doble del tiempo de espera que establecí cuando abrí el puerto serie. Me gustaría devolver la cadena inmediatamente tan pronto como lea 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 establezco el tiempo de espera en 0, no obtengo ningún resultado (probablemente 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 bloquea para siempre.
Aquí es un simple script de prueba:
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
El guión siempre tarda 10 segundos desde el momento en que dice "leer" hasta que se imprime la cadena "ID XX" que se lee desde el puerto serie.
Estoy seguro de que el dispositivo está enviando el retorno de carro, como yo he utilizado strace para ver las lecturas:
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)
se puede ver el 2 Seleccione() que dan los tiempos de espera de 10 segundos de retardo , pero también puede ver claramente que se lee el retorno de carro. Intenté 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 buffer_size en el BufferedRWPair() llame a '1' para evitar que la entrada de amortiguación, pero eso no hacía 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 propia línea de almacenamiento en búfer, pero quería intentar hacerlo "bien" "camino con textiowrapper primero.
¿Estás seguro de que la declaración de impresión no está activando el almacenamiento en búfer de salida? Intenta ejecutarlo con -u –