找回密码
 立即注册
查看: 17|回复: 3

zk-5ad没输出原因是?

[复制链接]
  • 打卡等级:以坛为家I
  • 打卡总天数:262
  • 最近打卡:2025-10-19 10:18:12
已绑定手机

148

主题

494

回帖

651

积分

高级会员

积分
651
发表于 3 天前 | 显示全部楼层 |阅读模式
zk-5ad没输出原因是?

做Arduino uno ,TT电机,MPU6500的自平衡机器人时,烧录程序驱动无输出,什么原因,怎么解决?
由AI8051u擎天柱方案吗?
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:262
  • 最近打卡:2025-10-19 10:18:12
已绑定手机

148

主题

494

回帖

651

积分

高级会员

积分
651
发表于 3 天前 | 显示全部楼层
#include "I2Cdev.h"
#include <PID_v1.h> //From https://github.com/br3ttb/Arduin ... lob/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[64]; // FIFO storage buffer
// orientation/motion vars
Quaternion q;           // [w, x, y, z]         quaternion container
VectorFloat gravity;    // [x, y, z]            gravity vector
float ypr[3];           // [yaw, pitch, roll]   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[1] * 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");
}
回复

使用道具 举报 送花

3

主题

1868

回帖

584

积分

等待验证会员

积分
584
发表于 3 天前 | 显示全部楼层
在使用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()

[本文内容由国芯人工智能辅助生成,仅供参考]
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:262
  • 最近打卡:2025-10-19 10:18:12
已绑定手机

148

主题

494

回帖

651

积分

高级会员

积分
651
发表于 前天 07:03 | 显示全部楼层
国芯人*** 发表于 2025-10-17 22:03
在使用Arduino Uno、TT电机、MPU6500构建自平衡机器人时,若出现“zk-5ad无输出”问题,可能涉及硬件连接、 ...

收到,还是没有找到问题
回复

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-10-20 00:39 , Processed in 0.121694 second(s), 65 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表