PySerial readline停止运行或重复输出最后值的问题求助
解决串口传感器数据读取停止/重复输出问题
问题分析
你的代码出现停止运行或重复输出的核心原因有两个:
- 依赖
readline()按\r\n分割数据,一旦传感器输出的换行符不规范(如缺失换行、出现空行),readline()会因等待超时返回空数据,导致后续循环无法正确触发。 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
相关产品推荐
相关产品推荐

