How to Build an Arduino Self-Balancing Robot

By Roland Pelayo

 

 arduino-self-balancing-robot-1

 

Ever wonder how Segways work? This tutorial will show you how to build an Arduino self-balancing robot that balances itself — just like a Segway!

How Does Balancing Work?

To keep the robot balanced, the motors must counteract the fall of the robot. This action requires a feedback and a correcting element. The feedback element is the MPU6050 gyroscope + accelerometer, which gives both acceleration and rotation in all three axis (MPU6050 I2C basics) which is used by the Arduino to know the current orientation of the robot. The correcting element is the motor and wheel combination.

arduino self-balancing robot balancing

Required Materials

  • Arduino (UNO or Nano can be used. I used Nano for this project.)
  • MPU6050 gyro+accelerometer breakout board.
  • L298N driver module
  • 2 x Geared DC Motor+wheels
  • Three platforms (PCB, acrylic, or thick plastic)
  • Posts to hold the platforms
  • Jumper wires
  • Headers
  • Battery Pack

 

Connection Diagram

self-balancing robot fritzing diagram

Complete Fritzing diagram

Connect the MPU6050 to the Arduino first and test the connection using the codes in this IMU interfacing tutorial.  If data is now displayed on the serial monitor, you’re good to go! Proceed to connect the rest of the components as shown above.

The L298N module can provide the +5V needed by the Arduino as long as its input voltage is +7 V or greater.  However, I chose to have separate power sources for the motor and the circuit for isolation. Note that if you are planning to use a supply voltage of more than +12V for the L298N module, you need to remove the jumper just above the +12V input.

Building the Robot

Robot frame (made mostly of acrylic slab) with two geared dc motors

Main circuit board consisting of an Arduino Nano and MPU6050

arduino self balancing motor driver

L298N motor driver module

Geared DC motor with wheel

 

The self-balancing robot is essentially an inverted pendulum. It can be balanced better if the center of mass is higher relative to the wheel axles. A higher center of mass means a higher mass moment of inertia which corresponds to lower angular acceleration (slower fall). This is why I’ve placed the battery pack on top. The height of the robot, however, was chosen based on the availability of materials.

 

arduino self-balancing robot assembled

Completed self-balancing robot. At the top are six Ni-Cd batteries for powering the circuit board. In between the motors is a 9V battery for the motor driver.

 

More Self-balancing Theories

In control theory, keeping some variable (in this case, the position of the robot) steady needs a special controller called a PID: P for proportional, I for integral, and D for derivative. Each of these parameters has “gains” normally called Kp, Ki, and Kd.

PID provides correction between the desired value (or input) and the actual value (or output). The difference between the input and the output is called “error”. The PID controller reduces the error to the smallest value possible by continually adjusting the output. In our Arduino self-balancing robot, the input (which is the desired tilt, in degrees) is set by software. The MPU6050 reads the current tilt of the robot and feeds it to the PID algorithm which performs calculations to control the motor and keep the robot in the upright position.

PID requires that the gains Kp, Ki, and Kd values be “tuned” to optimal values. Engineers use software like MATLAB to compute these values automatically. Unfortunately, we can’t use MATLAB in our case because it would further complicate the project. We will tune the PID values manually instead. I’ve outlined the steps on how to do this:

    1. Make Kp, Ki, and Kd equal to zero.
    2. Adjust Kp. Too little Kp will make the robot fall over (not enough correction). Too much Kp will make the robot go back and forth wildly. A good enough Kp will make the robot slightly go back and forth (or oscillate a little).
    3. Once the Kp is set, adjust Kd. A good Kd value will lessen the oscillations until the robot is almost steady.  Also, the right amount of Kd will keep the robot standing even if pushed.
    4. Lastly, set the Ki. The robot will oscillate when turned on even if the Kp and Kd are set but will stabilize in time. The correct Ki value will shorten the time it takes for the robot to stabilize.

 

Arduino Self-balancing Robot Code

I needed four external libraries to make this Arduino self-balancing robot work. The PID library makes it easy to calculate the P, I, and D values. The LMotorController library is used for driving the two motors with the L298N module. The I2Cdev library and MPU6050_6_Axis_MotionApps20 library are for reading data from the MPU6050. You can download the code including the libraries in this repository.

#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 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

//PID
double originalSetpoint = 173;
double setpoint = originalSetpoint;
double movingAngleOffset = 0.1;
double input, output;

