Mohammed Shabaj Ahmed
2019-08-14
This instructable will go through the design and build process for a self-balancing robot.
As a note, I just want to say that self-balancing robots are not a new concept and they have been built and documented by others. I want to use this opportunity to share with you my interpretation of this robot.
A self-balancing robot is a system that uses inertial measurement data, gathered from an onboard sensor, to continuously adjust its position to keep upright.
A simple analogy to consider is an inverted pendulum, where the centre of mass is above the pivot point. However, in our case, we are restricting the pendulum to one degree of freedom by having one axis of rotation—the axis of the two wheels.
Since any disturbance will cause the robot to fall, we need a method of actively keeping it balanced. This is where our closed-loop algorithm (PID controller) comes into play. Knowing which direction our robot is falling, we can adjust the direction of rotation of our motors to keep the system balanced.
The basic principle is: if the robot is falling forward, it will compensate by moving forward to catch itself; if falling backward, it will move backward.
So, we need to do two things:
We'll use an Inertial Measurement Unit (IMU), specifically the MPU-6050, which includes:
Sensor drawbacks:
For this instructable, we'll use the onboard Digital Motion Processing (DMP) of the MPU-6050. Others may use a complementary filter—either works.
Parts:
Tools:
I 3D printed the chassis and used standoffs to assemble the robot, which consists of 4 layers:
Design Principle: Keep everything modular for easy replacement and reusability.
Download the STL files and code from GitHub.
I soldered female headers to the perf-board to match the Arduino. Then I soldered male headers for I/O access. Components were mounted to the 3D printed frame and connected via jumper wires.
To balance the robot, we use a PID controller:
Algorithm Summary:
P + I + D
.Use this calibration script by Luis Rodenas to calculate and set offset values in setup()
.
What is DMP?
An onboard processor that fuses motion data from the gyroscope and accelerometer.
How to use DMP?
Use the example sketch:File → Examples → MPU6050 → MPU6050_DMP6
I used Arduino IDE and FTDI adapter to program the Arduino Pro Mini.
Base code: MPU6050_DMP6
example sketch
Additions: PID()
and MotorDriver()
functions
Wire.h
MPU6050
I2Cdev.h
// Include Libraries #include <Wire.h> #include <I2Cdev.h> #include <MPU6050.h> // Initialise variables and objects void setup() { // Set pinModes for motors and LED // Initialise MPU6050 and set offsets } void PID() { // Calculate PID output } void MotorDriver(float pid_output) { // Drive motors using PID result } void loop() { // Get data from DMP PID(); MotorDriver(); }
The full source code is available onGitHub
If tuning fails, start over with a new P value. Each system may need vastly different PID values.
The motors were too slow to respond to disturbances, and the system lacked inertia. As a result, the robot would lean and roll instead of balancing. The 3D printed wheels lacked traction and would slip.