求助:pyserial接收Arduino数据后输入缓冲区无法即时补充
解决PySerial接收Arduino串口数据延迟问题
我使用PySerial模块读取Arduino发送的串口数据,数据更新率约250Hz,单条数据包含29字节,波特率设置为230400。运行代码时发现,PySerial的输入缓冲区要等待约0.5秒才会自动从Arduino补充数据,请问如何实现数据接收后立即补充输入缓冲区?
我的代码如下:
import serial import time ser = serial.Serial() old = 0 while True: # 修正原代码语法错误:添加冒号 if ser.in_waiting > 29: print('buf: ', ser.readInputBuffer()) new = time.perf_counter_ns() print(ser.readBinaryList(29)) print('%.1f\n' % ((new - old)*1e-3)) # 修正原代码格式字符串语法错误 old = new # updated function definition_07/23 def readBinaryList(num): # 修正原代码变量名:mum改为num data_r = ser.read(num) data_r = [i for i in data_r] return data_r def readInputBuffer(): # 修正原代码:移除多余的self参数 return ser.in_waiting
解决方法
1. 正确初始化串口参数
原代码未指定串口核心参数,且默认阻塞模式会导致延迟。初始化时需明确配置非阻塞模式:
ser = serial.Serial( port='COM3', # 根据你的Arduino实际串口端口修改 baudrate=230400, timeout=0, # 非阻塞模式,读取时立即返回当前缓冲区数据,不等待 xonxoff=False, # 禁用软件流控制 rtscts=False, # 禁用硬件流控制 dsrdtr=False )
timeout=0是核心设置,避免因等待填充缓冲区产生延迟。
2. 调整接收缓冲区大小
默认缓冲区可能过大,导致数据攒到一定量才触发读取,可设置略大于单条数据的缓冲区:
ser.set_buffer_size(rx_size=64) # 大于单条29字节即可,减少数据累积
3. 优化读取逻辑
- 函数定义需放在调用前,避免运行报错;
- 每次读取后清空缓冲区残留数据,防止累积延迟;
- 循环内持续检查缓冲区,有数据立即处理:
import serial import time def readBinaryList(num): data_r = ser.read(num) return [i for i in data_r] def readInputBuffer(): return ser.in_waiting # 初始化串口 ser = serial.Serial( port='COM3', baudrate=230400, timeout=0, xonxoff=False, rtscts=False ) ser.set_buffer_size(rx_size=64) old = time.perf_counter_ns() while True: buf_size = readInputBuffer() if buf_size >= 29: print('buf: ', buf_size) data = readBinaryList(29) new = time.perf_counter_ns() print(data) print('%.1f\n' % ((new - old)*1e-3)) old = new # 清空缓冲区剩余数据,避免累积 if buf_size > 29: ser.read(buf_size - 29)
4. 检查Arduino端发送逻辑
确保Arduino发送严格的29字节二进制数据,避免使用Serial.println()(会添加换行符破坏数据结构),改用Serial.write()直接发送字节数组:
// Arduino示例代码 byte data[29]; // 填充29字节数据到data数组 Serial.write(data, 29); Serial.flush(); // 强制立即发送数据,不滞留
内容的提问来源于Stack Exchange,提问作者Adam Shiau
相关产品推荐
相关产品推荐

