`pyserial-asyncio` 是一个用于在 Python 的 `asyncio` 环境中进行异步串口通信的库

发布时间:2026/7/14 5:06:20
`pyserial-asyncio` 是一个用于在 Python 的 `asyncio` 环境中进行异步串口通信的库
pyserial-asyncio是一个用于在 Python 的asyncio环境中进行异步串口通信的库它封装了pyserial使其支持异步 I/O 操作如await serial.read()、await serial.write()避免阻塞事件循环。它通过SerialTransport和SerialProtocol与asyncio的事件循环集成通常配合asyncio.StreamReader/StreamWriter使用需借助serial_asyncio—— 注意官方库名为serial_asyncio而非pyserial-asyncio后者常为误称或旧名当前标准用法来自pyserial生态中的serial_asyncio模块。✅ 正确安装方式pipinstallpyserial# serial_asyncio 是 pyserial 的子模块无需单独安装✅ 基本异步读写示例importasyncioimportserial_asyncioclassSerialProtocol(asyncio.Protocol):def__init__(self):self.transportNonedefconnection_made(self,transport):self.transporttransportprint(串口已连接)defdata_received(self,data):print(f收到:{data.decode(errorsignore).strip()})defconnection_lost(self,exc):print(串口断开)asyncdefmain():# 创建串口连接Linux: /dev/ttyUSB0Windows: COM3transport,protocolawaitserial_asyncio.create_serial_connection(loopasyncio.get_running_loop(),protocol_factorySerialProtocol,url/dev/ttyUSB0,baudrate9600,bytesizeserial_asyncio.serial.EIGHTBITS,parityserial_asyncio.serial.PARITY_NONE,stopbitsserial_asyncio.serial.STOPBITS_ONE)try:awaitasyncio.sleep(60)# 保持运行60秒finally:transport.close()if__name____main__:asyncio.run(main())⚠️ 注意事项serial_asyncio依赖底层串口驱动支持非阻塞 I/OLinux/macOS 通常良好Windows 需较新 pyserial ≥ 3.5 asyncio 兼容层不支持await reader.read(n)直接使用需自定义StreamReader封装或使用protocol模式若需更高层 API如类似asyncio.open_connection的流式接口可结合asyncio.StreamReader/StreamWriter自行封装或使用社区库如aio-serial第三方。在 Windows 上正确配置pyserial-asyncio实际为serial_asyncio属于pyserial的 asyncio 支持模块实现稳定异步串口通信需特别注意 Windows 的串口驱动模型、事件循环兼容性、缓冲区管理及异常恢复机制。以下是经过验证的完整配置指南✅1. 环境与依赖关键版本要求# 推荐组合经测试稳定pipinstall--upgradepython3.9# asyncio 在 3.9 更成熟pipinstallpyserial3.5# 3.5 不支持 Windows 异步串口pipinstallasyncio# Python 3.7 已内置无需额外安装⚠️ 注意pyserial3.5在 Windows 上对CreateFile的FILE_FLAG_OVERLAPPED支持不完善会导致OSError: [WinError 87] 参数错误或阻塞。✅2. 使用ProactorEventLoopWindows 必选Windows 默认SelectorEventLoop不支持串口异步 I/O仅支持 socket必须显式启用ProactorEventLoop基于 IOCPimportasyncioimportserial_asyncio# ⚠️ Windows 下必须设置 ProactorEventLoopPython 3.8 默认但显式更安全ifhasattr(asyncio,WindowsProactorEventLoopPolicy):asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy())# 后续 asyncio.run() 或 loop.run_until_complete() 即使用 Proactor✅3. 串口参数建议提升稳定性awaitserial_asyncio.create_serial_connection(loopasyncio.get_running_loop(),protocol_factorylambda:MyProtocol(),urlCOM3,# 务必确认设备管理器中 COM 号真实存在baudrate115200,bytesizeserial_asyncio.serial.EIGHTBITS,parityserial_asyncio.serial.PARITY_NONE,stopbitsserial_asyncio.serial.STOPBITS_ONE,timeout0.1,# read timeout非阻塞读超时write_timeout0.1,# write timeoutxonxoffFalse,rtsctsFalse,dsrdtrFalse,# 关键禁用系统缓冲避免数据粘包/丢失inter_byte_timeout0.01,# 字节间超时用于分帧) 提示inter_byte_timeout对处理不定长帧如 Modbus RTU至关重要。✅4. 健壮的协议类含异常捕获与重连importloggingimportasyncio logging.basicConfig(levellogging.INFO)loggerlogging.getLogger(__name__)classRobustSerialProtocol(asyncio.Protocol):def__init__(self):self.transportNoneself._is_closingFalsedefconnection_made(self,transport):self.transporttransport logger.info(✅ 串口连接成功)defdata_received(self,data):ifdata:logger.debug(f 收到{len(data)}字节:{data.hex()})defconnection_lost(self,exc):self.transportNoneifnotself._is_closing:logger.warning(f⚠️ 串口断开:{exc})# 触发自动重连可选asyncio.create_task(self.reconnect())asyncdefreconnect(self):awaitasyncio.sleep(2.0)# 避免密集重试try:loopasyncio.get_running_loop()transport,_awaitserial_asyncio.create_serial_connection(looploop,protocol_factoryRobustSerialProtocol,urlCOM3,baudrate115200,# ... 其他参数同上)logger.info( 重连成功)exceptExceptionase:logger.error(f❌ 重连失败:{e})defclose(self):self._is_closingTrueifself.transportandnotself.transport.is_closing():self.transport.close()✅5. 验证与调试技巧✅ 使用mode COM3CMD或Get-ComPortPowerShell确认端口状态✅ 用PuTTY或Tera Term先手动测试波特率/流控是否匹配✅ 捕获OSError和serial.SerialException并记录errno如errno5表示拒绝访问常因端口被占用✅ 禁用 Windows “USB Serial Port” 的“节能模式”设备管理器 → 属性 → 电源管理 → 取消勾选“允许计算机关闭此设备以节约电源”。✅6. 替代方案若仍不稳定使用aio-serial第三方库封装更友好pipinstallaio-serialfromaio_serialimportSerialasyncwithSerial(COM3,115200)asser:awaitser.write(bAT\r\n)respawaitser.read_until(b\r\n,timeout1.0)综上Windows 下稳定运行的核心是ProactorEventLoop pyserial≥3.5 合理超时 显式异常处理 硬件级电源/驱动检查。