[英]How to read data from a serial port in Windows using python?
在 windows 10 我正在嘗試讀取連接的串行設備的 output。
使用hterm
我能夠看到串行端口COM5
上的數據。 所以串口工作正常。
現在使用 WSL2 (Ubuntu 20.04.3) 我正在運行以下 python 腳本
import serial
ser = serial.Serial("COM5", baudrate=115200)
失敗並出現錯誤
Traceback (most recent call last):
File "test1.py", line 6, in <module>
ser = serial.Serial("COM5", baudrate=115200)
File "/usr/lib/python3/dist-packages/serial/serialutil.py", line 240, in __init__
self.open()
File "/usr/lib/python3/dist-packages/serial/serialposix.py", line 268, in open
raise SerialException(msg.errno, "could not open port {}: {}".format(self._port, msg))
serial.serialutil.SerialException: [Errno 2] could not open port COM5: [Errno 2] No such file or directory: 'COM5'
我還嘗試使用本文中發布的建議,將串行設備連接到的 USB 端口附加到 WSL。
命令usbipd wsl list
in a windows powershell 顯示
8-3 0403:6001 USB Serial Converter Attached - Ubuntu-20.04
但是當在 WSL2 中運行相同的 python 代碼時,會出現相同的錯誤。
那么如何解決這個問題,以便我能夠使用 python 從串行端口讀取所有數據?
我通常使用一種解決方案,我只從 USB VID:PID 數據中識別端口名稱。 這允許我不對任何 com 端口名稱進行硬編碼。
您必須開始搜索與您的 USB 設備對應的端口名稱(請參閱下面的find_device()
)。
您還應該在讀取時在串行端口上使用鎖,這樣您就不會獲得多個並發訪問,尤其是在 Windows 上會產生權限錯誤。 請參閱_with_lock()
上下文管理器以鎖定串行讀取。
另外,以管理員身份運行代碼,以獲得串行讀取權限(不是必需的,但是嘿,先調試)。
以下示例同時兼容 linux 和 windows
import serial.tools.list_ports
import serial
from contextlib import contextmanager
from threading import Lock
# Your USB DEVICE
USB_VID = "0x0403"
USB_PID = "0x6001"
SERIAL_SETTINGS = {
"baudrate": 115200,
"bytesize": 8,
"parity": "N",
"stopbits": 1,
}
@contextmanager
def _with_Lock():
# This is a singleton, pylint: disable=global-statement
global LOCK
if LOCK is None:
LOCK = Lock()
LOCK.acquire()
yield
if LOCK is not None:
LOCK.release()
def find_devices():
# type: () -> List[str]
"""
Find all COM ports corresponding to your USB device
"""
_device_ports = []
for port in serial.tools.list_ports.comports():
if port.vid == int(USB_VID, 16) and port.pid == int(USB_PID, 16):
_device_ports.append(port.device)
return _device_ports
def read_device(device: str) -> str:
try:
with _with_lock():
with serial.Serial(device_port, timeout=1, **SERIAL_SETTINGS) as ser:
result = ser.read(size=64).decode('utf-8')
if len(result) == 0:
return None
else:
return result.strip("\r\n")
return result
except serial.SerialException as exc:
error_message = "Cannot read serial port {}: {}".format(device_port, exc)
print(error_message) # or log it
raise OSerror(error_message)
for port in find_devices():
data = read_device(port)
print(data)
希望這可以幫助。 更多串口讀取的例子可以參考我寫的一個讀取USB溫度傳感器的庫,看這個
您可以嘗試使用以下腳本。
import serial
ser = serial.Serial("COM5", baudrate=115200, timeout=1)`
while True:
data = ser.readline()
print(data)
我個人首先會讓它在 Ubuntu 20.04.3 中運行。
只需下載一個 Ubuntu 的虛擬機,安裝它(在 VM 環境中(或真機,如果有備用的話))並進行測試。
WSLx 確實不錯,但它仍然存在一些初期問題。
如果您知道它通過真實(或虛擬機)Ubuntu 安裝,那么您就完成了大部分工作。
我總是這樣做,因為我發現 WSLx 可能有一些奇怪的怪癖。 它不應該引起注意,但確實如此,尤其是當涉及到外部硬件時。
由於您使用的是 Ubuntu,因此您不能使用 Windows 使用的端口名稱。在 Ubuntu 中,端口名稱的格式通常為dev/ttyUSB
后跟端口號 ( dev/ttyUSB0
)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.