//adjust these values to fit your own design
double Kp = 50;   
double Kd = 1.4;
double Ki = 60;
PID pid(&input, &output, &setpoint, Kp, Ki, Kd, DIRECT);

double motorSpeedFactorLeft = 0.6;
double motorSpeedFactorRight = 0.5;
//MOTOR CONTROLLER
int ENA = 5;
int IN1 = 6;
int IN2 = 7;
int IN3 = 8;
int IN4 = 9;
int ENB = 10;
LMotorController motorController(ENA, IN1, IN2, ENB, IN3, IN4, motorSpeedFactorLeft, motorSpeedFactorRight);

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

 mpu.initialize();

 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
 mpu.setDMPEnabled(true);

 // enable Arduino interrupt detection
 attachInterrupt(0, dmpDataReady, RISING);
 mpuIntStatus = mpu.getIntStatus();

 // set our DMP Ready flag so the main loop() function knows it's okay to use it
 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);
 
 }

 // 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);
 input = ypr[1] * 180/M_PI + 180;
 }
}

My Kp, Ki, Kd values may or may not work you. If it doesn’t, then follow the steps I outlined above. Notice that the input tilt in my code is set to 173 degrees. You can change this value if you’d like but take note that this is the tilt angle to which the robot must be maintained.

Also, if your motors are too fast, you can adjust the motorSpeedFactorLeft and motorSpeedFactorRight values.

Video

Here’s the self-balancing robot in action!

What’s Next?

An improvement for this self-balancing robot would be controlling it remotely. Unfortunately, I can’t make this robot do that unless I make it ultra stable using dc motors with an encoder. An encoder would update the current speed of the motor which I can use to make the robot steadier via a second PID loop. I might do that next time so stay tuned!

 

