简体   繁体   English

Python中的虚拟串行设备?

[英]Virtual Serial Device in Python?

I know that I can use eg 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? 我知道我可以使用例如pySerial与串口设备通信,但如果我现在没有设备但仍需要为它编写客户端怎么办? 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? 如何在Python中编写“虚拟串行设备”并与pySerial通信,就像我会说,运行本地Web服务器? Maybe I'm just not searching well, but I've been unable to find any information on this topic. 也许我只是不好好搜索,但我一直无法找到有关此主题的任何信息。

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. 如果您创建更多虚拟端口,则不会遇到任何问题,因为不同的主服务器会获得不同的文件描述符,即使它们具有相同的名称。

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

It depends a bit on what you're trying to accomplish now... 这取决于你现在想要完成的事情......

You could wrap access to the serial port in a class and write an implementation to use socket I/O or file I/O. 您可以封装对类中串行端口的访问,并编写实现以使用套接字I / O或文件I / O. Then write your serial I/O class to use the same interface and plug it in when the device is available. 然后编写串行I / O类以使用相同的接口,并在设备可用时将其插入。 (This is actually a good design for testing functionality without requiring external hardware.) (这实际上是一种很好的测试功能设计,无需外部硬件。)

Or, if you are going to use the serial port for a command line interface, you could use stdin/stdout. 或者,如果要将串行端口用于命令行界面,则可以使用stdin / stdout。

Or, there's this other answer about virtual serial devices for linux . 或者,还有关于Linux的虚拟串行设备的另一个答案。

I was able to emulate an arbitrary serial port ./foo using this code: 我能够使用以下代码模拟任意串行端口./foo

SerialEmulator.py 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 ). socat需要安装( sudo apt-get install socat ),还有pyserial Python包( pip install pyserial )。

Open the python interpreter and import SerialEmulator: 打开python解释器并导入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. 然后,您的客户端程序可以使用pyserial包装./ttyclient ,从而创建虚拟串行端口。 You could also make client_port /dev/ttyUSB0 or similar if you can't modify client code, but might need sudo . 如果你不能修改客户端代码,你也可以创建client_port /dev/ttyUSB0或类似的东西,但可能需要sudo

Also be aware of this issue: Pyserial does not play well with virtual port 还要注意这个问题: Pyserial与虚拟端口不兼容

If you are running Linux you can use the socat command for this, like so: 如果您正在运行Linux,可以使用socat命令,如下所示:

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

When the command runs, it will inform you of which serial ports it has created. 当命令运行时,它将通知您它创建了哪些串行端口。 On my machine this looks like: 在我的机器上,这看起来像:

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]

Now I can write to /dev/pts/13 and receive on /dev/pts/12 , and vice versa. 现在我可以写入/dev/pts/13并在/dev/pts/12上接收,反之亦然。

Maybe a loop device will do the job if you need to test your application without access to a device. 如果您需要在不访问设备的情况下测试应用程序,那么循环设备可能会完成这项工作。 It's included in pySerial 2.5 https://pythonhosted.org/pyserial/url_handlers.html#loop 它包含在pySerial 2.5 https://pythonhosted.org/pyserial/url_handlers.html#loop中

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM