Frage

Ich habe eine Arbeitsverbindung mit meinem seriellen Gerät über Pyserial, aber ich möchte auch Dateien über das Xmodem -Protokoll als Teil meines Programms übertragen.

Welches wäre der plattformneutralste Weg, dies zu tun? Schlimmster Fall könnte ich close() mein serial.Serial Objekt in Python und Verwendung subprocess Aufrufen /usr/bin/sb, aber das scheint unelegant.

Ich bin derzeit auf Ubuntu 9.10 und verwende einen USB-TTY-Adapter.

Irgendwelche Ideen?

War es hilfreich?

Lösung

Es gibt XModem -Modul auf PYPI. Im Konstruktor sind zwei Funktionen zum Lesen und Schreiben von Daten erforderlich, um sie mit Ihrem geöffneten seriellen Port zu arbeiten. Unten ist eine einfache Probe seiner Verwendung:

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

Andere Tipps

Es ist super einfach, die auf PYPI gefundene XModem -Protokollimplementierung zu verwenden. Ein paar Dinge, die über das obige Beispiel zu beachten sind, ist, dass einige Dinge nicht benötigt werden. (Vielleicht funktionierte dies für den Autor oder mit einer früheren Version des Moduls?)

Die Dokumentation Hier gefunden ist äußerst hilfreich, also lassen Sie sich nicht von Ihnen erschrecken. Sie benötigen natürlich einen Absender und einen Empfänger, und da ich nicht weiß, welches das Python -Skript sein wird, hier sind zwei Beispiele, die ich getestet habe und die unten arbeiten. (im Grunde genommen kopiert und aus den Beispielen auf PYPI eingefügt)

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)

Vom Seriengerät empfangen:

stream = open('output', 'wb')
modem.recv(stream, crc_mode=0)

Zum seriellen Gerät senden:

stream = open('input', 'rb')
modem.send(stream)

Der Schlüssel hier ist, sicherzustellen, dass die Baud -Rate auf beiden Seiten festgelegt ist (hier defaugiert). Fügen Sie keine Verzögerung oder Schlaf hinzu, da dies nicht zeitbasiert, sondern auf Transaktionsbasis basiert. Mit den Drucken können Sie die Echtzeit der Transaktion sehen, wenn die Daten in oder aus der Datei/dem seriellen Port fließen.

Ich bin mit den Details des XModem -Protokolls nicht vertraut, sondern eine Person, die das beantwortet Xmodem-for-Python Die Frage scheint zu sein und hat sogar eine rohe Implementierung von Xmodem geliefert, die aussieht in Python. Vielleicht könnten Sie das oder Ideen von anderen Antworten dort verwenden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top