Arduino UNO与树莓派串口通信:Python读取传感器数据速度过慢问题
解决Python读取Arduino传感器数据速度慢的问题
看起来你遇到了Python读取Arduino传感器数据比IDE慢很多的情况,我帮你梳理几个常见的优化点,应该能解决这个问题:
1. 修正串口初始化的配置顺序
你的代码里先创建serial.Serial对象再设置波特率,这可能导致波特率没有正确生效(部分场景下pyserial不会动态更新波特率)。建议在初始化时直接指定所有关键参数:
import serial from time import sleep ser = serial.Serial( port='/dev/ttyACM0', baudrate=9600, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, bytesize=serial.EIGHTBITS, timeout=0.1 # 设置超时,避免读取操作无限阻塞 )
其中timeout参数尤为关键,它能让读取操作在指定时间内无数据时自动返回,不会一直挂起拖慢整体速度。
2. 优化读取与文件写入逻辑
频繁的磁盘IO会严重拖慢程序速度,你可以先把数据缓存到内存列表中,攒到一定数量再批量写入文件;同时改用一次性读取所有可用数据的方式,减少串口交互次数:
data_buffer = [] stop = False file = open("PulseData/MasterArrayData.txt","w") try: print("Start scanning") while not stop: # 一次性读取串口缓存的所有数据 raw_data = ser.read_all().decode('utf-8').strip() if raw_data: data_buffer.append(raw_data) # 每攒10条数据批量写入,可根据需求调整阈值 if len(data_buffer) >= 10: file.write('\n'.join(data_buffer) + '\n') file.flush() # 确保数据写入磁盘 data_buffer = [] sleep(0.001) # 短暂休眠,避免占用过多CPU资源 finally: # 程序结束时写入剩余未缓存的数据 if data_buffer: file.write('\n'.join(data_buffer) + '\n') file.close() ser.close()
3. 优化Arduino端的输出效率
Arduino IDE读取速度快,很大程度是因为IDE的串口监视器做了接收优化,而你的Arduino代码可能用了低效的输出方式:
- 优先用二进制数据传输代替ASCII字符串:比如用
Serial.write()直接发送传感器的原始字节(例如把16位整数拆成两个字节发送),比Serial.print()输出字符串的传输量小、速度快很多。 - 减少不必要的调试输出:只发送核心传感器数据,避免每次读取都输出冗余信息。
- 替换
delay()为非阻塞逻辑:如果Arduino代码里用了delay(),会阻塞程序导致数据输出间隔变长,改用millis()来控制传感器读取频率。
举个Arduino端优化的示例:
void setup() { Serial.begin(9600); // 初始化传感器... } void loop() { static unsigned long last_read_time = 0; const unsigned long read_interval = 10; // 每10ms读取一次传感器 if (millis() - last_read_time >= read_interval) { last_read_time = millis(); int sensor_value = analogRead(A0); // 读取传感器数据 // 将int类型拆分为两个字节发送 Serial.write((sensor_value >> 8) & 0xFF); Serial.write(sensor_value & 0xFF); } }
对应的Python读取二进制数据的代码片段:
while not stop: raw_bytes = ser.read(2) # 读取2字节对应一个16位整数 if len(raw_bytes) == 2: sensor_value = (raw_bytes[0] << 8) | raw_bytes[1] data_buffer.append(str(sensor_value)) # 后续写入逻辑同上
4. 树莓派端的串口环境优化
- 确保串口权限:执行
sudo usermod -aG dialout pi(假设你的用户名是pi),将用户加入dialout组,获取串口读写权限,重启后生效。 - 更新pyserial库:执行
pip install --upgrade pyserial,旧版本可能存在性能瓶颈。 - 关闭其他串口连接:比如Arduino IDE的串口监视器如果未关闭,会占用串口导致Python读取受阻。
试试这些优化点,应该能让Python的读取速度和Arduino IDE接近甚至一致。
内容的提问来源于stack exchange,提问作者Robin
相关产品推荐
相关产品推荐

