2010-02-18 3 views
29

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

ответ

4

Возможно, вам будет проще использовать что-то вроде com0com (если вы работаете в Windows), чтобы настроить виртуальный последовательный порт и разработать на нем.

4

Это зависит немного от того, что вы пытаетесь сделать сейчас ...

Вы можете обернуть доступ к последовательному порту в классе и написать реализацию в использовании сокетов ввода/вывода или файл ввода/вывода , Затем запишите свой последовательный интерфейс ввода/вывода для использования того же интерфейса и подключите его, когда устройство доступно. (Это действительно хороший дизайн для тестирования функциональности без необходимости внешнего оборудования.)

Или, если вы собираетесь использовать последовательный порт для интерфейса командной строки, вы можете использовать stdin/stdout.

Или это еще один ответ о virtual serial devices for linux.

+0

Да, написать класс «виртуального последовательного устройства», который дублирует интерфейс pySerial. Тогда ваш код может использовать либо ваш класс «виртуального устройства», либо реальный интерфейс pySerial, взаимозаменяемо. –

+0

Это хорошая реализация, так как ее довольно легко реализовать, и она будет работать на всех платформах! – Pithikos

+0

Прошу прощения, чтобы обновить это старое сообщение, но не могли бы вы рассказать немного больше? Это было бы очень полезно для меня. Спасибо – rowman

27

это то, что я сделал, и работал для меня до сих пор:

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) 

При создании нескольких виртуальных портов, у вас не будет никаких проблем, так как разные мастера получить разные дескрипторы файлов даже если они имеют одно и то же имя.

+0

Это именно тот ответ, который я искал. Это работает для меня в Mac OS X. – DrRobotNinja

+1

Это не будет работать в Windows, в которой отсутствует модуль termios, требуемый pty. – OYRM

+1

Я, кажется, умею читать с фальшивого устройства просто отлично (т.е. у меня есть другая программа, записывающая устройство в конечную точку 's_name'), но всякий раз, когда я выдаю' ser.write ("...") ', этот текст просто возвращайтесь обратно в следующий раз, когда я 'os.read (master, 1000)', независимо от того, что-либо подключено к порту, а другой конец порта, похоже, не получает данные. – Ponkadoodle

2

Если вы работаете в 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, и наоборот.

1

я был в состоянии эмулировать произвольный последовательный порт ./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 питона (pip install pyserial).

Открыть питон переводчик и импорт SerialEmulator:

>>> from SerialEmulator import SerialEmulator 
>>> emulator = SerialEmulator('./ttydevice','./ttyclient') 
>>> emulator.write('foo') 
>>> emulator.read() 

Ваша программа-клиент может затем обернуть ./ttyclient с pyserial, создавая виртуальный последовательный порт. Вы также можете сделать client_port /dev/ttyUSB0 или аналогичным, если вы не можете изменить код клиента, но может потребоваться sudo.

быть также известно об этой проблеме: Pyserial does not play well with virtual port

Смежные вопросы