New Project

CONNECT

Arduino Self Balancing Robot

  • Page Views 9209
  • Spread the love
    •  
    •  
    •  
    •  
    •  
    •  
    •  
    •  
    •  
    •  
    •  
    •  

    ‘Make your own robot’ project will describe the construction of our plant in Arduino Self Balancing Robot in this section.Tell controlled android version of our previous projects we.This Is our project to move to our control.Let’s go let’s get to our building project.

    Materials:

    • Arduino Uno or Mega
    • L298 Motor Driver Card
    • 3 Piece potentiometer
    • You can cut plexiglass plate for mechanical or rigid plastic containers.
    • 4 pieces of screw rods in length of about 20 cm
    • 24-Piece Nut
    • 2 pieces 6V DC motors at 250 rpm (from which together with the wheels)
    • Lipo battery

    The mechanics:

    20 × 8 cm can be cut in three Plexiglas plates keselim.farkl size.Cut diameter of the screw rod through the hole until after the corner of each sheet’s open.Each plate so that the rod between two nuts and bolts Let’s mounting screws.Let us consider each other to be equal to the gap between the plates.Then our engine by connecting it to the bottom right in the center of the iron so that the left and right edges of the plate Let’s just put the silicon wire.Such mechanical parts.

    Electronic Section:

    Circuit diagram:

     

    L298N

     

    We use the engine running in a synchronous motor drive with its own library.In this way, also it happens to be that minimize errors in the work of the engine with full data system.

    We’re putting the plus side of the battery to the motor LiPo 12V power input on the drive.
    We’re putting the minus end of the GND input.

     

     

    In addition to the circuit attribute to 3 units 0.1 analog potentiometer year and 2 pins.Here the task of potentiometer kPa, manually adjusting the values of kd and will allow us to find the optimal balance point of the robot.Mpu6050 gyro sensor mounted on the bottom plate horizontally let.

    Software Part:

    Libraries let’s get out of here >>libraries

    Arduino Software:

    #include <PID_v1.h>
    #include <LMotorController.h>
    #include "I2Cdev.h"
    
    #include "MPU6050_6Axis_MotionApps20.h"
    
    #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
     #include "Wire.h"
    #endif
    
    
    #define LOG_INPUT 0
    #define MANUAL_TUNING 0
    #define LOG_PID_CONSTANTS 0 //MANUAL_TUNING must be 1
    #define MOVE_BACK_FORTH 0
    
    #define MIN_ABS_SPEED 30
    
    //MPU
    
    
    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
    
    
    //PID
    
    
    #if MANUAL_TUNING
     double kp , ki, kd;
     double prevKp, prevKi, prevKd;
    #endif
    double originalSetpoint = 174.29;
    double setpoint = originalSetpoint;
    double movingAngleOffset = 0.3;
    double input, output;
    int moveState=0; //0 = balance; 1 = back; 2 = forth
    
    #if MANUAL_TUNING
     PID pid(&input, &output, &setpoint, 0, 0, 0, DIRECT);
    #else
     PID pid(&input, &output, &setpoint, 70, 240, 1.9, DIRECT);
    #endif
    
    
    //MOTOR CONTROLLER
    
    
    int ENA = 3;
    int IN1 = 4;
    int IN2 = 8;
    int IN3 = 5;
    int IN4 = 7;
    int ENB = 6;
    
    
    LMotorController motorController(ENA, IN1, IN2, ENB, IN3, IN4, 0.6, 1);
    
    
    //timers
    
    
    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)
     #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
     Wire.begin();
     TWBR = 24; // 400kHz I2C clock (200kHz if CPU is 8MHz)
     #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
     Fastwire::setup(400, true);
     #endif
    
     // initialize serial communication
     // (115200 chosen because it is required for Teapot Demo output, but it's
     // really up to you depending on your project)
     Serial.begin(115200);
     while (!Serial); // wait for Leonardo enumeration, others continue immediately
    
     // 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
     Serial.println(F("Initializing DMP..."));
     devStatus = mpu.dmpInitialize();
    
     // supply your own gyro offsets here, scaled for min sensitivity
     mpu.setXGyroOffset(220);
     mpu.setYGyroOffset(76);
     mpu.setZGyroOffset(-85);
     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..."));
     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(")"));
     }
    }
    
    
    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();
     motorController.move(output, MIN_ABS_SPEED);
     
     unsigned long currentMillis = millis();
    
     if (currentMillis - time1Hz >= 1000)
     {
     loopAt1Hz();
     time1Hz = currentMillis;
     }
     
     if (currentMillis - time5Hz >= 5000)
     {
     loopAt5Hz();
     time5Hz = currentMillis;
     }
     }
    
     // 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);
     mpu.dmpGetGravity(&gravity, &q);
     mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
     #if LOG_INPUT
     Serial.print("ypr\t");
     Serial.print(ypr[0] * 180/M_PI);
     Serial.print("\t");
     Serial.print(ypr[1] * 180/M_PI);
     Serial.print("\t");
     Serial.println(ypr[2] * 180/M_PI);
     #endif
     input = ypr[1] * 180/M_PI + 180;
     }
    }
    
    
    void loopAt1Hz()
    {
    #if MANUAL_TUNING
     setPIDTuningValues();
    #endif
    }
    
    
    void loopAt5Hz()
    {
     #if MOVE_BACK_FORTH
     moveBackForth();
     #endif
    }
    
    
    //move back and forth
    
    
    void moveBackForth()
    {
     moveState++;
     if (moveState > 2) moveState = 0;
     
     if (moveState == 0)
     setpoint = originalSetpoint;
     else if (moveState == 1)
     setpoint = originalSetpoint - movingAngleOffset;
     else
     setpoint = originalSetpoint + movingAngleOffset;
    }
    
    
    //PID Tuning (3 potentiometers)
    
    #if MANUAL_TUNING
    void setPIDTuningValues()
    {
     readPIDTuningValues();
     
     if (kp != prevKp || ki != prevKi || kd != prevKd)
     {
    #if LOG_PID_CONSTANTS
     Serial.print(kp);Serial.print(", ");Serial.print(ki);Serial.print(", ");Serial.println(kd);
    #endif
    
     pid.SetTunings(kp, ki, kd);
     prevKp = kp; prevKi = ki; prevKd = kd;
     }
    }
    
    
    void readPIDTuningValues()
    {
     int potKp = analogRead(A0);
     int potKi = analogRead(A1);
     int potKd = analogRead(A2);
     
     kp = map(potKp, 0, 1023, 0, 25000) / 100.0; //0 - 250
     ki = map(potKi, 0, 1023, 0, 100000) / 100.0; //0 - 1000
     kd = map(potKd, 0, 1023, 0, 500) / 100.0; //0 - 5
    }
    #endif

     

    We complete install the software and necessary connections.Let loose in an upright position after running our robot.If you have trouble in stopping the robot’s balance with the potentiometer ‘kPa’, ‘on’ and ‘kd’ We’re changing values.

     

    ‘Make your own robot’ in equilibrium with the Arduino in this part of our project we have completed our standing robot.Make their robots to discuss our next project .. good work …

    Share

    What did they say ?

    21 Comment - "Arduino Self Balancing Robot"

    avatar
    Sort:   The Newests | Ancients | Likes
    André Donizete
    Visitor
    André Donizete
    Hello, good morning. Am technical school student , I’m 16 years old , have a scientific design of an inverted pendulum for people users of the wheelchair . I am in the assembly of the prototype , and I’m using almost all its components , such as the one Arduino , I’m using MPU6050 , and the bridge h L298d , however this bridge h is not the keyes , does this code will function normally ?? I am very grateful to be can answer me and give me some tips for I am a little confused in this part… Read more »
    André Donizete
    Visitor
    André Donizete

    Thanks for the info , however my bridge is different … h has the same chi only that it is less. You could also tell me why you guys uses Enables the bridge h ? Thank you have a good day.

    Josephine
    Visitor
    Josephine

    hello!
    where do you place and connect the 3 piece potentiometer? (in detail please!)
    what is the resistence of the potentiometer? b10K?
    What is the LiPo battery voltage?
    if you add weight to the top of the robot will try to balance work it out?

    Josephine
    Visitor
    Josephine

    where do the other two legs of the potentiometers get connected to?

    ahmed
    Visitor
    ahmed

    i think to the GND and to 5V of the arduino

    shubham
    Visitor
    shubham

    while uploading this code in ardiuno uno , em getting error .

    C:\Users\Admin\Desktop\balance_robot\balance_robot.ino:1:20: fatal error: PID_v1.h: No such file or directory

    #include

    ^

    compilation terminated.

    exit status 1
    Error compiling for board Arduino/Genuino Uno.

    Oatania
    Visitor
    Oatania

    I have some questions
    1. Which is the interrupt pin of MPU6050 on the arduino board?
    2. I found “originalSetpoint = 174.29;” wrote on your code, How can you get that value?
    3. when i uploaded the code to my robot, the robot did nothing and the serial monitor showed me
    Initializing I2C devices…
    Testing device connections…
    MPU6050 connection successful
    Initializing DMP…
    Enabling DMP…
    Enabling interrupt detection (Arduino external interrupt 0)…
    DMP ready! Waiting for first interrupt…

    Could you help me pls, thank you for your great project 🙂

    Lois
    Visitor
    Lois

    Nope. 14 stories is still a lot. I dub you prolific. (I can’t get more than about 10 out at any given time, though including recent rush of flash prtdcuoivity, I might be at about 14.)

    SAHIL
    Visitor
    SAHIL

    Im done with all connections but i am stuck at ”
    Enabling interrupt detection (Arduino external interrupt 0)…
    DMP ready! Waiting for first interrupt…

    Not getting what to do!

    suman
    Visitor
    suman

    SEZGIN GÜL wow nice project its really beautiful

    suman
    Visitor
    suman

    hi i am geting error at mpu 6050 what to do can you help me please
    Initializing I2C devices…
    Testing device connections…
    MPU6050 connection failed
    Initializing DMP…
    DMP Initialization failed (code 1)

    Josephine
    Visitor
    Josephine

    hi so i’ve replicated the robot however regardless when the power is turned on the wheels spin non-stop. however when tested the out puts of the arduino to the motor stepper are working fine and react to the position of the gyro. any thoughts?

    Muhammad Mustafa
    Visitor
    Muhammad Mustafa

    sir, can you explain this error please
    “fatal error: I2Cdev.h: No such file or directory

    #include “I2Cdev.h”

    ^

    compilation terminated.

    exit status 1
    Error compiling.

    wpDiscuz

    BE A FACEBOOK FAN

    Instagram