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

树莓派使用Pyserial与Arduino串口通信无响应问题求助

问题排查步骤
  • 优先排查串口打开后复位延迟问题:Arduino通过USB连接时,打开串口会触发自动复位,启动需要1~2秒初始化时间,你的代码打开串口后直接发数据,此时Arduino还未完成启动,数据会直接丢失,这是符合你「Arduino IDE发送正常、Python发送失败」现象的最高概率问题。
  • 确认串口设备路径正确性:树莓派上Arduino的端口可能会在重连后在ttyACM0和ttyACM1之间跳转,可执行命令ls /dev/ttyACM*确认当前实际挂载的端口和代码中配置一致。
  • 加回显调试验证数据接收:在Arduino解析数据逻辑后增加回显代码,Python端发完数据后读取串口返回内容,可直接确认Arduino是否收到了正确数据。
  • 校验数据解析逻辑:现有Arduino代码遇到不完整半包、顺序错误的数据包时会解析失败,建议增加包结束标记(比如换行符),收到完整包后再解析。
  • 核对串口参数一致性:确认Arduino和Python的波特率、校验位、停止位完全一致,pyserial默认参数为8N1,和Arduino默认参数匹配,一般不会有问题但可额外核对。
修复后的代码示例

Python端修复代码

import serial
import time

ser = serial.Serial('/dev/ttyACM1', 9600, timeout=1)
# 等待Arduino复位完成
time.sleep(2)
ser.flush()

# 增加换行符作为包结束标记,避免半包解析异常
ser.write(b"90X90Y\n")
# 可选:读取Arduino回显验证通信正常
response = ser.readline().decode('utf-8').strip()
print(f"Arduino返回内容:{response}")
ser.close()

Arduino端修复代码

#include <Servo.h> 

Servo X;
Servo Y;

String receiveBuffer;
int moveX;
int moveY;

int defX = 95;
int defY = 5;

void setup(){
  Serial.begin(9600);
  X.attach(6);
  Y.attach(7);
  // 初始化舵机到默认位置
  X.write(defX);
  Y.write(defY);
}

void loop(){
  if (Serial.available() > 0){
    char c = Serial.read();
    // 收到换行符代表完整包接收完成,开始解析
    if (c == '\n') {
      int xIndex = receiveBuffer.indexOf('X');
      int yIndex = receiveBuffer.indexOf('Y');
      // 校验包格式合法再解析
      if (xIndex != -1 && yIndex != -1) {
        String receiveX = receiveBuffer.substring(0, xIndex);
        String receiveY = receiveBuffer.substring(xIndex+1, yIndex);
        moveX = receiveX.toInt();
        moveY = receiveY.toInt();
        // 限制角度在舵机合法范围内,避免损坏硬件
        moveX = constrain(moveX, 0, 180);
        moveY = constrain(moveY, 0, 180);
        X.write(moveX);
        Y.write(moveY);
        // 回显确认接收成功
        Serial.print("OK X:");
        Serial.print(moveX);
        Serial.print(" Y:");
        Serial.println(moveY);
      }
      // 清空缓冲区准备接收下一个包
      receiveBuffer = "";
    } else {
      receiveBuffer += c;
    }
  }
}
替代实现方案
  • 方案1:使用Firmata协议,给Arduino刷入StandardFirmata固件,Python端使用pyfirmata库直接控制舵机,不需要自己编写串口解析逻辑,适合快速开发。
  • 方案2:修改通信格式为固定长度字节流,比如每次发3个字节:第一个字节为0xFF作为包头,第二个字节为X轴角度,第三个字节为Y轴角度,Arduino收到3个字节且包头正确时直接取后两个字节作为角度值,解析效率更高,不会出现字符串解析异常。
  • 方案3:用I2C通信代替USB串口,将Arduino设为I2C从设备,树莓派作为主设备发送角度数据,不会占用USB串口,也不存在串口触发Arduino复位的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 02:36:04