Arduino Self Balancing Robot




Introduction: Arduino Self Balancing Robot

About: Now retired but have a passion for robot design and construction. Also enjoy programming, my career was largely commercial programming and design work using Cobol, Fortan, and industrial automation and integra…

Ardunio Self Balancing Robot Project Date: July 2018

Project Equipment:

· 18650 Battery Holder (holds 3 x batteries)

· 3 X 18650 2100mA batteries

· Arduino Uno R2 (Running a PID Proportional–Integral–Derivative motor control sketch)

· MPU-6050 3-axis gyroscope and accelerometer

· L298N Dual Bridge DC Stepper Motor Driver

· 2 X N20 DC 100RPM Geared Motor with press fit Rubber Tires

· 3 X 0.75mm Brass Sheet, 140mm X 80mm

· M2 Brass Stand-off / Screw / nut & bolt kit

· Male/Female Jumper Wires & 1mm wire (50cm)

· Two-Pole Power switch


This is my first project to be published on the Instructables site. It is the first version of this robot with subsequent versions having Bluetooth control, via an Android App which I will be developing on Android Studio, IR sensors for object detection and LCD display.

My philosophy when building robots is to ensure that they not only work in the way required but also that they look aesthetically correct with clean lines and good construction methods. I used a number of internet-based resources both for the electronics and Arduino code and for that I offer my thanks to those contributors.

The choice of the 18650 batteries was based on their power rating and ease of obtaining good quality second hand batteries usually from old laptops. The Arduino board is a standard clone, as is the L298N Dual Bridge motor controller. The N20 DC motors are adequate for the project but I felt that larger 6V DC motors with direct drive would perform better, this being a possible future upgrade to the project.

The basic construction consisted of three 140mmX80mm 0.75mm brass rectangles with holes drilled for the M2 stand-offs, holes for the L298N, MPU-6050, and Arduino Uno supports and four 2mm holes to attach the N20 motor supports. I added two out riders to catch the robot should it topple over, these had the added advantage in that they provided a stand for the robot, while it was switched off, and which the robot could start from when switched on. While the jumper wires were adequate, I have found that the connections are weak and that fully soldered connections are better, such as those to the MPU-6050.

Step 1: Fritzing Diagram

Fritzing Wiring Diagram:

The attached Fritzing diagram shows the various connections from the batteries, via the two-pole switch, to the Arduino Uno. From the Arduino Uno to the MPU-6050 and to the L298N Motor Driver and finally from the L298N to the N20 DC motors.

Step 2: Construction


Construction started with the 3 brass plates cut to size, drilled at all four corners, and mounting holes for both the Arduino Uno, MPU-6050 and L298 motor driver. Using 10mm stand-offs the MPU-6050, Arduino Uno, and L298 motor driver where attached and wired as per the above diagram. The N20 DC motors where mounted on the bottom plate using four drilled holes and four M1 bolts and nuts. After being soldered each motor’s wires where connected to the left and right connectors of the L298 motor driver. The L298 motor driver jumper was installed so that a 5V supply could be provided for the Arduino Uno board. Next the 18650 battery holder was glued to the top plate and wired through a two-pole switch to the 12V and Ground inputs of the L298 motor driver. Rubber tube was attached to the top plate to help protect the robot as was the two out-riders which where attached to the bottom plate. Finally, the MPU-6050 was mounted separately onto the middle plate, this and all other components where mounted on the center line of the robot’s X axis.


I have included the Arduino source code which will require adjustments to the following parameters:

· OriginalSetpoint (Place all components on the center line, this helps with a nearly vertical value of 180 degrees plus or minus ½ a degree, current value 180.28).

· MovingAngle Offset (Unchanged at 0.1)

· Kp (Originally 0, current value 50)

· Kd (Originally 0, current value 2.2)

· Ki (Originally 0, current value 270)

· MotorSpeedFactorLeft (Originally 1, current value 0.61)

