You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为什么pyserial在串口对端未发送数据时会读取到空字节b''

pyserial 读取串口持续返回空字节串 b'' 原因说明

核心原因

  1. read(0) 固定返回空字节
    你调用 serialport.read(serialport.inWaiting()) 时,当串口缓冲区没有数据,inWaiting() 会返回0,而pyserial的read(n)方法当入参n为0时,无论串口配置如何都会直接返回b'',这是官方定义的正常行为。
  2. 死循环逻辑缺少终止条件
    你注释掉了空数据的退出判断if data == "" or "&end" in data:,仅保留了&end匹配的逻辑,空字节串转字符串后是"",永远不会匹配到&end,所以程序会一直循环执行读取、打印空数据的逻辑。
  3. 串口非阻塞配置
    如果串口初始化时设置了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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.14 08:24:04