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

树莓派与Arduino持续串口通信问题:高频发送读取异常

Hey there! Let's break down why your Raspberry Pi-Arduino serial link is misbehaving when you set the send interval to 1 second— I’ve dealt with this exact quirk before, so here’s what’s going on and how to fix it:

Common Root Causes
  • Data Framing/Sticking Issues: Arduino’s default serial buffer is only 64 bytes. When you send data every 1 second, the Pi might be pushing new bytes before the Arduino finishes processing the last batch. This leads to "stuck" data (like combining "ON" and "OFF" into "ONOFF") which your if-else checks can’t match.
  • Flawed Reading Logic in Arduino Code: If you’re using Serial.read() (which grabs one byte at a time) or Serial.readString() with default timeouts, you might not be capturing complete messages. With a 1-second interval, the timeout window can overlap with the next incoming data, causing partial reads.
  • Overlooked Arduino Reboot Delay: When the Pi initializes the serial port, the Arduino reboots automatically. If you start sending data immediately (without a delay), the first few messages get lost, and subsequent reads can be out of sync.
Step-by-Step Fixes

1. Add a Clear Delimiter to Your Messages (Most Effective!)

The easiest way to avoid data sticking is to mark the end of each message—like a newline character (\n). This tells the Arduino exactly where one message ends and the next begins.

Raspberry Pi (Python) Code:

import serial
import time

# Replace with your correct port (might be /dev/ttyACM0)
ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=1)
time.sleep(2)  # Critical: Wait for Arduino to finish rebooting

while True:
    # Send data with a newline delimiter
    ser.write(b"ON\n")
    # Or switch to "OFF\n" for testing
    time.sleep(1)

Arduino Code:

String receivedMsg;

void setup() {
  Serial.begin(9600);
  Serial.setTimeout(500);  // Shorten timeout to avoid overlapping with next send
}

void loop() {
  if (Serial.available() > 0) {
    // Read until we hit the newline delimiter
    receivedMsg = Serial.readStringUntil('\n');
    receivedMsg.trim();  // Remove any extra whitespace/newlines
    
    // Now your if-else checks will work reliably
    if (receivedMsg == "ON") {
      Serial.println("Executing ON action");
      // Add your hardware control code here
    } 
    else if (receivedMsg == "OFF") {
      Serial.println("Executing OFF action");
      // Add your hardware control code here
    }
    else {
      Serial.print("Invalid input: ");
      Serial.println(receivedMsg);
    }
  }
}

2. Clear Stale Data from the Serial Buffer

If there’s leftover data in the buffer from partial reads, it can mess up future messages. Add this line at the start of your Arduino loop() (or before reading) to clear old bytes:

// Clear any unprocessed bytes
while (Serial.available() > 0) {
  Serial.read();
}

Just make sure you use this alongside the delimiter method—don’t rely on it alone.

3. Verify Serial Parameters Match

Double-check that both devices are using the same:

  • Baud rate (9600, 115200, etc.)
  • Data bits (8 is standard)
  • Stop bits (1 is standard)
  • Parity (none is standard)
    While this works at 5 seconds, higher frequency can expose tiny mismatches that were hidden before.

4. Try a Higher Baud Rate

Switching to a faster baud rate (like 115200) reduces the time it takes to transmit each message, lowering the chance of buffer overflow. Just update the Serial.begin() call on both devices to match.

Final Notes

9 times out of 10, the delimiter fix will resolve this issue immediately. The key is giving both devices a clear way to identify complete messages. If you’re still seeing weird behavior, try adding debug prints to both sides—print what the Pi sends and what the Arduino reads, so you can spot exactly where the data is getting messed up.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 04:00:22