Entrada serial com buffer de linha

Eu tenho um dispositivo serial que estou tentando ler a partir de entrada. Enviei uma string "ID \ r" e ela retorna "ID XX \ r" (onde \ r é um retorno de carro ASCII, hex 0x0d).

Como a opção eol em serial.readline não é mais suportada, estou usando o TextIOWrapper para ler a partir da porta serial e retornar uma linha por vez.

Meu problema é que, em vez de retornar minha string assim que ele vê o retorno do carro, ele está aguardando até o dobro do tempo limite definido quando abri a porta serial. Eu gostaria que ele retornasse a string imediatamente assim que ela lesse uma linha inteira, já que eu posso ter centenas desses comandos para enviar para o dispositivo e não quero esperar pelo timeout de cada vez. Se eu definir o tempo limite como 0, não receberei nenhuma saída (presumivelmente porque meu script pára de esperar antes que o dispositivo tenha a chance de gerar qualquer saída) e se eu definir o tempo limite como Nenhum, o script é bloqueado para sempre.

Aqui está um script de teste simples:

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

O script sempre leva 10 segundos a partir do momento em que diz "leitura" até imprimir a string "ID XX" que leu na porta serial.

Estou certo de que o dispositivo está retornando o retorno de carro, como eu usei strace para assistir as leituras:

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

Você pode ver os 2 select () timeouts que dão o atraso de 10 segundos, mas você também pode ver claramente o retorno de carro que está sendo lido. Eu tentei definir o parâmetro newline como 'Nenhum' e '' (que deve permitir automaticamente \ r, \ n e \ r \ n) e para '\ r', mas com o mesmo resultado a cada vez.

Eu também tentei definir o buffer_size na chamada BufferedRWPair () para '1' para mantê-lo de entrada de buffer, mas isso não fez diferença.

Alguma ideia do que estou fazendo errado?

Se eu não conseguir fazer isso funcionar, meu próximo passo será usar serial.read () para ler um caractere de cada vez e fazer meu próprio buffer de linha, mas eu queria tentar fazer isso da maneira "certa" com o textiowrapper primeiro.

questionAnswers(4)

yourAnswerToTheQuestion