Recommended Posts
Showing 89 comments
  • giback
    Reply

    Hello, I applied the source code you uploaded to Arduino Uno and compile a compile error. Please help me

  • Alex
    Reply

    Great Project! As I am following your guide and tune the PID, I find that no matter what value my Kp is, the robot will diverge (run away until it cannot catch and fall). I have tried increasing Kd as well, it does get rid of the oscillations but it stills fall as it runs away and cannot stay at one spot. Would you please give me some insight? Is it because my motors are not strong/fast enough?

  • Weskley
    Reply

    Congratulations on the project. It could help me because when the code is compiled the following error occurs:
    invalid preprocessing directive #se.
    And in the code select the line with the following code:
    # se I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE

  • The Boss
    Reply

    Hello, I did the editing, but my robot does not try to correct itself, as if he had an infinite error. In addition, the robot does not start in one direction and when you lean it in the other direction, it does not capture it. Thank you for helping me.

  • Edward
    Reply

    I have found this version with stepper motor drivers and …woah! Extremely fast and agile: https://www.youtube.com/watch?v=d6J0ijMG3jI
    I guess the fine tuning makes the difference and the stepper motors deliver enough power.

  • DINESH KUMAR GOUDA
    Reply

    Hello
    I have tried with arduino uno but its not working and the code is writing some error plz help in making this

  • poom
    Reply

    It’s waiting for interrupt i dont know how to fix it

  • shikor
    Reply

    library isn’t working, plzz give me valid library link that’s work

  • Harold Valega
    Reply

    Hello, the project is very well specified. I have only had a problem and it is with respect to the engines that in crazy times, when it starts the arduino work well and then after a while do not respond so fast or they stay spinning in one direction. If you could help me with this please I thank you.

    • Agastya
      Reply

      Same for me too

  • KASHIF MEHMOOD
    Reply

    I am a beginner working on Arduino Uno and i am looking for some mini projects that are not uploaded on google so i make some practice by myself,please send me some mini challenge project.

  • Remy
    Reply

    Hi,

    What RPM are the geared DC motors you are using?

    Great tutorial by the way!

  • Dan Urbauer
    Reply

    HI ROLAND,
    WHEN I TRY TO UPLOAD YOUR SKETCH FOR THE SELF BALANCING ROBOT I GET THIS LONG ERROR MESSAGE. DO YOU KNOW HOW TO FIX IT? I AM USING AN ARDUINO UNO CLONE.

    Arduino: 1.8.3 (Mac OS X), Board: “Arduino/Genuino Uno”

    WARNING: Spurious .mystools folder in ‘MySensors’ library
    In file included from /Users/danurbauer/Documents/Arduino/MY_SELF_BALANCING_ROBOT_BY_ROLAND_PELAYO_ARDUINO/MY_SELF_BALANCING_ROBOT_BY_ROLAND_PELAYO_ARDUINO.ino:7:0:
    /Users/danurbauer/Documents/Arduino/libraries/MPU6050/MPU6050_6Axis_MotionApps20.h: In member function ‘uint8_t MPU6050::dmpGetAccel(int32_t*, const uint8_t*)’:
    /Users/danurbauer/Documents/Arduino/libraries/MPU6050/MPU6050_6Axis_MotionApps20.h:580:31: warning: left shift count >= width of type
    data[0] = ((packet[28] << 24) + (packet[29] << 16) + (packet[30] <= width of type
    data[0] = ((packet[28] << 24) + (packet[29] << 16) + (packet[30] <= width of type
    data[1] = ((packet[32] << 24) + (packet[33] << 16) + (packet[34] <= width of type
    data[1] = ((packet[32] << 24) + (packet[33] << 16) + (packet[34] <= width of type
    data[2] = ((packet[36] << 24) + (packet[37] << 16) + (packet[38] <= width of type
    data[2] = ((packet[36] << 24) + (packet[37] << 16) + (packet[38] <= width of type
    data[0] = ((packet[0] << 24) + (packet[1] << 16) + (packet[2] <= width of type
    data[0] = ((packet[0] << 24) + (packet[1] << 16) + (packet[2] <= width of type
    data[1] = ((packet[4] << 24) + (packet[5] << 16) + (packet[6] <= width of type
    data[1] = ((packet[4] << 24) + (packet[5] << 16) + (packet[6] <= width of type
    data[2] = ((packet[8] << 24) + (packet[9] << 16) + (packet[10] <= width of type
    data[2] = ((packet[8] << 24) + (packet[9] << 16) + (packet[10] <= width of type
    data[3] = ((packet[12] << 24) + (packet[13] << 16) + (packet[14] <= width of type
    data[3] = ((packet[12] << 24) + (packet[13] << 16) + (packet[14] <= width of type
    data[0] = ((packet[16] << 24) + (packet[17] << 16) + (packet[18] <= width of type
    data[0] = ((packet[16] << 24) + (packet[17] << 16) + (packet[18] <= width of type
    data[1] = ((packet[20] << 24) + (packet[21] << 16) + (packet[22] <= width of type
    data[1] = ((packet[20] << 24) + (packet[21] << 16) + (packet[22] <= width of type
    data[2] = ((packet[24] << 24) + (packet[25] << 16) + (packet[26] <= width of type
    data[2] = ((packet[24] << 24) + (packet[25] << 16) + (packet[26] < Preferences.

    ANY HELP WOULD BE APPRECIATED
    DAN

  • Dan Urbauer
    Reply

    Hi Roland,

    Do you know where I can download this library: MPU6050_6Axis_MotionApps20.h; I can’t find it anywhere I look on the net. If it is included in another library, I don’t think the sketch you wrote will utilize it. When I tried to compile the sketch it stopped at the: MPU6050_6Axis_MotionApps20.h library, hence I’m unable to proceed with making the robot. I have all the hardware and the body, all I need now is the: MPU6050_6Axis_MotionApps20.h library. Any help you can give would be most appreciated.

    Dan

  • Sriker Ankem
    Reply

    how to stat the robot either have to place it down horizontally or vertically?

  • Sriker Ankem
    Reply

    how did placed mpu6050 horizontally or vertically

  • Doug
    Reply

    Robot is built and wired up. The code loads fine, but the wheels just continuously turn. Can you advise what might be the problem? Thanks

    • Raffael
      Reply

      Hello Doug,

      How did you execute the code?

      When I execute the code, shows:

      libraries/arduino-self-balancing-robot-master/MPU6050.cpp.o (symbol from plugin): In function `MPU6050::getSlaveAddress(unsigned char)’:
      (.text+0x0): multiple definition of `MPU6050::getSlaveAddress(unsigned char)’

      Thanks

    • Roland Pelayo
      Reply

      Hi Doug,

      Try reorientating the robot and find where it stops. If it do stop, then that’s the rest position. If it doesn’t stop no matter how you angle it, then there must be something wrong with the MPU6050. I suggest you connect the Arduino to the serial monitor and see the messages.

  • Raffael
    Reply

    Hello, the code show this:

    libraries/arduino-self-balancing-robot-master/MPU6050.cpp.o (symbol from plugin): In function `MPU6050::getSlaveAddress(unsigned char)’:
    (.text+0x0): multiple definition of `MPU6050::getSlaveAddress(unsigned char)’
    ….

    Why? Can you help me?

    Thanks

  • Allen
    Reply

    I’ve confirmed that my MPU6050 is working via the teapot airplane demo

    However, the wheels only drive forward at a constant speed regardless of orientation

    thoughts?

  • Ashish
    Reply

    Hello What are the specification of your motors like I am doing the same like your but my motors are 300 RPM (3-9 V DC) Single Shaft motors(L) so can I simply power motor driver with 9V if yes Would motors run perfectly and what about their torque and how long would they run
    Also in your Fritzing schematic AA battery supply( I assume it is 6V =1.5x4V) to 5V pin of Nano won’t this damage the Nano; as input is restricted to 5V for that particular pin or else should I use different pin like Vin?

  • Armando Garcia-Mendoza
    Reply

    Hello,
    One thing to mention as others that may find this issue,
    at least my MPU6050 was not working until I put to GND the ADO pin.

  • Yuvpreet Singh
    Reply

    Sir please tell me.. how to make this model a wireless ? which components should i use to make this robo go forward reverse righ and left

  • Qiyty
    Reply

    Hi,
    Actually, I don’t understand this part:
    mpu.setXGyroOffset(220);
    mpu.setYGyroOffset(76);
    mpu.setZGyroOffset(-85);
    mpu.setZAccelOffset(1788);

    How can we set these parameters?
    Thanks for your help!

  • satyam keshri
    Reply

    sir,I need help from starting,I need circuit diagram .
    Thanku

  • Dan Urbauer
    Reply

    Hi Roland,

    I have been having great difficulty finding the “LMotorController” library to download so I can add it to my Arduino libraries. Can you give me a link or tell me how to find it. All I am able to find are the LMotorController.h and LMotorController.ccp files. Can you help me? Any help would be much appreciated.

    Dan

    • KenV
      Reply

      Those two files are the entire LMotorController library, they just need to be saved in the right place.

      The easiest approach is to follow the link in the article above (https://github.com/kurimawxx00/arduino-self-balancing-robot). Click the green button on the right side of the page labeled “Clone or Download”, then select “Download ZIP”. Save the zip file in any convenient location. Then, from the Arduino IDE, select “Sketch”, “Import Library”, “Add Library…” and give it the location of your zip file. Now all the needed libraries are installed in their correct places.

  • Myu
    Reply

    Hey,
    Can you tell me how to calibrate the mpu? I mean we have to insert the initial balanced points right?

  • yanwar eko
    Reply

    HI, im already do this tutorial and use the code . but got problem the rotation of motor is to slow. can you teach me what the problem ? thanks

  • KenV
    Reply

    I inadvertently laid out my MPU6050 with the x-axis pointing along the wheel axles, rather than straight forward. Rather than re-wire my board, I simply changed the line input = ypr[1] * 180/M_PI + 180
    to: input = ypr[2] * 180/M_PI + 180
    But it doesn’t seem to want to stabilize. Is there something going on with the gravity vector as well? Is it fixable, or should I just re-wire?

    I wish this had been clearer in the article!

    • KenV
      Reply

      To answer my own question… it’s not enough to just use ypr[2] (i.e. pitch) instead of ypr[1] (i.e. roll) in this part of the code. The entire MPU6050 had to be rotated 90 degrees before it would stabilize, because there are other routines that also use its output, and assume a particular orientation.

  • Arsh Raj
    Reply

    HI , can you plz send me the connection digram of the self balancing robot with arduino uno . my gmail is [email protected]

  • Aditya
    Reply

    my circuit is connected properly but the motor is not even starting :( can u pls help me and could u also pls specify which between the yellow and green wire is +ve and -ve

    • KenV
      Reply

      I had the same problem until I connected the ground terminal on the L298N module to the ground pin on the Arduino – in other words, connecting the negative terminals of the two batteries. If you’re using two separate power sources, this is a must!

      Green vs. yellow for +ve and -ve doesn’t matter, as long as they’re consistent. The motors will spin in whatever direction they need.

      • MrC
        Reply

        This worked for me thanks!

    • Yanwar Eko
      Reply

      hi , i had same problem, but i already try connected the ground therminal of the battry and arduino, but the motor spin is to slow :(

      • Roland Pelayo
        Reply

        Hi,

        Are your batteries full? the L298N needs at least 2 A to drive the motors.

  • cholisz
    Reply

    i have error program “LMotorContoller does note name a type”
    need answred..

    • Roland Pelayo
      Reply

      Hi,

      Have you added the LMotorController library? That must be the reason

  • Yanwar Eko
    Reply

    Hello, i got some problem here, the l298 not work properly ,motor rotation work to slow, but when i remove not to use enable (use jamper for ENA and ENB) the motor rotation work properly , can you help me, please

    • Roland Pelayo
      Reply

      Hello,

      That looks like a power problem. Did you use separate power supply for your motors?

  • saifuddin
    Reply

    i use same material and same code like yours but its still not working properly when i turn it on it is going on any single direction please suggest this is for my daughter i have to complete this

    • Roland Pelayo
      Reply

      Hi,

      Is the MPU6050 working properly? What exactly do you mean by going on any single direction? Does it fall over the entire time?

      • Saifuddin
        Reply

        Mpu6050 is working properly and yes it is fall over the entire time

  • Dharmender
    Reply

    I am getting these errors while I compile the code without connecting any hardware.

    In file included from D:\self_balancing_attempts\diy\arduino-self-balancing-robot-master\arduino-self-balancing-robot-master\AmBOT_final_nano\AmBOT_final_nano.ino:4:0:

    C:\Users\Dharmender\Documents\Arduino\libraries\arduino-self-balancing-robot-master/MPU6050_6Axis_MotionApps20.h: In member function ‘uint8_t MPU6050::dmpGetAccel(int32_t*, const uint8_t*)’:

    C:\Users\Dharmender\Documents\Arduino\libraries\arduino-self-balancing-robot-master/MPU6050_6Axis_MotionApps20.h:580:31: warning: left shift count >= width of type

    data[0] = ((packet[28] << 24) + (packet[29] << 16) + (packet[30] << 8) + packet[31]);

  • Gabi
    Reply

    Hi,

    can you explain please why output is not calculated while input is (input = ypr[1] * 180/M_PI + 180;). My robot doesnot work properly so I println the output value, which is -255 all the time and I think that s the problem

    • Roland Pelayo
      Reply

      Hello,

      maybe your MPU6050 is not working properly? Kindly check its output values using the serial monitor.

  • Rino
    Reply

    hi dude, can i use adxl345 instead of mpu? with same configuration like u write down in this article, thanks anyway

    • Roland Pelayo
      Reply

      Hi,

      Sadly, the ADXL345 is accelerometer only. You need a gyroscope and accelerometer for this project.

      • Rino
        Reply

        Ok then, i will use mpu
        Btw do u have the vector of this acrilyc design? If u wouldn’t mind can u email me that design at [email protected]
        And one more question, so i use 4 AA battery for circuit supply or 6 AA battery?

        • Roland Pelayo
          Reply

          Sadly, I don’t have any design file right now. But I will build one and would be sending it to you as soon as possible. And yeah, 4 AA battery should be used to have 4.8V (if rechargeable) or 6V (if non-rechargeable).

          • Rino
            Reply

            why serial monitor stuck at “DMP ready! Waiting for first interrupt…”

            i used arduino nano and already connect INT to Digital pin 2

  • Unnyb
    Reply

    I am using mpu6050, it works properly with mpu6050 eg code…. But unfortunately with your code My mpu6050 is still waiting for interrupt….. It won’t start….. How can I rectify …. Please help me

    • Roland Pelayo
      Reply

      Hi,

      Which arduino board are you using? It may be an issue with your arduino and not on the MPU6050

      • Yiv
        Reply

        I’m using Arduino UNO, I meet the same problem, it shows: DMP ready! Waiting for first interrupt…
        And my robot cannot keep balanced, it runs so quickly without changing directions or speech, how can I solve it?
        Pls help me, thanks so much!

  • sanjay
    Reply

    can we use arduino uno

    • sanjay
      Reply

      can we use the same codes for arduino uno with correct pinnumber

      • Roland Pelayo
        Reply

        Yes you can! :) The UNO and the Nano have the same pin numbers as far as coding is concerned

  • Abhishek Chheda
    Reply

    hii.. I am a student and has taken this task of building self balancing robot as my final year project. I am from mechanical background and don’t know much about this field.
    Would you please tell me what all basics is required to learn before I start building this robot.

    • Roland Pelayo
      Reply

      Hi! I suggest you read about microcontroller programming first :) you can also learn basic electronics at allaboutcircuits.com

  • Bryan
    Reply

    Did you upgrade to motors with encoders and add an extra PID loop for a controllable balance bot?

    • Roland Pelayo
      Reply

      I am currently working on it :)

  • SHYAM Kishor Kumar
    Reply

    HI,
    can you please explain me these lines of code.
    1. double motorSpeedFactorLeft = 0.6;
    2. double motorSpeedFactorRight = 0.5;
    3. LMotorController motorController(ENA, IN1, IN2, ENB, IN3, IN4, motorSpeedFactorLeft, motorSpeedFactorRight);
    4. double originalSetpoint = 173;// how do we check and set this value.
    5. double setpoint = originalSetpoint;
    6. double movingAngleOffset = 0.1;
    7. double input, output;

    • Roland Pelayo
      Reply

      Hello,
      the motorSpeedFactor constants are used to fine tune the speed of the motor. You see that they are not equal because my motors do not turn at the same speed even if they are physically the same. Line 3 on that code is how you would create a LMotorController object with the L293D pins and motorSpeedFactor constants as parameter. Line 4 meanwhile is dependent on your robot. I found that at 173 degrees, my robot is much more balanced compared to the “standard” 180 degrees (which is when the gyroscope is perfectly flat with respect to the horizontal). Then you need to assign that angle to the setpoint variable used for PID tuning. movingAngleOffset is a constant which means you can tolerate + or minus 0.1 degrees from 173 degrees. Input and output are variables used for PID tuning. I hope I answered your question.

  • serge28
    Reply

    sorry to say it but your sketch look incomplet ! even it look interresting.

    there is not any lines for the comparison with input MPU values and the setpoint !
    neither any “void” for the motorpowering !
    i’m maybe wrong, but when i tryed, nothing happen when i turn on the sketch on my own robot.

    PS forgive my not perfect english, i’m french

    • Roland Pelayo
      Reply

      Hi,

      The comparison is done in the line where you can find pid.compute(). This is all you need since the PID object has been instantiated (in the line where you find PID pid(&input, &output, &setpoint, Kp, Ki, Kd, DIRECT);) The motor powering is found right below to the pid.compute() line where you can see motorController.move(output, MIN_ABS_SPEED);

      • serge28
        Reply

        thank you for your reply… so i have to look for still why nothing happen when i turn on.
        Serge

  • Cristian
    Reply

    Hello, I am actually getting a lot of errores when i compile. One exit status errores, more specifically. How can i fix it? Or, what am I doing wrong?

    • Roland Pelayo
      Reply

      Can you give more details please? Did you use the same code and arduino board? did you use the same IMU?

      • Cristian
        Reply

        Of course, sorry. I actually used an arduino Uno. I have everything connected as it should. Now, what’s happening, is that it doesn’t receive interrupts. Thank you so much.

        • Roland Pelayo
          Reply

          Sorry but it’s hard to answer your problem without me looking at your circuit. But if you are using the same circuit and code, the only thing I can suggest is to check for improper connections.

  • Thai Binh
    Reply

    Thanks for helpful post. Could you pls explain about the setpoint (or input) is 173?. I thought it must be zero degree for robot steady in vertical position, isn’t it? And what did you mean when adding 180 into conversion to degree of pitch (input) variable? I am newbie on Adruino projects. Pls help me.

    • Roland Pelayo
      Reply

      Hi, my MPU6050 is placed flat which means its angle in the x-axis (pitch) is 0 or 180 degrees ideally. But I found that 173 degrees is much more stable so I used that. Also, I used 180 (hence + 180 on the formula you pointed at) instead of zero because I would like to avoid negative values for the PID computation.

      • Thai Binh
        Reply

        Got it. Many thanks for your explainng!

        • Shyam Kishor Kumar
          Reply

          On what basing we are trying to stable the Robot is it the Yaw pitch roll or the X Y Z axes.

          • Roland Pelayo
            Reply

            I’m using pitch or rotation on the x-axes.

  • Ali
    Reply

    One of the best guides I’ve seen for self balancing robots! Thank you for the well written tutorial!

    • Roland Pelayo
      Reply

      Thanks :)

  • Colden
    Reply

    Being very new to the DIY community of electronics and robotics, is there a specific material list for this? Something that goes into detail if the jumper wires are male to male or varied. Is there a link that you could find for headers (Im not sure what these are). Is there also a more detailed tutorial that explains your building process?

  • Colden
    Reply

    Would you happen to remember where you bought those platforms for this project? I am having trouble finding platforms like those in your images and videos.

  • Adam Gray
    Reply

    Can you give me code of MPU6050 library? Thank you verymuch. my email: [email protected]

Leave a Comment

75 − = 74

Start typing and press Enter to search