Подтвердить что ты не робот

Виртуальное последовательное устройство в Python?

Я знаю, что могу использовать, например. pySerial, чтобы разговаривать с последовательными устройствами, но что, если у меня нет устройства прямо сейчас, но все равно нужно написать для него клиент? Как я могу написать "виртуальное последовательное устройство" в Python и поговорить с pySerial, например, я бы, скажем, запустил локальный веб-сервер? Может быть, я просто не хорошо разбираюсь, но я не смог найти какую-либо информацию по этой теме.

4b9b3361

Ответ 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 не играет хорошо с виртуальным портом