Question

J'ai une connexion de travail avec mon appareil série via pyserial, mais je veux aussi transférer des fichiers via le protocole XMODEM dans le cadre de mon programme.

Quelle serait la façon la plus la plate-forme neutre pour le faire? Le pire des cas, je ne pouvais close() mon objet serial.Serial en Python et utiliser subprocess de faire appel à /usr/bin/sb, mais qui semble inélégant.

Je suis actuellement sur Ubuntu 9.10 et je utilise un adaptateur USB-ATS.

Toutes les idées?

Était-ce utile?

La solution

Il y a le module xmodem sur PyPI. Il prend deux fonctions dans le constructeur pour les données de lecture et d'écriture, les mettre en œuvre pour travailler avec votre port série ouvert. Ci-dessous est simple échantillon de son utilisation:

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

Autres conseils

Il est super simple à utiliser la mise en œuvre du protocole de XMODEM trouvé sur PyPI. Quelques choses à noter à propos de l'exemple ci-dessus, il y a certaines choses qui ne sont pas nécessaires. (Peut-être que cela a fonctionné pour l'auteur ou avec une version précédente du module?)

La documentation trouvé est extrêmement utile, alors ne laissez pas vous faire peur. Vous aurez besoin d'un émetteur et un récepteur évidemment, et comme je ne sais pas lequel le script Python sera, voici deux exemples que je l'ai testé et travaillent ci-dessous. (Essentiellement copié et collé des exemples sur 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)

Pour recevoir du périphérique série:

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

Pour envoyer au périphérique série:

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

La clé est ici pour être sûr que la vitesse de transmission est réglée sur les deux côtés (par défaut ici). Ne pas ajouter de tout retard ou le sommeil que ce n'est pas en fonction du temps, mais basé sur les transactions. les impressions vous permettra de voir le temps réel des transactions comme les flux de données dans ou hors du fichier / port série.

Je ne connais pas les détails du protocole xmodem, mais une personne répondant à la xmodem-pour-python question semble être, et a même fourni ce qui ressemble à une mise en œuvre brute de xmodem Python. Peut-être que vous pourriez l'utiliser, ou des idées d'autres réponses là.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top