2010-02-18 29 views
29

So che posso usare per es. pySerial per parlare con i dispositivi seriali, ma cosa succede se non ho un dispositivo in questo momento, ma ho ancora bisogno di scrivere un client per questo? Come posso scrivere un "dispositivo seriale virtuale" in Python e avere pySerial parlare con esso, come direi, per esempio, eseguire un server web locale? Forse non sto cercando bene, ma non sono riuscito a trovare alcuna informazione su questo argomento.Dispositivo seriale virtuale in Python?

risposta

4

Potrebbe essere più facile usare qualcosa come com0com (se sei su Windows) per configurare una porta seriale virtuale e svilupparla.

4

Dipende un po 'su quello che stai cercando di realizzare la società ...

Si potrebbe avvolgere l'accesso alla porta seriale in una classe e scrivere un'implementazione di utilizzare presa I/O o file di I/O . Quindi scrivere la classe I/O seriale per utilizzare la stessa interfaccia e collegarla quando il dispositivo è disponibile. (Questo è in realtà un buon progetto per testare le funzionalità senza richiedere hardware esterno.)

Oppure, se si intende utilizzare la porta seriale per un'interfaccia della riga di comando, è possibile utilizzare stdin/stdout.

Oppure, c'è questa altra risposta su virtual serial devices for linux.

+0

Sì, scrivere una classe "dispositivo seriale virtuale" che duplica l'interfaccia pySerial. Quindi il tuo codice può utilizzare la tua classe "dispositivo virtuale" o la vera interfaccia pySerial, in modo intercambiabile. –

+0

Questa è una buona implementazione dal momento che è piuttosto semplice da implementare e funzionerà su tutte le piattaforme! – Pithikos

+0

Siamo spiacenti di aggiornare questo vecchio post, ma potresti approfondire un po 'di più? Questo sarebbe molto utile per me. Grazie – rowman

27

questa è una cosa che ho fatto e lavorato per me finora:

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) 

Se si creano le porte virtuali non dovreste avere problemi come i diversi maestri ottengono diversi descrittori di file anche se hanno lo stesso nome

+0

Questa è esattamente la risposta che stavo cercando. Questo funziona per me su Mac OS X. – DrRobotNinja

+1

Questo non funzionerà su Windows, che non ha il modulo termios richiesto da pty. – OYRM

+1

Mi sembra di essere in grado di leggere il dispositivo finto bene (cioè ho un altro programma che scrive sul dispositivo in endpoint 's_name'), ma ogni volta che rilascio' ser.write ("...") ', quel testo appena risuonato la prossima volta che ho 'os.read (master, 1000)', indipendentemente dal fatto che qualcosa sia connesso alla porta, e l'altra estremità della porta non sembra ottenere i dati. – Ponkadoodle

2

Se si esegue Linux È possibile usare il comando socat per questo, in questo modo:

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

Quando l'esecuzione del comando, che vi informerà delle quali porte seriali che ha creato. Sulla mia macchina questo appare come:

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] 

adesso posso scrivere a /dev/pts/13 e ricevere sul /dev/pts/12, e viceversa.

1

ho potuto emulare una porta seriale arbitraria ./foo utilizzando questo codice:

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 deve essere installato (sudo apt-get install socat), così come il pacchetto pyserial pitone (pip install pyserial).

Aprire l'interprete Python e l'importazione SerialEmulator:

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

tuo programma client può poi avvolgere ./ttyclient con pySerial, creando la porta seriale virtuale. È inoltre possibile creare client_port /dev/ttyUSB0 o simile se non è possibile modificare il codice cliente, ma potrebbe essere necessario sudo.

anche essere consapevoli di questo problema: Pyserial does not play well with virtual port

Problemi correlati