Wiem, że mogę użyć np. pySerial, aby porozmawiać z urządzeniami szeregowymi, ale co, jeśli nie mam teraz urządzenia, ale muszę jeszcze napisać do niego klienta? Jak mogę napisać "wirtualne urządzenie szeregowe" w Pythonie i mieć z nim rozmowę na temat pySerial, tak jakbym, powiedzmy, uruchomił lokalny serwer sieciowy? Może po prostu nie szukam dobrze, ale nie udało mi się znaleźć żadnych informacji na ten temat.Virtual Serial Device w języku Python?
Odpowiedz
Może być łatwiej używać czegoś takiego jak com0com (jeśli jesteś w systemie Windows), aby skonfigurować wirtualny port szeregowy i rozwijać się na tym.
To zależy trochę od tego, co starasz się osiągnąć teraz ...
Można owinąć dostęp do portu szeregowego w klasie i napisać implementację użyć gniazda we/wy lub plik I/O . Następnie wpisz swoją klasę I/O, aby użyć tego samego interfejsu i podłączyć go, gdy urządzenie jest dostępne. (Jest to właściwie dobry projekt do testowania funkcjonalności bez wymaganego zewnętrznego sprzętu.)
Lub, jeśli zamierzasz używać portu szeregowego dla interfejsu linii poleceń, możesz użyć stdin/stdout. To jest inna odpowiedź na temat virtual serial devices for linux.
Może urządzenie z pętlą wykona zadanie, jeśli chcesz przetestować aplikację bez dostępu do urządzenia. Jest to zawarte w pyserial 2,5 https://pythonhosted.org/pyserial/url_handlers.html#loop
to jest coś zrobiłem i pracował dla mnie do tej pory:
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)
Jeśli tworzysz porty więcej wirtualnych będziesz miał żadnych problemów w różnych mistrzów uzyskać różne deskryptory nawet jeśli mają takie samo imię.
To jest dokładnie odpowiedź, której szukałem. Działa to dla mnie na Mac OS X. – DrRobotNinja
To nie zadziała w systemie Windows, w którym brakuje modułu termios wymaganego przez pty. – OYRM
Wydaje mi się, że jestem w stanie odczytać z fałszywego urządzenia po prostu dobrze (tj. Mam inny program zapisujący na urządzeniu w punkcie końcowym 's_name'), ale za każdym razem, gdy wysyłam' ser.write ("...") ', ten tekst po prostu powtórz echo następnym razem, gdy 'os.read (master, 1000)', niezależnie od tego, czy coś jest podłączone do portu, a drugi koniec portu nie wydaje się uzyskać danych. – Ponkadoodle
Jeśli używasz systemu Linux można użyć komendy socat za to tak:
socat -d -d pty,raw,echo=0 pty,raw,echo=0
Kiedy biegnie dowodzenia, poinformuje cię o których porty szeregowe to stworzył. Na moim komputerze to wygląda:
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]
Teraz mogę napisać do /dev/pts/13
i odbierać na /dev/pts/12
i vice versa.
byłem w stanie naśladować dowolny port szeregowy ./foo
przy użyciu tego kodu:
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
musi być zainstalowany (sudo apt-get install socat
), a także pakiet pyserial
Pythona (pip install pyserial
).
Otwórz interpreter Pythona i import SerialEmulator:
>>> from SerialEmulator import SerialEmulator
>>> emulator = SerialEmulator('./ttydevice','./ttyclient')
>>> emulator.write('foo')
>>> emulator.read()
Program klient może następnie owinąć ./ttyclient
z pyserial, tworząc wirtualny port szeregowy. Można również zrobić client_port /dev/ttyUSB0
lub coś podobnego, jeśli nie można zmodyfikować kodu klienta, ale może być potrzebny sudo
.
Należy także pamiętać o tym problemie: Pyserial does not play well with virtual port
Tak, napisać klasę „wirtualne urządzenie szeregowe”, który powiela interfejs pyserial. Wtedy twój kod może używać zamiennie albo "klasę urządzenia wirtualnego", albo rzeczywistego interfejsu pySerial. –
Jest to dobra implementacja, ponieważ jest raczej łatwa do wdrożenia i będzie działać na wszystkich platformach! – Pithikos
Przepraszam za aktualizację tego starego posta, ale czy mógłbyś nieco bardziej rozwinąć? Byłoby to dla mnie bardzo pomocne. Dzięki – rowman