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

Arduino与PySerial串口连接重新打开后速度变慢问题求助

Arduino-PySerial Serial Connection Slow on Reconnect (Fast First Run Only)

Problem Summary

I'm facing an issue where the first serial connection between Arduino and PySerial runs at expected speed (~6ms per transaction), but subsequent connections are drastically slower (~28ms per transaction). Only unplugging the USB cable or reflashing the Arduino sketch restores the original speed—resetting the Arduino via the reset button doesn't help.

Minimal Reproducible Code

Arduino Sketch:

void setup() {
  Serial.begin(9600);
  Serial.println("Arduino ready"); // Print when Arduino ready
}
void loop() {
  // send data only when you receive data:
  if(Serial.available() > 0) {
    Serial.read();
    Serial.println(' ');
  }
  delay(1); // delay in between reads for stability
}

Python Code (PySerial 3.4, Python 3.6):

import serial
import time
ser = serial.Serial('COM5',9600,timeout=1)
print(ser.readline()) # Wait until Arduino is ready
for i in range(1,10):
  tic = time.time() # Start timer
  ser.write(b' ')
  ser.readline()
  toc = time.time() # Log time
  print("Serial write / read took %7.4f ms" % ((toc-tic)*1000))
ser.close()

Test Results

  • First Run:
    b'Arduino ready\r\n'
    Serial write / read took 5.9998 ms
    Serial write / read took 6.0000 ms
    ... (all ~6-7ms)
    
  • Subsequent Runs:
    b'Arduino ready\r\n'
    Serial write / read took 27.9999 ms
    Serial write / read took 29.0003 ms
    ... (all ~28-29ms)
    

Solution & Explanation

This issue almost always comes down to unflushed serial buffers on either the Arduino or host side, or the Arduino failing to reset its serial state properly when the port is re-opened (since a software port close doesn’t trigger the same hardware reset as plugging in the USB cable). Here’s how to fix it:

1. Force a Hardware Reset via PySerial

Most Arduino boards use the DTR line to trigger a reset when the USB is plugged in. We can mimic this in Python by toggling the DTR line before opening the port, ensuring the Arduino starts fresh with empty buffers:

import serial
import time

# Initialize serial port without opening first
ser = serial.Serial()
ser.port = 'COM5'
ser.baudrate = 9600
ser.timeout = 1

# Trigger Arduino reset by toggling DTR
ser.dtr = False
time.sleep(0.1)
ser.dtr = True
ser.open()

# Wait for Arduino to finish setup and clear leftover buffer data
time.sleep(2)
ser.flushInput()
print(ser.readline())

for i in range(1,10):
  tic = time.time()
  ser.write(b' ')
  response = ser.readline()
  toc = time.time()
  print(f"Serial write / read took {((toc-tic)*1000):7.4f} ms")

ser.close()

2. Flush Buffers on Both Ends

Stale data in buffers can cause unexpected delays, so make sure both sides clear their buffers on startup:

  • Arduino Side: Add buffer clearing in setup():
    void setup() {
      Serial.begin(9600);
      // Clear any leftover bytes from previous connections
      while (Serial.available() > 0) {
        Serial.read();
      }
      Serial.println("Arduino ready");
    }
    
  • Python Side: Always call ser.flushInput() and ser.flushOutput() right after opening the port to clear host-side buffers.

3. Why the Reset Button Doesn’t Work?

The Arduino reset button only resets the microcontroller, but the USB-to-serial chip (like CH340 or FTDI) often retains buffer data or stays in a stale state from the previous connection. Unplugging the USB resets both the microcontroller and the USB chip, which is why it fixes the issue.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:18:34