Python中的虚拟串行设备?

tda*_*vis 41 python serial-port virtual-serial-port pyserial

我知道我可以使用例如pySerial与串口设备通信,但如果我现在没有设备但仍需要为它编写客户端怎么办?如何在Python中编写"虚拟串行设备"并与pySerial通信,就像我会说,运行本地Web服务器?也许我只是不好好搜索,但我一直无法找到有关此主题的任何信息.

小智 37

到目前为止,这是我为我做的事情:

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)
Run Code Online (Sandbox Code Playgroud)

如果您创建更多虚拟端口,则不会出现问题,因为不同的主服务器会获得不同的文件描述符,即使它们具有相同的名称.

  • 这不适用于Windows,它缺少pty所需的termios模块. (5认同)
  • pyserial的单元测试有一组很好的示例:https://github.com/pyserial/pyserial/blob/7bd427087857ba474180058b727578ca4cec5e2e/test/test_pty.py (3认同)

mtr*_*trw 6

使用像com0com这样的东西(如果你在Windows上)来设置虚拟串口并在其上进行开发可能更容易.


Ric*_*ard 6

如果您运行的是 Linux,您可以使用socat命令,如下所示:

socat -d -d pty,raw,echo=0 pty,raw,echo=0
Run Code Online (Sandbox Code Playgroud)

当命令运行时,它会通知您它创建了哪些串行端口。在我的机器上,这看起来像:

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]
Run Code Online (Sandbox Code Playgroud)

现在我可以在 上写信/dev/pts/13和接收/dev/pts/12,反之亦然。


ste*_*eko 5

如果您需要在不访问设备的情况下测试您的应用程序,那么循环设备可能会完成这项工作。它包含在 pySerial 2.5 https://pythonhosted.org/pyserial/url_handlers.html#loop


Pat*_*man 5

我可以./foo使用以下代码模拟任意串行端口:

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()
Run Code Online (Sandbox Code Playgroud)

socat需要安装(sudo apt-get install socat)和pyserialpython软件包(pip install pyserial)。

打开python解释器并导入SerialEmulator:

>>> from SerialEmulator import SerialEmulator
>>> emulator = SerialEmulator('./ttydevice','./ttyclient') 
>>> emulator.write('foo')
>>> emulator.read()
Run Code Online (Sandbox Code Playgroud)

然后,您的客户端程序可以./ttyclient使用pyserial 包装,从而创建虚拟串行端口。/dev/ttyUSB0如果您无法修改客户端代码,但也可能需要,则也可以创建client_port 或类似名称sudo

另请注意此问题:Pyserial在虚拟端口上无法正常运行