· MotorSpeedFactorRight (Originally 1, current value 0.47)

All the Kp, Kd, and Ki values have been adjusted using numerous evaluations of the robot’s movements. During this phase it was important to always start the robot in the same position and orientation. The Motor Speed factor for the left and right motor, it is important to determine early which motor is the left motor and which is the right motor looking at the “front” of the robot. It is also important to determine early which orientation of the MPU-6050 the device is in as this dictates which of the X or Y values the PID calculation is to use. Once determined I marked the bottom of the robot with which direction the greater than 180 degrees and less than 180 degrees directions where, again this helped with determining the Kp, Kd, and Ki values. Sampling was kept to 10ms and minimum motor speed set at 30. The final set of parameters deal with the Gyroscopic and Acceleration default values for the MPU-6050. A calibration program is required which provides these values for the MPU-6050 I was using. The following are the values the calibration program generated:

· setXGyroOffset = 65

· setYGyroOffset = -13

· setZGyroOffset = -14

· setZAccelOffset = 1554

Source Coding:

Using the Arduino 1.8.5 development software the following program was modified and then downloaded to the Arduino Uno board via a USB connection. It was necessary to find and download the following library files:

· PID_v1.h

· LMotorController.h

· I2Cdev.h

· MPU6050_6Axis_MotionApps20.h

· Wire.h

(All of these files are available from the web site)

Step 3: Arduino Sketch

Arduino Sketch:

The attached Arduino Sketch contains the full program. This is version two as the original version was without the LCD display and parameters adjustment. My thanks to the original authors of the PID parts of the software.

The main problem with interfacing the LCD was the use of interrupts by the MPU6050 Module 3 Axis analog gyro sensors+ 3 Axis Accelerometer Module. Inclusion of the LCD display code caused the MPU6050 module to either stop working or return invalid results.

The modified code allows the user to interrupt the sketch by pressing the SELECT button, pressing the SELECT button again returns control to the program, it was however necessary to rerun part of the MPU setup routine in order that the robot re-started correctly. Once in the adjustment function the user can press the LEFT and RIGHT buttons to cycle through the available parameters, SetPoint angle, Kp, Kd, and Ki. While any one of these parameters are displayed the user can press the UP and DOWN button to either add values to or remove values from the displayed parameter. In the case of the SetPoint and Kd the increment is 0.1, for the Kp and Ki parameters the increment is 1.

Step 4: What I Learned and What's Next for the Robot

I used the calibration script provided at the following link:

Arduino Self Balancing Article

All of the above parameters are fed into the PID. A good starting point for me was the Arduino site: PID Motor Controller Reviewwhere many very good reference articles are provided. There are also many very good “You Tube” videos to watch. I also found the following a great help and thank the article’s author Self Balancing Robot

For an in depth understanding of how a PID feedback system works I found the following link very useful Wikipedia PID Review

What I have learned:

This is not my first Arduino based robot, I have developed line tracking, obstacle avoidance, remote control via WIFI and Android, servo-controlled camera, and optical motor control, however this was and still remains the most complicated robot to set-up with having no less than 13 parameters to set before I stable balancing robot is achieved. While test connection can be made using the standard jumpers it is best to solder all connections as loose connections, especially to the motors, can cause problems with calibration of the robot. As the PID motor controller was being used to provide correction to an “inverted Pendulum” I felt that the heaviest part of the robot needed to be the top, rather than placing the heavy batteries at the bottom of the robot which makes the PID process of correction easier. The attached video shows the robot in action.

What’s next:

This platform is now ready to be enhanced with obstacle avoidance, LCD display, and Bluetooth Android control. The Bluetooth control requires the development of an Android App, using Android Studio, which is another part of the development process which I enjoy.

UPDATE: The LCD has been added to the robot, however the obstacle avoidance and Bluetooth control would be difficult to add due to the use of interrupts by the MPU6050 and will therefore be included into the next project.

