2010-02-18 26 views
29

Sé que puedo usar, p. pySerial para hablar con dispositivos seriales, pero ¿qué ocurre si no tengo un dispositivo en este momento pero aún necesito escribir un cliente para él? ¿Cómo puedo escribir un "dispositivo serial virtual" en Python y hacer que pySerial hable con él, como diría, por ejemplo, ejecutar un servidor web local? Quizás no estoy buscando bien, pero no he podido encontrar ninguna información sobre este tema.Dispositivo serie virtual en Python?

Respuesta

4

Puede ser más fácil usar algo como com0com (si está en Windows) para configurar un puerto serie virtual y desarrollarlo.

4

Depende un poco de lo que estamos tratando de lograr ahora ...

Usted puede envolver el acceso al puerto serie en una clase y escribir una implementación de usar toma de E/S o un archivo de E/S . Luego, escriba su clase de E/S en serie para usar la misma interfaz y conéctela cuando el dispositivo esté disponible. (Este es realmente un buen diseño para probar la funcionalidad sin requerir hardware externo.)

O, si va a utilizar el puerto serie para una interfaz de línea de comando, puede usar stdin/stdout.

O, esta es la otra respuesta acerca de virtual serial devices for linux.

+0

Sí, escribir una clase "dispositivo de serie virtual" que duplica la interfaz PySerial. Entonces su código puede usar su clase de "dispositivo virtual" o la interfaz real de pySerial, de manera intercambiable. –

+0

Esta es una buena implementación ya que es bastante fácil de implementar y funcionará en todas las plataformas. – Pithikos

+0

Perdón por actualizar esta publicación anterior, pero ¿podría elaborar un poco más? Esto sería muy útil para mí. Gracias – rowman

27

esto es algo que hice y funcionó para mí hasta ahora:

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 crea más puertos virtuales que no tendrá ningún problema ya que los diferentes maestros reciben diferentes descriptores de archivo, incluso si tienen el mismo nombre

+0

Esta es exactamente la respuesta que estaba buscando. Esto funciona para mí en Mac OS X. – DrRobotNinja

+1

Esto no funcionará en Windows, que carece del módulo de termios requerido por pty. – OYRM

+1

Parece que puedo leer perfectamente el dispositivo falso (es decir, tengo otro programa que escribe en el dispositivo en el punto final 's_name'), pero cada vez que publico' ser.write ("...") ', ese texto solo recuperé el eco la próxima vez que 'os.read (maestro, 1000)', independientemente de si hay algo conectado al puerto, y el otro extremo del puerto no parece obtener los datos. – Ponkadoodle

2

Si está ejecutando Linux Puede utilizar el comando socat para esto, así:

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

Cuando se ejecuta el comando, se le informará de los puertos en serie que ha creado. En mi máquina será similar a:

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] 

Ahora me pueden escribir a /dev/pts/13 y recibir en /dev/pts/12, y viceversa.

1

que era capaz de emular un puerto serie arbitraria ./foo utilizando este código:

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 necesidades para ser instalado (sudo apt-get install socat), así como el paquete pyserial pitón (pip install pyserial)

Abrir el intérprete de Python e importación SerialEmulator:

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

Su programa cliente puede envolver ./ttyclient con PySerial, creando el puerto serie virtual. También puede hacer client_port /dev/ttyUSB0 o similar si no puede modificar el código del cliente, pero podría necesitar sudo.

También ser conscientes de este problema: Pyserial does not play well with virtual port

Cuestiones relacionadas