使用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); } }
关键修改说明
- 修正角度范围控制:移除无效的
if条件,改用constrain()函数直接将角度值限制在0-180范围内,确保舵机接收有效指令。 - 添加更新频率控制:通过
lastUpdateTime和updateInterval控制舵机指令的发送间隔(50ms),避免高频调用导致的资源占用和电流过载。 - 优化变量可读性:将
timer改为lastUpdateTime,更清晰表达变量用途。
内容的提问来源于stack exchange,提问作者simo
相关产品推荐
相关产品推荐

