Un périphérique série virtuel en Python?

je sais que je peux utiliser, par exemple, pySerial de parler à des périphériques série, mais si je n'ai pas d'appareil pour l'instant, mais encore le besoin d'écrire un client? Comment puis-je écrire un "périphérique série virtuel" en Python et demander à pySerial de lui parler, comme je voudrais, disons, lancer un serveur web local? Peut-être que je ne cherche pas bien, mais j'ai été incapable de trouver des informations sur ce sujet.

30
demandé sur dsolimano 2010-02-18 22:59:31

6 réponses

c'est quelque chose que j'ai fait et a fonctionné pour moi jusqu'à présent:

import os, pty, serial

master, slave = pty.openpty()
s_name = os.ttyname(slave)

ser = serial.Serial(s_name)

# To Write to the device
ser.write('Your text')

# To read from the device
os.read(master,1000)

si vous créez plus de ports virtuels, vous n'aurez aucun problème puisque les différents maîtres obtiennent des descripteurs de fichier différents même s'ils ont le même nom.

27
répondu Aquiles 2013-02-26 17:29:44

il peut être plus facile d'utiliser quelque chose comme com0com (si vous êtes sur Windows) pour configurer un port série virtuel, et développer sur ce.

5
répondu mtrw 2010-02-18 20:14:42

Ça dépend un peu de ce que vous essayez d'accomplir maintenant...

vous pouvez envelopper l'accès au port série dans une classe et écrire une implémentation pour utiliser les entrées/sorties de socket ou les entrées/sorties de fichier.ensuite, écrivez votre classe d'entrées/sorties de série pour utiliser la même interface et la brancher lorsque le périphérique est disponible. (C'est effectivement une bonne conception pour tester la fonctionnalité sans nécessiter de matériel externe.)

Ou, si vous allez utiliser le port série pour une commande interface de ligne, vous pouvez utiliser stdin / stdout.

ou, il y a cette autre réponse sur les périphériques série virtuels pour linux .

4
répondu Dave Bacher 2017-05-23 12:25:16

j'ai pu émuler un port série arbitraire ./foo en utilisant ce code:

SerialEmulator.py

import os, subprocess, serial, time

# this script lets you emulate a serial device
# the client program should use the serial port file specifed by client_port

# if the port is a location that the user can't access (ex: /dev/ttyUSB0 often),
# sudo is required

class SerialEmulator(object):
    def __init__(self, device_port='./ttydevice', client_port='./ttyclient'):
        self.device_port = device_port
        self.client_port = client_port
        cmd=['/usr/bin/socat','-d','-d','PTY,link=%s,raw,echo=0' %
                self.device_port, 'PTY,link=%s,raw,echo=0' % self.client_port]
        self.proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        time.sleep(1)
        self.serial = serial.Serial(self.device_port, 9600, rtscts=True, dsrdtr=True)
        self.err = ''
        self.out = ''

    def write(self, out):
        self.serial.write(out)

    def read(self):
        line = ''
        while self.serial.inWaiting() > 0:
            line += self.serial.read(1)
        print line

    def __del__(self):
        self.stop()

    def stop(self):
        self.proc.kill()
        self.out, self.err = self.proc.communicate()

socat doit être installé ( sudo apt-get install socat ), ainsi que le paquet pyserial python ( pip install pyserial ).

ouvrir l'interpréteur python et importer SerialEmulator:

>>> from SerialEmulator import SerialEmulator
>>> emulator = SerialEmulator('./ttydevice','./ttyclient') 
>>> emulator.write('foo')
>>> emulator.read()

votre programme client peut alors envelopper ./ttyclient avec pyserial, créant le port série virtuel. Vous pouvez aussi faire client_port /dev/ttyUSB0 ou similaire si vous ne pouvez pas modifier le code client, mais vous pourriez avoir besoin de sudo .

soyez également conscient de cette question: Pyserial ne joue pas bien avec le port virtuel

3
répondu Patrick Steadman 2017-05-23 12:00:25

si vous utilisez Linux, vous pouvez utiliser la commande socat comme suit:

socat -d -d pty,raw,echo=0 pty,raw,echo=0

lorsque la commande s'exécute, elle vous informe des ports série qu'elle a créés. Sur ma machine cela ressemble à:

2014/04/23 15:47:49 socat[31711] N PTY is /dev/pts/12
2014/04/23 15:47:49 socat[31711] N PTY is /dev/pts/13
2014/04/23 15:47:49 socat[31711] N starting data transfer loop with FDs [3,3] and [5,5]

maintenant je peux écrire à /dev/pts/13 et recevoir sur /dev/pts/12 , et vice versa.

2
répondu Richard 2014-04-23 20:55:57

Peut-être une boucle appareil fera le travail si vous avez besoin de tester votre application sans accès à un périphérique. Il est inclus dans pySerial 2.5 https://pythonhosted.org/pyserial/url_handlers.html#loop

2
répondu steko 2016-03-15 05:33:49