2010-02-18 13 views
29

Ich weiß, dass ich z. pySerial, um mit seriellen Geräten zu sprechen, aber was, wenn ich gerade kein Gerät habe, aber noch einen Client dafür schreiben muss? Wie kann ich ein "virtuelles serielles Gerät" in Python schreiben und pySerial damit sprechen lassen, als würde ich beispielsweise einen lokalen Webserver betreiben? Vielleicht suche ich einfach nicht gut, aber ich konnte keine Informationen zu diesem Thema finden.Virtuelles serielles Gerät in Python?

Antwort

4

Es kann einfacher sein, etwas wie com0com zu verwenden (wenn Sie unter Windows sind), um eine virtuelle serielle Schnittstelle einzurichten und darauf aufzubauen.

4

es ein bisschen hängt davon ab, was Sie jetzt erreichen wollen ...

Sie den Zugriff auf die serielle Schnittstelle in einer Klasse wickeln konnte und eine Implementierung schreiben Buchse I/O oder Datei-I/O verwenden . Schreiben Sie dann Ihre serielle I/O-Klasse, um dieselbe Schnittstelle zu verwenden, und schließen Sie sie an, wenn das Gerät verfügbar ist. (Dies ist ein gutes Design zum Testen der Funktionalität, ohne dass externe Hardware erforderlich ist.)

Oder, wenn Sie den seriellen Port für eine Befehlszeilenschnittstelle verwenden möchten, könnten Sie stdin/stdout verwenden.

Oder gibt es diese andere Antwort über virtual serial devices for linux.

+0

Ja, eine „virtuelles serielles Gerät“ Klasse schreiben, die die pyserial Schnittstelle dupliziert. Dann kann Ihr Code entweder Ihre Klasse "virtuelles Gerät" oder die echte pySerial-Schnittstelle synonym verwenden. –

+0

Dies ist eine gute Implementierung, da es ziemlich einfach zu implementieren ist und auf allen Plattformen funktioniert! – Pithikos

+0

Es tut uns leid, diesen alten Beitrag zu aktualisieren, aber könnten Sie bitte etwas mehr ausarbeiten? Dies wäre sehr hilfreich für mich. Danke – rowman

27

dies etwas ist, ich tat und arbeitete bisher für mich aus:

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) 

Wenn Sie mehrere virtuelle Ports erstellen werden Sie keine Probleme haben, da die verschiedenen Meistern verschiedene Datei-Deskriptoren erhalten sogar wenn sie denselben Namen haben.

+0

Dies ist genau die Antwort, die ich gesucht habe. Das funktioniert für mich unter Mac OS X. – DrRobotNinja

+1

Dies funktioniert nicht unter Windows, dem das von pty benötigte termios-Modul fehlt. – OYRM

+1

Ich scheine in der Lage zu sein, von dem gefälschten Gerät gut zu lesen (dh ich habe ein anderes Programm, das auf dem Endgerät unter s_name schreibt), aber immer wenn ich 'ser.write (" ... ")', diesen Text ausstelle Ich werde einfach das nächste Mal zurückgemeldet, wenn ich 'os.read (master, 1000)' höre, unabhängig davon, ob irgendetwas mit dem Port verbunden ist, und das andere Ende des Ports scheint die Daten nicht zu bekommen. – Ponkadoodle

2

Wenn Sie Linux ausführen, können Sie den socat Befehl verwenden, etwa so:

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

Wenn der Befehl ausgeführt wird, wird es Ihnen, von denen serielle Ports informieren sie geschaffen hat. Auf meinem Rechner sieht das so:

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] 

Jetzt kann ich zu /dev/pts/13 und erhalten auf /dev/pts/12 schreiben, und umgekehrt.

1

Ich war in der Lage, eine beliebige serielle Schnittstelle ./foo mit diesem Code zu emulieren:

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 Bedürfnisse installiert (sudo apt-get install socat) sowie das pyserial Python-Paket wird (pip install pyserial).

Öffnen Sie den Python-Interpreter und importieren SerialEmulator:

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

Ihr Client-Programm kann dann wickeln ./ttyclient mit pyserial, die virtuelle serielle Schnittstelle zu schaffen. Sie könnten auch client_port /dev/ttyUSB0 oder ähnlich machen, wenn Sie den Client-Code nicht ändern können, aber möglicherweise sudo benötigen.

Auch bewusst sein, diese Ausgabe: Pyserial does not play well with virtual port