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

使用MPU6050与SG90舵机时Arduino Uno运行数秒后崩溃求助

MPU6050配合SG90舵机运行数秒崩溃的解决办法

你提供的代码运行数秒后崩溃,主要有几个关键问题需要修正:

问题分析

  • 舵机控制条件逻辑错误:原代码中if ((lastan> 0) || (lastan< 180))的判断永远成立,任何整数必然满足其中一个条件,导致myservo.write()被高频重复调用,占用大量CPU资源,甚至引发舵机过载或Arduino资源耗尽。
  • 角度值未做有效范围限制:(mpu.getAngleX()-70)*-1的计算结果可能超出SG90舵机的有效角度范围(0-180),无效值会导致舵机异常,进而影响系统稳定性。
  • 高频无间隔控制舵机:持续无延迟地发送舵机指令,可能导致舵机电流过大,引发Arduino供电不足崩溃。

修正后的代码

#include "Wire.h"
#include <MPU6050_light.h>
#include <Servo.h>

Servo myservo;
MPU6050 mpu(Wire);
unsigned long lastUpdateTime = 0;
const unsigned long updateInterval = 50; // 每50ms更新一次舵机,避免高频调用

void setup() {
  myservo.attach(10);
  Serial.begin(115200);
  Wire.begin();
  
  byte status = mpu.begin();
  Serial.print(F("MPU6050 status: "));
  Serial.println(status);
  while(status != 0){ } // 连接失败则停止运行
  
  Serial.println(F("Calculating offsets, do not move MPU6050"));
  delay(1000);
  // mpu.upsideDownMounting = true; // 如果MPU6050倒置安装,取消注释此行
  mpu.calcOffsets(); // 校准陀螺仪和加速度计偏移
  Serial.println("Done!\n");
}

void loop() {
  mpu.update();
  
  // 限制更新频率,避免高频操作
  if (millis() - lastUpdateTime >= updateInterval) {
    lastUpdateTime = millis();
    
    float angleX = mpu.getAngleX();
    int lastan = (angleX - 70) * -1;
    
    // 将角度限制在0-180的有效范围内
    lastan = constrain(lastan, 0, 180);
    
    myservo.write(lastan);
    // 可选:打印调试信息
    // Serial.print("Angle X: ");
    // Serial.print(angleX);
    // Serial.print(" | Servo Pos: ");
    // Serial.println(lastan);
  }
}

关键修改说明

  1. 修正角度范围控制:移除无效的if条件,改用constrain()函数直接将角度值限制在0-180范围内,确保舵机接收有效指令。
  2. 添加更新频率控制:通过lastUpdateTime和updateInterval控制舵机指令的发送间隔(50ms),避免高频调用导致的资源占用和电流过载。
  3. 优化变量可读性:将timer改为lastUpdateTime,更清晰表达变量用途。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 11:20:37