我知道我可以使用例如 pySerial 与串行设备通信,但是如果我现在没有设备但仍需要为其编写客户端怎么办?如何在 Python 中编写“虚拟串行设备”并让 pySerial 与之对话,就像我会运行本地 Web 服务器一样?也许我只是没有很好地搜索,但我一直无法找到有关此主题的任何信息。
6 回答
到目前为止,这是我为我所做并为我解决的事情:
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)
如果您创建更多虚拟端口,您将不会有任何问题,因为不同的 master 会获得不同的文件描述符,即使它们具有相同的名称。
./foo
我能够使用以下代码模拟任意串行端口:
串行模拟器.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
需要安装 ( sudo apt-get install socat
),以及pyserial
python 包 ( pip install pyserial
)。
打开python解释器并导入SerialEmulator:
>>> from SerialEmulator import SerialEmulator
>>> emulator = SerialEmulator('./ttydevice','./ttyclient')
>>> emulator.write('foo')
>>> emulator.read()
然后,您的客户端程序可以./ttyclient
使用 pyserial 进行包装,从而创建虚拟串行端口。/dev/ttyUSB0
如果您无法修改客户端代码,您也可以制作 client_port或类似内容,但可能需要sudo
.
If you are running Linux you can use the socat command for this, like so:
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.
使用com0com 之类的东西(如果您在 Windows 上)设置虚拟串行端口并在此基础上进行开发可能会更容易。
如果您需要在不访问设备的情况下测试应用程序,那么循环设备可能会完成这项工作。它包含在 pySerial 2.5 https://pythonhosted.org/pyserial/url_handlers.html#loop
这有点取决于您现在要完成的工作...
您可以将对串行端口的访问封装在一个类中并编写一个实现以使用套接字 I/O 或文件 I/O。然后编写您的串行 I/O 类以使用相同的接口,并在设备可用时将其插入。(这实际上是一种无需外部硬件即可测试功能的好设计。)
或者,如果您要将串行端口用于命令行界面,则可以使用 stdin/stdout。
或者,还有关于linux 的虚拟串行设备的其他答案。