为什么pyserial在串口对端未发送数据时会读取到空字节b''
pyserial 读取串口持续返回空字节串 b'' 原因说明
核心原因
read(0)固定返回空字节
你调用serialport.read(serialport.inWaiting())时,当串口缓冲区没有数据,inWaiting()会返回0,而pyserial的read(n)方法当入参n为0时,无论串口配置如何都会直接返回b'',这是官方定义的正常行为。- 死循环逻辑缺少终止条件
你注释掉了空数据的退出判断if data == "" or "&end" in data:,仅保留了&end匹配的逻辑,空字节串转字符串后是"",永远不会匹配到&end,所以程序会一直循环执行读取、打印空数据的逻辑。 - 串口非阻塞配置
如果串口初始化时设置了timeout=0(非阻塞模式),就算没有调用read(0),正常的读操作也会在缓冲区无数据时立刻返回b'',不会阻塞等待数据到来,进一步加快了空数据的打印频率。
修复方案
- 增加缓冲区非空判断,无数据时不执行读取逻辑,避免拿到空字节:
def read_com(serialport): while True: # 仅当缓冲区有数据时再读取,新版pyserial推荐用in_waiting属性替代inWaiting()方法 if serialport.in_waiting > 0: data = serialport.read(serialport.in_waiting) print(data) # 增加errors参数避免非UTF8数据导致解码报错 data_str = str(data, encoding="utf-8", errors="ignore") if "&end" in data_str: return data_str
- 串口初始化时设置合理的超时时间,避免无意义的频繁轮询,比如:
import serial # timeout单位为秒,设置为1代表无数据时最多等待1秒再返回 ser = serial.Serial(port="你的串口号", baudrate=9600, timeout=1)
- 如果你的需求是读到
&end就结束,可以直接用pyserial内置的read_until方法简化逻辑:
def read_com(serialport): data = serialport.read_until(expected=b"&end") print(data) return str(data, encoding="utf-8", errors="ignore")
内容的提问来源于stack exchange,提问作者guoyanzhang
相关产品推荐
相关产品推荐

