Posso usar o protocolo Xmodem com Pyseial?
Pergunta
Eu tenho uma conexão de trabalho com meu dispositivo serial via Pyseial, mas também quero transferir arquivos através do protocolo XMODEM como parte do meu programa.
Qual seria a maneira mais neutra de plataforma de fazer isso? Na pior das hipóteses, eu poderia close()
minha serial.Serial
objeto em python e uso subprocess
para chamar /usr/bin/sb
, mas isso parece deselegante.
Atualmente, estou no Ubuntu 9.10 e estou usando um adaptador USB-TTY.
Alguma ideia?
Solução
Há módulo Xmodem no Pypi. São necessárias duas funções no construtor para ler e escrever dados, implemente -os para trabalhar com sua porta serial aberta. Abaixo está a amostra simples de seu uso:
import serial
try:
from cStringIO import StringIO
except:
from StringIO import StringIO
from xmodem import XMODEM, CRC
from time import sleep
def readUntil(char = None):
def serialPortReader():
while True:
tmp = port.read(1)
if not tmp or (char and char == tmp):
break
yield tmp
return ''.join(serialPortReader())
def getc(size, timeout=1):
return port.read(size)
def putc(data, timeout=1):
port.write(data)
sleep(0.001) # give device time to send ACK
port = serial.Serial(port='COM5',parity=serial.PARITY_NONE,bytesize=serial.EIGHTBITS,stopbits=serial.STOPBITS_ONE,timeout=0,xonxoff=0,rtscts=0,dsrdtr=0,baudrate=115200)
port.write("command that loads data via xmodem\r\n")
sleep(0.02) # give device time to handle command
readUntil(CRC)
buffer = StringIO('data to send')
XMODEM(getc, putc).send(buffer, quiet = 1)
buffer.close()
readUntil()
Outras dicas
É super simples usar a implementação do protocolo XMODEM encontrada no PYPI. Algumas coisas a serem observadas sobre o exemplo acima é que existem algumas coisas que não são necessárias. (Talvez isso tenha funcionado para o autor ou com uma versão anterior do módulo?)
A documentação encontrado aqui é extremamente útil, então não deixe que isso o assuste. Você precisará de um remetente e um receptor, obviamente, e como não sei qual será o script Python, aqui estão dois exemplos que testei e estão funcionando abaixo. (basicamente copiado e colado a partir dos exemplos no Pypi)
import serial
from xmodem import XMODEM
ser = serial.Serial(port='COM56')
def getc(size, timeout=8):
gbytes = ser.read(size)
print(f'Read Byte: {gbytes}')
return gbytes or None
def putc(data, timeout=8):
pbytes = ser.write(data)
print(f'Put Byte: {pbytes}')
return pbytes or None
if __name__ == '__main__':
modem = XMODEM(getc, putc)
Para receber do dispositivo serial:
stream = open('output', 'wb')
modem.recv(stream, crc_mode=0)
Para enviar para o dispositivo serial:
stream = open('input', 'rb')
modem.send(stream)
A chave aqui é garantir que a taxa de transmissão seja definida de ambos os lados (inadimplente aqui). Não adicione nenhum atraso ou sono, pois não é baseado no tempo, mas baseado em transações. As impressões permitirão que você veja a transação em tempo real à medida que os dados fluem dentro ou fora da porta de arquivo/serial.
Não estou familiarizado com os detalhes do protocolo Xmodem, mas uma pessoa respondendo ao xmodem-for python A pergunta parece ser e até forneceu o que parece ser uma implementação grosseira do Xmodem dentro Pitão. Talvez você possa usar isso, ou idéias de outras respostas lá.