Я знаю, что могу использовать, например. pySerial, чтобы разговаривать с последовательными устройствами, но что, если у меня нет устройства прямо сейчас, но все равно нужно написать для него клиент? Как я могу написать "виртуальное последовательное устройство" в Python и поговорить с pySerial, например, я бы, скажем, запустил локальный веб-сервер? Может быть, я просто не хорошо разбираюсь, но я не смог найти какую-либо информацию по этой теме.
Виртуальное последовательное устройство в Python?
Ответ 1
это то, что я сделал и разработал у меня до сих пор:
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)
Если вы создадите больше виртуальных портов, у вас не будет проблем, поскольку разные мастера получат разные файловые дескрипторы, даже если они имеют одинаковое имя.
Ответ 2
Может быть проще использовать что-то вроде com0com (если вы находитесь в Windows) для настройки виртуального последовательного порта, и развиваться на этом.
Ответ 3
Это немного зависит от того, что вы пытаетесь выполнить сейчас...
Вы можете обернуть доступ к последовательному порту в классе и написать реализацию для использования ввода/вывода сокета или ввода/вывода файлов. Затем запишите свой последовательный интерфейс ввода/вывода для использования того же интерфейса и подключите его, когда устройство доступно. (На самом деле это хороший дизайн для тестирования функциональности без необходимости использования внешнего оборудования.)
Или, если вы собираетесь использовать последовательный порт для интерфейса командной строки, вы можете использовать stdin/stdout.
Или это другой ответ о виртуальных последовательных устройствах для Linux.
Ответ 4
Возможно, устройство loop выполнит задание, если вам нужно протестировать приложение без доступа к устройству. Он включен в pySerial 2.5 https://pythonhosted.org/pyserial/url_handlers.html#loop
Ответ 5
Если вы используете Linux, вы можете использовать команду socat, например:
socat -d -d pty,raw,echo=0 pty,raw,echo=0
Когда команда запустится, она сообщит вам, какие последовательные порты она создала. На моей машине это выглядит так:
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]
Теперь я могу написать /dev/pts/13
и получить на /dev/pts/12
и наоборот.
Ответ 6
Я смог эмулировать произвольный последовательный порт ./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()
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, создав виртуальный последовательный порт. Вы также можете сделать client_port /dev/ttyUSB0
или подобное, если вы не можете изменить код клиента, но может потребоваться sudo
.
Также помните об этой проблеме: Pyserial не играет хорошо с виртуальным портом