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

PySerial readline停止运行或重复输出最后值的问题求助

解决串口传感器数据读取停止/重复输出问题

问题分析

你的代码出现停止运行或重复输出的核心原因有两个:

  1. 依赖readline()按\r\n分割数据,一旦传感器输出的换行符不规范(如缺失换行、出现空行),readline()会因等待超时返回空数据,导致后续循环无法正确触发。
  2. time.sleep(2)会长时间阻塞循环,造成串口缓冲区数据堆积,甚至溢出,进而引发数据读取异常。

从你提供的日志来看,空的\r\n数据包会导致原代码读取到空内容,而缺失换行的不完整数据包会让readline()一直等待超时,最终表现为程序“停止”。

改进后的代码

import serial
import time

# 初始化串口,调整超时时间避免过早返回空数据
com = serial.Serial(
    port='COM5',
    baudrate=115200,
    bytesize=8,
    parity=serial.PARITY_NONE,
    stopbits=serial.STOPBITS_ONE,
    rtscts=True,
    timeout=1
)

# 用于拼接不完整数据包的缓冲区
data_buffer = b''

try:
    while True:
        # 读取所有可用的串口数据(无数据时至少读取1字节触发超时)
        received = com.read(com.in_waiting or 1)
        if received:
            data_buffer += received
            # 按\r\n拆分完整数据包,处理缓冲区中所有已完成的数据
            while b'\r\n' in data_buffer:
                line, data_buffer = data_buffer.split(b'\r\n', 1)
                if line:  # 跳过空行,避免无效输出
                    print(line.decode().strip())
        # 短延迟降低CPU占用,可根据传感器输出频率调整
        time.sleep(0.01)
except KeyboardInterrupt:
    print("程序已终止")
except Exception as e:
    print(f"运行错误: {str(e)}")
finally:
    # 确保串口资源被释放
    com.close()

关键修改说明

  • 缓冲区拼接数据:不再依赖单次readline()读取完整行,而是先把所有接收的数据存入缓冲区,再按\r\n拆分,彻底解决换行符缺失或不规范的问题。
  • 移除长延迟:把time.sleep(2)替换为0.01秒短延迟,既减少CPU占用,又保证串口数据能被及时处理,避免缓冲区堆积。
  • 异常捕获与资源释放:处理键盘中断和通用异常,保证程序能优雅退出,同时确保串口被正确关闭,避免资源泄漏。
  • 过滤空行:跳过拆分出的空内容,避免输出无效数据,也防止空行导致的重复输出问题。

内容的提问来源于stack exchange,提问作者Jorge24

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 23:50:43