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