zk-5ad没输出原因是?
zk-5ad没输出原因是?做Arduino uno ,TT电机,MPU6500的自平衡机器人时,烧录程序驱动无输出,什么原因,怎么解决?
由AI8051u擎天柱方案吗?
#include "I2Cdev.h"
#include <PID_v1.h> //From https://github.com/br3ttb/Arduino-PID-Library/blob/master/PID_v1.h
#include "MPU6050_6Axis_MotionApps20.h" //https://github.com/jrowberg/i2cdevlib/tree/master/Arduino/MPU6050
MPU6050 mpu;
// MPU control/status vars
bool dmpReady = false;// set true if DMP init was successful
uint8_t mpuIntStatus; // holds actual interrupt status byte from MPU
uint8_t devStatus; // return status after each device operation (0 = success, !0 = error)
uint16_t packetSize; // expected DMP packet size (default is 42 bytes)
uint16_t fifoCount; // count of all bytes currently in FIFO
uint8_t fifoBuffer; // FIFO storage buffer
// orientation/motion vars
Quaternion q; // quaternion container
VectorFloat gravity; // gravity vector
float ypr; // yaw/pitch/roll container and gravity vector
/*********Tune these 4 values for your BOT*********/
double setpoint= 182; //set the value when the bot is perpendicular to ground using serial monitor.
//Read the project documentation on circuitdigest.com to learn how to set these values
double Kp = 15; //21 Set this first
double Kd = 0.9; //0.8 Set this secound
double Ki = 140; //140 Finally set this
/******End of values setting*********/
double input, output;
PID pid(&input, &output, &setpoint, Kp, Ki, Kd, DIRECT);
volatile bool mpuInterrupt = false; // indicates whether MPU interrupt pin has gone high
void dmpDataReady()
{
mpuInterrupt = true;
}
void setup() {
Serial.begin(115200);
// initialize device
Serial.println(F("Initializing I2C devices..."));
mpu.initialize();
// verify connection
Serial.println(F("Testing device connections..."));
Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));
// load and configure the DMP
devStatus = mpu.dmpInitialize();
// supply your own gyro offsets here, scaled for min sensitivity
mpu.setXGyroOffset(-479);
mpu.setYGyroOffset(84);
mpu.setZGyroOffset(15);
mpu.setZAccelOffset(1638);
// make sure it worked (returns 0 if so)
if (devStatus == 0)
{
// turn on the DMP, now that it's ready
Serial.println(F("Enabling DMP..."));
mpu.setDMPEnabled(true);
// enable Arduino interrupt detection
Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)..."));
attachInterrupt(0, dmpDataReady, RISING);
mpuIntStatus = mpu.getIntStatus();
// set our DMP Ready flag so the main loop() function knows it's okay to use it
Serial.println(F("DMP ready! Waiting for first interrupt..."));
dmpReady = true;
// get expected DMP packet size for later comparison
packetSize = mpu.dmpGetFIFOPacketSize();
//setup PID
pid.SetMode(AUTOMATIC);
pid.SetSampleTime(10);
pid.SetOutputLimits(-255, 255);
}
else
{
// ERROR!
// 1 = initial memory load failed
// 2 = DMP configuration updates failed
// (if it's going to break, usually the code will be 1)
Serial.print(F("DMP Initialization failed (code "));
Serial.print(devStatus);
Serial.println(F(")"));
}
//Initialise the Motor outpu pins
pinMode (6, OUTPUT);
pinMode (9, OUTPUT);
pinMode (10, OUTPUT);
pinMode (11, OUTPUT);
//By default turn off both the motors
analogWrite(6,LOW);
analogWrite(9,LOW);
analogWrite(10,LOW);
analogWrite(11,LOW);
}
void loop() {
// if programming failed, don't try to do anything
if (!dmpReady) return;
// wait for MPU interrupt or extra packet(s) available
while (!mpuInterrupt && fifoCount < packetSize)
{
//no mpu data - performing PID calculations and output to motors
pid.Compute();
//Print the value of Input and Output on serial monitor to check how it is working.
Serial.print(input); Serial.print(" =>"); Serial.println(output);
if (input>150 && input<200){//If the Bot is falling
if (output>0) //Falling towards front
Forward(); //Rotate the wheels forward
else if (output<0) //Falling towards back
Reverse(); //Rotate the wheels backward
}
else //If Bot not falling
Stop(); //Hold the wheels still
}
// reset interrupt flag and get INT_STATUS byte
mpuInterrupt = false;
mpuIntStatus = mpu.getIntStatus();
// get current FIFO count
fifoCount = mpu.getFIFOCount();
// check for overflow (this should never happen unless our code is too inefficient)
if ((mpuIntStatus & 0x10) || fifoCount == 1024)
{
// reset so we can continue cleanly
mpu.resetFIFO();
Serial.println(F("FIFO overflow!"));
// otherwise, check for DMP data ready interrupt (this should happen frequently)
}
else if (mpuIntStatus & 0x02)
{
// wait for correct available data length, should be a VERY short wait
while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();
// read a packet from FIFO
mpu.getFIFOBytes(fifoBuffer, packetSize);
// track FIFO count here in case there is > 1 packet available
// (this lets us immediately read more without waiting for an interrupt)
fifoCount -= packetSize;
mpu.dmpGetQuaternion(&q, fifoBuffer); //get value for q
mpu.dmpGetGravity(&gravity, &q); //get value for gravity
mpu.dmpGetYawPitchRoll(ypr, &q, &gravity); //get value for ypr
input = ypr * 180/M_PI + 180;
}
}
void Forward() //Code to rotate the wheel forward
{
analogWrite(6,output);
analogWrite(9,0);
analogWrite(10,output);
analogWrite(11,0);
Serial.print("F"); //Debugging information
}
void Reverse() //Code to rotate the wheel Backward
{
analogWrite(6,0);
analogWrite(9,output*-1);
analogWrite(10,0);
analogWrite(11,output*-1);
Serial.print("R");
}
void Stop() //Code to stop both the wheels
{
analogWrite(6,0);
analogWrite(9,0);
analogWrite(10,0);
analogWrite(11,0);
Serial.print("S");
} 在使用Arduino Uno、TT电机、MPU6500构建自平衡机器人时,若出现“zk-5ad无输出”问题,可能涉及硬件连接、传感器数据读取、驱动逻辑或控制算法等多个环节。以下为可能原因及解决方案的系统分析。
一、zk-5ad无输出的可能原因
1. 硬件连接问题
电源供电不足:TT电机功率较大,若电源电压或电流不足,可能导致电机无法驱动。需确保电源电压(如7.4V锂电池)稳定,且Arduino Uno的稳压模块能正常供电。
电机驱动模块故障:若使用L298N或TB6612等驱动模块,需检查模块是否损坏、引脚连接是否正确(如PWM信号线、方向控制线)。
MPU6500通信异常:MPU6500通过I2C接口与Arduino通信,需检查SDA/SCL引脚是否接反、上拉电阻是否缺失或I2C地址是否冲突(默认地址为0x68)。
2. 传感器数据读取失败
MPU6500初始化失败:程序中未正确配置MPU6500寄存器(如电源管理寄存器PWRMGMT1未置零),导致传感器未启动。
数据读取错误:未正确解析MPU6500的加速度计和陀螺仪原始数据,或未进行单位转换(如将陀螺仪数据乘以灵敏度系数)。
滤波算法缺失:未使用互补滤波或卡尔曼滤波融合加速度计和陀螺仪数据,导致角度计算误差过大,影响控制逻辑。
3. 控制逻辑或算法问题
PID参数整定不当:比例(P)、积分(I)、微分(D)系数未合理设置,可能导致系统响应过慢或震荡。例如,P值过小无法纠正倾斜,P值过大则引发剧烈抖动。
输出限幅缺失:电机PWM信号未设置上下限(如analogWrite()范围应为0-255),可能导致输出无效或过载。
方向逻辑错误:电机旋转方向与倾角变化方向未正确对应,例如机器人前倾时电机应向前转动,若方向相反则系统无法平衡。
4. 程序逻辑或代码错误
中断或延时冲突:程序中使用delay()函数可能导致传感器采样间隔过大,影响实时性。建议使用millis()实现非阻塞延时。
变量类型错误:浮点运算未正确声明(如float),或整型溢出导致角度计算错误。
未启用串口调试:未通过Serial.print()输出传感器数据或中间变量,难以定位问题根源。
二、解决方案与调试步骤
1. 硬件排查
使用万用表测量电源电压,确保电机供电充足(如TT电机额定电压为6-12V)。
单独测试电机驱动模块:编写简单程序控制电机正反转,确认驱动模块功能正常。
使用I2C扫描工具(如Arduino IDE的Wire库示例)检测MPU6500是否被正确识别(地址应为0x68)。
2. 传感器调试
编写独立程序读取MPU6500原始数据,验证加速度计和陀螺仪输出是否合理(如静止时加速度Z轴应接近1g)。
实现互补滤波算法,计算倾角并输出至串口,确保角度变化平滑且无漂移。
3. 控制逻辑优化
从简单比例控制(仅P项)开始调试,逐步增加D项抑制震荡,最后加入I项消除稳态误差。
设置PWM输出阈值(如最小值为80,最大值为200),避免电机因输出过小无法启动或过大过载。
通过串口绘图工具(如Arduino Serial Plotter)观察倾角和PWM输出波形,调整PID参数至系统稳定。
4. 代码示例片段
```cpp
// MPU6500初始化
Wire.beginTransmission(0x68);
Wire.write(0x6B);// 电源管理寄存器
Wire.write(0); // 唤醒传感器
Wire.endTransmission();
// 读取传感器数据
void readMPU() {
Wire.beginTransmission(0x68);
Wire.write(0x3B);// 加速度计首地址
Wire.endTransmission();
Wire.requestFrom(0x68, 6);
while (Wire.available() < 6);// 等待数据
AccX = Wire.read()
[本文内容由国芯人工智能辅助生成,仅供参考] 国芯人工智能 发表于 2025-10-17 22:03
在使用Arduino Uno、TT电机、MPU6500构建自平衡机器人时,若出现“zk-5ad无输出”问题,可能涉及硬件连接、 ...
收到,还是没有找到问题
页:
[1]