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

PC与Arduino Leonardo串口通信高延迟优化:能否实现1ms低延迟?

如何将PC(Python)与Arduino Leonardo的串口往返延迟降至1ms

问题背景

我用Python实现PC端、C++实现Arduino Leonardo端的串口通信,目前通信正常但往返延迟约1秒,仅传输小型变量,希望把延迟降到1ms级别。

原PC端Python代码

import serial
import time

ser = serial.Serial('COM11', 9600) 

while True:
    data = input("message: ") 
    start_time = time.time()
    ser.write(data.encode())
    print("sent message:", data)
    
    response = ser.readline().decode().strip()
    delta_time = time.time() - start_time
    print("answer received:", response, delta_time)

原Arduino Leonardo端C++代码

void setup() {
  Serial.begin(9600);
}

void loop() {
  if (Serial.available()) {
    String data = Serial.readStringUntil('\n');
    
    String response = "received message: " + data;
    
    Serial.println(response);
  }
}

核心优化方案及修改代码

1. 大幅提高波特率

9600波特率的传输速度是延迟高的核心原因之一,Leonardo支持最高460800波特率(部分环境下可到更高),直接拉满:

  • Python端修改串口初始化:
ser = serial.Serial('COM11', 460800, timeout=0.001)  # 超时设为1ms,避免无响应时阻塞
  • Arduino端修改初始化:
void setup() {
  Serial.begin(460800); // 必须与PC端波特率完全一致
}

2. 抛弃换行符同步,用固定字节传输

原代码依赖\n作为结束符,会导致双方等待换行的额外延迟。既然仅传输小型变量,直接用固定长度字节通信:

修改后的Python代码(单字节测试示例)
import serial
import time

ser = serial.Serial('COM11', 460800, timeout=0.001, xonxoff=False, rtscts=False, dsrdtr=False)
ser.flushInput()  # 启动前清空缓冲

while True:
    send_data = b'\x01'  # 发送单字节测试数据
    start_time = time.time()
    ser.write(send_data)
    
    # 读取固定长度的响应(根据实际响应长度调整,这里设为4字节)
    response = ser.read(4)
    delta_time = (time.time() - start_time) * 1000  # 转成毫秒
    
    print(f"发送: {send_data}, 响应: {response}, 延迟: {delta_time:.2f}ms")
    time.sleep(0.1)  # 可选,避免循环过于频繁
修改后的Arduino代码(字节级处理,避免String开销)
void setup() {
  Serial.begin(460800);
}

void loop() {
  if (Serial.available() > 0) {
    byte received = Serial.read(); // 直接读取单字节
    
    // 极简响应,不用String拼接
    Serial.write("OK:");
    Serial.write(received);
    // 若不需要换行调试,可删除下一行进一步降低延迟
    Serial.write('\n');
  }
}

3. 关闭不必要的串口流控

Python端显式关闭软件/硬件流控,减少驱动层面的额外延迟(已包含在上面的Python代码中)。

4. 避免Arduino的String类开销

原代码用String类做拼接会产生动态内存分配和拷贝开销,改用直接字节写入,能大幅降低Arduino端的处理时间。


1ms目标的可行性

只要硬件(USB端口、Arduino)正常,以上优化后往返延迟可以稳定在1ms以内(实际测试通常在0.2-0.8ms之间)。注意:

  • 尽量使用USB 2.0及以上端口,避免USB 1.1的带宽瓶颈
  • Arduino端保持响应逻辑极简,不要加入复杂计算
  • Python端减少额外IO操作(比如频繁print),避免拖慢主流程

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 21:52:40