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
相关产品推荐
相关产品推荐

