Go Down

Topic: self balance robot unknow issue not working  (Read 82 times) previous topic - next topic


Jan 13, 2021, 06:01 pm Last Edit: Jan 17, 2021, 10:35 pm by tahajunaid

hey everyone. 
I'm new here please help me out and i will try my best to post my questions in the best way.
extremely need help, I build a self-balance robot, after all the connections and coding, I don't know why the robot not balancing when I turn on the robot it keeps moving forward. i tried different codes which already available in google and saw many videos every one using the same codes which im using but their robot working 100% but mine, not i have no idea what im doing wrong, but it seems like the mpu5060 not sending signals to the Arduino.
even i tried to change KP, KD , Ki but no use.
I don't have a background in programming this why I need your help. 

laibaries which i used:

hardware im using:

L298N motor driver module connections:
nt ENA = 10;
int IN1 = 6;
int IN2 = 7;
int IN3 = 8;
int IN4 = 9;
int ENB = 11;

mpu5060 connections:

Code: [Select]
#include "PID_v1.h"
#include "LMotorController.h"
#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps20.h"

   #include "Wire.h"

#define MIN_ABS_SPEED 20

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

double originalSetpoint = 165; 
double setpoint = originalSetpoint;
double movingAngleOffset = 0.1;
double input, output;
int moveState=0; //0 = balance; 1 = back; 2 = forth
double Kp = 10; // First adjustment
double Kd = 0; // Second adjustment
double Ki = 0; // Third adjustment
PID pid(&input, &output, &setpoint, Kp, Ki, Kd, DIRECT); // kp = 55,kd=0.9

double motorSpeedFactorLeft = 0.6;
double motorSpeedFactorRight = 0.6;
int ENA = 10;
int IN1 = 6;
int IN2 = 7;
int IN3 = 8;
int IN4 = 9;
int ENB = 11;
LMotorController motorController(ENA, IN1, IN2, ENB, IN3, IN4, motorSpeedFactorLeft, motorSpeedFactorRight);

long time1Hz = 0;
long time5Hz = 0;

volatile bool mpuInterrupt = false;     // indicates whether MPU interrupt pin has gone high
void dmpDataReady()
   mpuInterrupt = true;

void setup()
   // join I2C bus (I2Cdev library doesn't do this automatically)
       TWBR = 24; // 400kHz I2C clock (200kHz if CPU is 8MHz)
       Fastwire::setup(400, true);

   // initialize serial communication
   // (115200 chosen because it is required for Teapot Demo output, but it's
   // really up to you depending on your project)
   while (!Serial); // wait for Leonardo enumeration, others continue immediately

   // initialize device
   Serial.println(F("Initializing I2C devices..."));

   // 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
   Serial.println(F("Initializing DMP..."));
   devStatus = mpu.dmpInitialize();

   // supply your own gyro offsets here, scaled for min sensitivity
   mpu.setZAccelOffset(1788); // 1688 factory default for my test chip

   // 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..."));

       // 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.SetOutputLimits(-255, 255);  
       // 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 "));

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
       motorController.move(output, MIN_ABS_SPEED);

   // 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
       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);
       mpu.dmpGetGravity(&gravity, &q);
       mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
       #if LOG_INPUT
           Serial.print(ypr[0] * 180/M_PI);
           Serial.print(ypr[1] * 180/M_PI);
           Serial.println(ypr[2] * 180/M_PI);
       input = ypr[1] * 180/M_PI + 180;

this is a serial monitor status.


Jan 13, 2021, 11:17 pm Last Edit: Jan 13, 2021, 11:18 pm by gilshultz
You might want to include the schematic, not the (Frizzy thing) and be sure you are wired to your schematic. List all the modules you used and the power supply as well. I would start by loading a I2C scanner and determining is all your I/O is mapped per your software and to the proper ports. When that works write small sketches to test part of the robot to be sure your code is written properly.  I am only guessing but I think you found this robot, got the parts and downloaded the code. If you did that and do not have much experience in programming the above debug will be a tremendous asset for you as you learn.
This response is to help you get started in solving your problem, not solve it for you.
Good Luck & Have Fun!


Please edit your post to add code tags.  See the "How to get the best out of the forum" post.

Go Up