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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:47:41