我有以下简单的设置:
串行设备 -> PL2303 UART-to-USB -> Win10 机器 -> 使用 PySerial 3.5 的 myScript.py
串行设备通过 COM10 处的 PL2303 UART-to-USB 连接到 PC。
串行设备仅在按下物理“发送”按钮时发送数据,并且仅发送一个 20 个字符 每次按下都会终止行。
读取串口设备数据的简单代码:
import time
import os
import sys
import serial
ser = serial.Serial("COM10", 9600, timeout=0.5)
while(1):
if ser.in_waiting:
serial_data = str(ser.readline().decode('ascii')) #Read (receive) data
print("Received: " + serial_data) #Print data
time.sleep(0.01) #Slight delay just in case.
代码运行良好。但是,当拔出串行设备时(通过 USB 转串行插头拔出),Python 会崩溃,并出现以下异常:
File "D:\Program Files\Python37\lib\serial\serialwin32.py", line 259, in in_waiting
raise SerialException("ClearCommError failed ({!r})".format(ctypes.WinError()))
serial.serialutil.SerialException: ClearCommError failed (OSError(22, 'The I/O operation has been aborted because of either a thread exit or an application request.', None, 995))
现在,每当串行设备被物理拔出时出现警告/异常已经不是什么新鲜事了。 PuTTy 可以做到这一点,许多其他终端仿真器也可以做到这一点,从逻辑上讲,PySerial 也应该这样做。
但是,我清楚地记得,在开发过程中的某个时刻,拔掉串行设备并没有引起 PySerial 的任何反应。我什至可以“热插拔” - 拔下一个串行设备,插入另一个串行设备,脚本仍然可以工作并打印接收到的数据。
这种“热插拔”可能吗?还是我完全记错了?
您可以使用 try- except 块使其可热插拔。这对我有用(使用 Arduino 作为串行设备)。
import time
import serial
ser = serial.Serial("COM9", 9600, timeout=0.5)
while True:
try:
if ser.in_waiting:
serial_data = str(ser.readline().decode('ascii'))
print("Received: " + serial_data)
time.sleep(0.01)
except:
try:
ser = serial.Serial("COM9", 9600, timeout=0.5)
except:
pass
目前,当您开始运行代码时,必须插入设备。但是您可以将初始的 serial.Serial 调用放在它自己的 try- except 块中以避免这种情况。或者您可以完全忽略此行,它仍然可以正常工作。