Building a Self Balancing Robot

This is an advance project to make a two-wheel self balancing robot. Email parts@robotsforfun.com to get the parts for this project.

Before you attempt to do this, you need to first know how to control two DC motors using the L293D H-bridge to make the robot move forward and backward, and how to get the tilt angle readings from the MPU6050 gyroscope.

Parts needed:
  • Arduino Nano or Arduino Pro Mini (Using the Arduino Uno is alright but it's better to use the smaller form factor Nano or Mini)
  • GY-521 Gyroscope and accelerometer MPU6050
  • L293D H-bridge chip
  • Two DC motors
  • Two wheels
  • Two 3.7V Li-ion rechargeable batteries
  • A battery holder for the two batteries
  • On/off switch
  • Wires
  • A small suitable "U" frame for the robot body. The top of the "U" frame should be flat, level, and wide enough to put the battery holder. Something like a tin can would work!
  • If you have a 3-D printer, you can also print out this custom 3-D frame.
  • Soldering iron
self balancing robot
self balancing robot
1 Building the physical robot.

Mount the two DC motors and wheels to the bottom of the "U" frame. Make sure that they are straight.

Mount the battery holder and the GY-521 gyroscope on the top of the "U" frame. The placement of the battery and the gyroscope is very important.

  • First, since the battery is the heaviest component in the robot, you want to place it on the top in the center so that the weight is balanced.
  • Second, you must mount the gyroscope very level, straight, flat with the component side facing up, and doesn't wiggle or move around. Place the gyroscope so that the black chip on the gyroscope is centered with the wheel axis. The X axis of the gyroscope must be parallel to the wheel axis and the INT pin on the board towards the front of the robot. If you mount the gyroscope in a different orientation then you will have to modify the code to get the correct angles.

Find convenient locations to put the Arduino, the L293D chip, and the on/off switch. Place the Arudino in such a way that allows easy access and programming of the Arduino because you will be repeatedly programming the Arduino when making adjustments for the robot to balance. Don't tape it down yet. Do this after you have solder all the wire connections in step 2 below.

self balancing robot
self balancing robot
2 Connecting the wires.

Make the following wire connections. Try to be clean and neat, and cut the wires as short as possible.

  1. GY-521 gyroscope
    MPUArduino
    SCLA5
    SDAA4
    INT2
    VCC5V
    GNDGND
  2. L293D DC motor driver chip
    L293DDescriptionArduinoMotorBattery
    pin 2input 110 
    pin 7input 211 
    pin 10input 36 
    pin 15input 45 
    pins 3 & 6output 1 & 2motor 1 
    pins 11 & 14output 3 & 4motor 2 
    pin 8VCC 2+ 7.4V
    pin 16VCC 15V
    pin 4, 5, 12, or 13GNDGNDnegative (black)
3 Controlling the two DC motors.

If you don't know how to control two DC motors using the L293D H-Bridge you should read this first..

To make a motor turn we issue two analogWrite commands to the two input pins for the motor. If the two values in the analogWrite commands are both zero then the motor will stop. If one value is zero and the other is a positive number between 1 and 255, then the motor will turn in one direction. Of course the value has to be big enough to provide enough power to turn on the motor. The bigger the number the faster the motor will turn.

Determine the values for the analogWrite commands in order to make the robot go forward and backward. Fill in the table on the right so that you remember them. You will need to modify the code with these settings in step 6 below.

Robot movement in1Pin value in2Pin value in3Pin value in4Pin value
stop        
go forward        
go backward        
4 Gyroscope MPU6050 library.

If you don't know how to get the readings from the gyroscope you should read this first.

If you have not already done so, download and install this MPU6050_RobotsForFun library. This is the code for interfacing with the gyroscope and getting the tilt angles of the robot.

5 Proportional-Integral-Derivative (PID) library.

Download and install this PID libaray.

This is the code based on the formula shown on the right for calculating the correction values (Output) needed for the robot to stay balanced when given the tilt angle (Input). There are four values (Setpoint, Kp, Ki, and Kd) in the code that need to be adjusted in order for the calculations to work correctly and have the robot balanced.

  • Setpoint is the angle at which the robot is upright. It should be 180 if everything is mounted perfectly. But since things are never perfect, it will be a little bit off from 180.
  • Kp determines how aggressively the PID reacts to the current amount of error (Proportional) (double >=0).
  • Ki determines how aggressively the PID reacts to error over time (Integral) (double>=0).
  • Kd determines how aggressively the PID reacts to the change in error (Derivative) (double>=0).

Look here for a short introduction on what PID is and the PID library. Look here if you're interested in learning the details of the math and the code. There's a lot of advanced math and coding involved in the calculations, but this is definitely a good read and relatively easy to understand if you want to understand the full picture.





PID Formula
6 Program.

From the Arduino IDE menu, select File | Examples | MPU6050_RobotsForFun | selfBalancingRobot

Make sure the values in the analogWrite commands in the goForward() and goBackward() functions are set correctly based on what you have obtained in step 3 above.

Hold the robot upright and steady.

Upload and run the program, or press the reset button if you have already uploaded the program.

If everything is adjusted correctly, the robot will stay upright and balanced. It will not stay fixed but will move a little.

7 Adjustments.

If the robot does not balance (which most likely will be the case) then you'll have to adjust the setpoint, Kp, Kd, and Ki values in the code. Follow the instructions below and in the code to adjust these values.

  1. Make sure that you are getting meaningful X-axis readings from the gyroscope. This is the pidInput value being printed on the Serial Monitor. When you tilt the robot along the X-axis (i.e. the wheel axis) the angle should decrease in one direction and increase in the other direction. It should be 180 or close to 180 when the robot is perfectly upright. If not, you need to fix your gyroscope.
  2. Change the setpoint value in the code to the angle that you get when the robot is perfectly upright.
  3. Make sure that the robot is moving in the correct direction when it is tilted. When it is tilted forward it should go forward, and when it is tilted backward it should go backward. If it is not, you need to make sure your goForward() and goBackward() routines are correct. Then check the two direction tests in the loop() routine and make sure they are correct.
  4. Set both Kd and Ki to zero. Adjust the Kp value so that the robot doesn't fall over and doesn't oscillate back and forth too much as shown in the two videos on the right. A good Kp will make the robot not fall over and oscillate just slightly back and forth.
  5. 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.
  6. 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.


When Kp is too small, the robot cannot stand up.


When Kp is too large, the robot oscillates back and forth too much.