Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Virtual Serial Device in Python?

I know that I can use e.g. pySerial to talk to serial devices, but what if I don't have a device right now but still need to write a client for it? How can I write a "virtual serial device" in Python and have pySerial talk to it, like I would, say, run a local web server? Maybe I'm just not searching well, but I've been unable to find any information on this topic.

like image 265
tdavis Avatar asked Feb 18 '10 19:02

tdavis


People also ask

What is virtual serial via USB?

A USB Virtual COM Port allows you to use a USB Interface to talk to serial devices. This essentially gives users a simple pathway to communicating to peripherals using software development tools that support serial communications, a relatively common standard is most programming languages.

What is virtual serial port emulator?

Virtual Serial Port Emulator allows you to create an unlimited number of virtual COM ports. The software emulates serial port functionality connected by virtual null modem cable in such a way that the system does not see the difference between virtual and real hardware ports.

Is serial the same as PySerial?

pySerial includes a small console based terminal program called serial.


2 Answers

this is something I did and worked out for me so far:

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) 

If you create more virtual ports you will have no problems as the different masters get different file descriptors even if they have the same name.

like image 122
Aquiles Avatar answered Sep 20 '22 21:09

Aquiles


I was able to emulate an arbitrary serial port ./foo using this 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 needs to be installed (sudo apt-get install socat), as well as the pyserial python package (pip install pyserial).

Open the python interpreter and import SerialEmulator:

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

Your client program can then wrap ./ttyclient with pyserial, creating the virtual serial port. You could also make client_port /dev/ttyUSB0 or similar if you can't modify client code, but might need sudo.

Also be aware of this issue: Pyserial does not play well with virtual port

like image 29
Patrick Steadman Avatar answered Sep 19 '22 21:09

Patrick Steadman