一、背景
在物联网和工业控制领域,串口通信仍是设备交互的基石。但Python原生的pyserial库在实际项目中往往捉襟见肘——线程安全、实时读写、超时控制等问题频发。本文将带你从基础Serial调用开始,逐步构建一个支持多线程、实时数据处理的工业级串口工具类
二、PySerial基础实现
先介绍最简单最常用的串口读写实现
2.1 环境准备
pip install pyserial # 基础库
pip install serial-tools # 可选工具集
2.2 简单例子
import serial
# 初始化连接
serial_ = serial.Serial(
port='COM7',
baudrate=115200,
timeout=2 # 读超时(秒)
)
cmd = "ls\n".encode("utf-8") # 每条命令必带换行符,表示一条命令的结束
# 读取100字节
serial_.write(cmd)
response = serial_.read(100)
print(response.decode("utf-8", "ignore"))
# 读取一行
serial_.write(cmd)
response = serial_.readline()
print(response.decode("utf-8", "ignore"))
# 读取多行
serial_.write(cmd)
serial_.readlines()
print(response.decode("utf-8", "ignore"))
# 读取所有
serial_.write(cmd)
response = serial_.readall()
print(response.decode("utf-8", "ignore"))
# 必须显式关闭!
serial_.close()
2.3 痛点分析
- 阻塞式读取,不能准确判断数据结束位置。
- 数据读写与业务逻辑高度耦合。
- 可靠性,易用性差,有数据丢失的可能。
三、高级封装
3.1 待解决问题清单
| 问题类型 | 引发场景 | 后果 |
|---|---|---|
| 线程阻塞 | 长时间read() | 程序无响应 |
| 数据粘包 | 高速传输 | 协议解析失败 |
| 设备异常掉线 | USB接触不良 | 进程崩溃 |
| 编码混乱 | 中英文混合数据 | 解码错误 |
3.2 具体实现
3.3 核心介绍
- 多线程读写隔离,通过Event同步
- 数据缓冲设计,一直读,直到线程结束
- 支持check操作,检查输出中是否出现某些关键字
3.4 使用示例
from base_serial import BaseSerial
serial_ = BaseSerial("COM10")
# 读取到的数据输出到终端
serial_.reader_output(True)
# 输入指定命令,并获取返回
print(serial_.write("ls", called=True, timeout=2).decode("utf-8"))
# 检查日志中是否有指定关键字
# print("检查是否有config1 : {}".format(serial_.check_log(5, *["config1"])))
print("检查是否有linkerconfig:{}".format(serial_.check_log(5, *["linkerconfig"])))
# 输入键值
serial_.key_event("KEYCODE_DPAD_UP")
serial_.key_event(19)
关键字《linkerconfig》存在的例子
acct data_mirror mnt second_stage_resources
apex debug_ramdisk odm storage
bin dev odm_dlkm sys
bugreports etc oem system
cache init postinstall system_dlkm
config init.environ.rc proc system_ext
d linkerconfig product vendor
data metadata sdcard vendor_dlkm
acct data_mirror mnt second_stage_resources
apex debug_ramdisk odm storage
bin dev odm_dlkm sys
bugreports etc oem system
cache init postinstall system_dlkm
config init.environ.rc proc system_ext
d linkerconfig product vendor
data metadata sdcard vendor_dlkm
console:/ $
检查是否有linkerconfig:True
console:/ $
Process finished with exit code 0
关键字《config1》不存在的例子
acct data_mirror mnt second_stage_resources
apex debug_ramdisk odm storage
bin dev odm_dlkm sys
bugreports etc oem system
cache init postinstall system_dlkm
config init.environ.rc proc system_ext
d linkerconfig product vendor
data metadata sdcard vendor_dlkm
acct data_mirror mnt second_stage_resources
apex debug_ramdisk odm storage
bin dev odm_dlkm sys
bugreports etc oem system
cache init postinstall system_dlkm
config init.environ.rc proc system_ext
d linkerconfig product vendor
data metadata sdcard vendor_dlkm
console:/ $
检查是否有config1 : False
console:/ $
Process finished with exit code 0
完整代码链接:github.com/WJQ6666/Ser…