Thanks for taking the time to read this article, and once again thanks to all those people whose articles helped me make this robot a reality.

Christine Thompson

Be the First to Share


    • Origami Speed Challenge

      Origami Speed Challenge
    • Science Fair Challenge

      Science Fair Challenge
    • Trash to Treasure Contest

      Trash to Treasure Contest



    1 year ago

    Hi; I am looking to make this project. The issue is that the article refers to the pre-LCD version, but the photos and code are for the v2 version. Has anyone else made the v1 version without the LCD? I am looking for the v1 code. Is there an updated circuit diagram, including the LCD? Has anyone been able to add directional control? I as thinking of a simple RC setup?


    Reply 1 year ago

    Hi, I have looked through my files and cannot find a V1 version for this project. I suspect I just updated the V1 file to V2. Examining the code on V2 the LCD screen and associated control buttons where added to the V1 version to allow easy adjustments of the parameters. Without this screen and control buttons you would need to either always have the USB cable attached or employ a WIFI/ Bluetooth communications system to allow you to adjust the parameters. I did not want to proceed with this project in this way. If you remove all references to the LCD and its control buttons you should a version of the code very close to the original V1.


    Reply 1 year ago

    Thanks for the reply. I have found a similar project that is using 3 pots to adjust the K-values, so will try that. Have you published the wiring diagram for the LCD version?


    1 year ago

    Anyone else notice that the L298N pin assignments are reversed between the Frizzing and the actual code?


    Reply 1 year ago

    Hi, thanks for spotting that. I looked at the code and the Fritzing diagram and the connections are indeed reversed. The code, lines 94 through 99 are correct and match the physical connections on the robot. The Fritzing diagram is a poor one as the PCB markings are covered by the connector lines. Please ensure the PCB markings on the L298N board you are using match up to ENA-Pin5, IN1-Pin6, IN2-Pin7, IN3-Pin8, IN4-Pin9 and ENB-Pin10, (this is on a Arduino Uno).


    2 years ago

    nice work buddy , am on the same boat you were a couple years back. I set my setpoint to183 as it seems most stable, i then made kp,ki,kd all zero and started with kp slowly increasing its value and according to this video ( he says when u get the correct KP the robot almost balances itself already but ive gone upto 75 and it does balance just for a second and then starts running away just to fall front or back, i leftthe kp at 75 and then started with KD and gradually incresed it upto 2.5 so as to keep the jitter to a minimum , now moving to the ki I started with 0.5 and it is now at 10 and i do not find any difference , it does balance for a couple of seconds at most and then keeps accelerating rapidly to fall on either side, I would like to know from you some more tips , like if using a esp32 for fatser calculation helps, how high should i make this thing for the best stability and by the way I use the cheap dc gear motors on mine, any other values that i need to consider apart from setpoint, kp, ki, kd. Thanks a ton buddy


    3 years ago on Step 4

    Hi I am new one on this research. can you explain why do we need these:
    double originalSetpoint = 180.10; //180.28
    double setpoint = originalSetpoint;
    double movingAngleOffset = 0.1;
    double input, output;
    //adjust these values to fit your own design
    double Kp = 20; //50
    double Kd = 2.2; //2.2
    double Ki = 270; //270

    And where can we find those values?


    Reply 3 years ago

    The Kp, Kd, and Ki settings are different for each robot, have a look at this article

    The values also depend on the position of the MPU 6050 unit, start with the default values, then adjust each using small increments to see if there is any improvement. Also I found a couple of You Tube videos that help with the initial settings.


    Reply 3 years ago

    I one more question, how u know the value of setpoint?


    3 years ago

    Very nice project.

    DIY Hacks and How Tos

    Cool Robot. If you want to make the video easier for people to view, you can upload it to Youtube and then embed it on the page using the Embed Video tool in the step editor. This will let people watch the video on the page without having to download it.