Control Systems Project Report
Control Systems Project Report
Submitted to :
Engr. Mam Maira Naz
Submitted by :
Arzah Saeed 2017-UET-IEFR-FD-ELECT-01
Mah-E-Hira 2017-UET-IEFR-FD-ELECT-04
Self-Balancing Robot
Preface:
Our project provides complete information on the topic “Self Balancing Robot” and
maximum effort have been taken to make project more comprehensive and lucid to
understand. Our project covers a variety of sub topics like its working ,setup, coding, wiring
and different aspects of Self Balancing Robot.
Index:
Introduction
Components
Circuit diagram
Working
Uses of Laser security alarm system
Advantages of Laser security alarm system
Conclusion
Introduction:
This Self Balancing Robot is a Two-wheeled Robot that balances vertically using a closed-
loop algorithm. This Self Balancing Robot Features various modes like Position Hold, Simple
Mode, Rise Mode and Joystick Control. This Robot is controllable by a Transmitter. Self
Balancing robot uses data from the Accelerometer and Gyroscope to correct its orientation
and position.
Components:
Arduino UNO
Geared DC motors (Yellow coloured) – 2Nos
L298N Motor Driver Module
MPU6050
A pair of wheels
7.4V Li-ion Battery
Connecting wires
3D Printed Body
Controller: The controller that we have used here is Arduino UNO, why because it is
simply easy to use. We can also use a Arduino UNO since we can program it directly without
any external hardware.
Motors: The best choice of motor that we can use for a self balancing robot, without a doubt
will be Stepper motor. But To keep things simple We have used a DC gear motor. Yes it is
not mandatory to have a stepper; the bot works fine with these cheap commonly available
yellow coloured DC gear motors as well.
Motor Driver: we have selected the DC gear motors. We can either use the L298N driver
module like me, or even a L293D should work just fine. Learn more about controlling DC
motor using L293D and Arduino.
Wheels: Our wheels have good grip over the floor we are using. Watch closely, the grip
should never allow wheels to skit on the floor.
Accelerometer and Gyroscope: The best choice of Accelerometer and Gyroscope for our
bot will be the MPU6050.
Battery: We need a battery that is as light as possible and the operating voltage should be
more than 5V so that we can power our Arduino directly without a boost module. So the ideal
choice will be a 7.4V Li-polymer battery. Here, since I had a 7.4V Li-ion battery readily
available We have used it. But remember a Li-po is advantageous than Li-ion.
Chassis: Another place where we should not compromise is with wer bots chassis. We can
use cardboard, wood, plastic anything that we are good with. But, just make sure the chassis
is sturdy and should not wiggle when the bot is trying to balance. We have designed by own
chassis on Solidworks inferring from the other bots and 3D printed it. If we have a printer
then we can also print the design, the design files will be attached in the upcoming heading.
The parts have no overhanging structures so we can easily print them without any supports
and an infill of 25% will work fine. The designs are pretty plain and any basic printer should
be able to handle it with ease. We used the Cura software to slice the model and printed using
our Tevo Tarantula, the setting are shown below.
We would have to print the body part as well as four motor mounting parts. The assembling
is pretty straight forward; use 3mm nuts and bolts to secure the motor and boards in place.
After assembling it should look something like this shown in the picture below.
The actual design was planned with the L298N drive module in the bottom rack the Arduino
and battery on top of it as shown above. If we are following the same order we can directly
screw the board trough the holes provided and use a wire tag for the Li-po battery. This
arrangement should also work, except for the super plain wheels which we had to change
later.
In our bot we have swapped the position of battery and Arduino UNO board for ease of
programming and also had to introduce a perf board for completing the connections. So our
bot did not look as I planned in initial stage. After completing the wiring programming
testing and everything, our bot finally looks like this
Circuit Diagram
Making the connections for this Arduino based Self balancing Robot is pretty simple. We
just have to interface the MPU6050 with Arduino and connect the motors though the Motor
driver module. The whole set-up is powered by the 7.4V li-ion battery. The circuit diagram
for the same is shown below.
Experimental setup:
The Arduino and the L298N Motor driver module is directly powered through the Vin pin
and the 12V terminal respectively. The on-board regulator on the Arduino board will convert
the input 7.4V to 5V and the ATmega IC and MPU6050 will be powered by it. The DC
motors can run from voltage 5V to 12V. But we will be connecting the 7.4V positive wire
from battery to 12V input terminal of motor driver module. This will make the motors
operate with 7.4V. The following table will list how the MPU6050 and L298N motor driver
module is connected with Arduino.
Component
Arduino Pin
Pin
MPU6050
Vcc +5V
Ground Gnd
SCL A5
SDA A4
INT D2
L298N
IN1 D6
IN2 D9
IN3 D10
IN4 D11
The MPU6050 communicates with Arduino through I2C interface, so we use the SPI pins A4
and A5 of Arduino. The DC motors are connected to PWM pins D6,D9 D10 and D11
respectively. We need to connect them to PWM pins because we will be controlling the speed
of the DC motor by varying the duty cycle of the PWM signals.
At the same time we also have to control the speed at which wheels are rotating, if the bot
is slightly disoriented from centre position the wheels rotate slowly and the speed increase as
it gets more away from the centre position. To achieve this logic we use the PID algorithm,
which has the centre position as set-point and the level of disorientation as the output.
To know the current position of the bot we use the MPU6050, which is a 6-axis
accelerometer and gyroscope sensor combined. In order to get a reliable value of position
from the sensor we need to use the value of both accelerometer and gyroscope, because the
values from accelerometer has noise problems and the values from gyroscope tends to drift
with time. So we have to combine both and get the value of yaw pitch and roll of our robot,
of which we will use only the value of yaw.
Sounds bit of head reeling right? But worry not, thanks to the Arduino community we have
readily available libraries that can perform the PID calculation and also get the value of yaw
from the MPU6050. The library is developed by br3ttb and jrowberg respectively. Before
proceeding download their libraries form the following link and add them to your Arduino lib
directory.
https://github.com/br3ttb/Arduino-PID-Library/blob/master/PID_v1.h
https://github.com/jrowberg/i2cdevlib/tree/master/Arduino/MPU6050
Now, that we have the libraries added to our Arduino IDE. Let’s start programming for our
Self balancing Robot. Like always the complete code for the Project is given at the end of
this page, here I am just explaining the most important snippets in the code. A told earlier the
code is build on top of the MPU6050 example code we are just going to optimize the code for
our purpose and add the PID and control technique for our self balancing robot.
First we include the libraries that are required for this program to work. They include the in-
built I2C library, PID Library and MPU6050 Library that we just downloaded.
#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps20.h"
//https://github.com/jrowberg/i2cdevlib/tree/master/Arduino/MPU6050
Then we declare the variables that are required to get the data from the MPU6050
sensor. We read both the gravity vector and quaternion values and then compute the yaw
pitch and roll value of the bot. The float array ypr[3] will hold the final result.
// orientation/motion vars
float ypr[3]; // [yaw, pitch, roll] yaw/pitch/roll container and gravity vector
Next comes the very important segment of the code, and this is where you will be spending a
long time in tuning for the right set of values. If you robot is built with a very good centre
of gravity and the components are symmetrically arranged (which in most cases is not) then
the value of your set-point will be 180. Else connect your bot to Arduino serial monitor and
tilt it till you find a good balancing position, read the value displayed on serial monitor and
this is your set point value. The value of Kp, Kd and Ki has to be tuned according to your bot.
No two identical bots will have the same values of Kp, Kd and Ki so there is no escaping
from it. Watch the video at the end of this page to get an idea of how to adjust these values.
double setpoint= 176; //set the value when the bot is perpendicular to ground using
serial monitor.
//Read the project documentation on circuitdigest.com to learn how to set these values
In the next line we initialise the PID algorithm by passing the input variables input,
output, set point, Kp, Ki and Kd. Out of these we have already set the values of set-point
Kp,Ki and Kd in the above snippet of code. The value of input will be the current value of
yaw that is read from the MPU6050 sensor and the value of output will be the value that is
calculated by the PID algorithm. So basically the PID algorithm will give us an output value
which should be used to correct the Input value to being it close to the set point.
own values of offsets you can use this Arduino sketch to calculate the offset value of you
sensor and update the following lines accordingly in your program.
// supply your own gyro offsets here, scaled for min sensitivity
mpu.setXGyroOffset(220);
mpu.setYGyroOffset(76);
mpu.setZGyroOffset(-85);
mpu.setZAccelOffset(1688);
We also have to initialise the Digital PWM pins that we are using to connect our motors to.
In our case it is D6, D9, D10 and D11. So we initialise these pins as output pins make them
LOW by default.
analogWrite(6,LOW);
analogWrite(9,LOW);
analogWrite(10,LOW);
analogWrite(11,LOW);
Since we assume that the MPU6050 will return 180 when the bot is upright. We will get
correction values positive when the bot is falling towards front and we will get values in
negative if the bot is falling towards back. So we check for this condition and call the
appropriate functions to move the bot forward or back ward.
pid.Compute();
//Print the value of Input and Output on serial monitor to check how it is working.
The PID output variable also decides how fast the motor has to be rotated. If the bot is
just about to fall then we make minor correction by rotating the wheel slowly. If these minor
correction dint work and still if the bot is falling down we increase the speed of the motor.
The value of how fast the wheels rotate will be decided by the PI algorithm. Note that for the
Reverse function we have multiplied the value of output with -1 so that we can convert the
negative value to positive.
analogWrite(6,output);
analogWrite(9,0);
analogWrite(10,output);
analogWrite(11,0);
analogWrite(6,0);
analogWrite(9,output*-1);
analogWrite(10,0);
analogWrite(11,output*-1);
Serial.print("R");
analogWrite(6,0);
analogWrite(9,0);
analogWrite(10,0);
analogWrite(11,0);
Serial.print("S");
Arduino Code:
/*Arduino Self Balancing Robot
* Build on top of Lib: https://github.com/jrowberg/i2cdevlib/tree/master/Arduino/MPU6050
*/
#include "I2Cdev.h"
#include <PID_v1.h> //From https://github.com/br3ttb/Arduino-PID-
Library/blob/master/PID_v1.h
#include
"MPU6050_6Axis_MotionApps20.h" /
/https://github.com/jrowberg/i2cdevlib/tree/master/Arduino/MPU6050
MPU6050 mpu;
// 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
volatile bool mpuInterrupt = false; // indicates whether MPU interrupt pin has gone high
void dmpDataReady()
{
mpuInterrupt = true;
}
void setup() {
Serial.begin(115200);
// initialize device
Serial.println(F("Initializing I2C devices..."));
mpu.initialize();
// supply your own gyro offsets here, scaled for min sensitivity
mpu.setXGyroOffset(220);
mpu.setYGyroOffset(76);
mpu.setZGyroOffset(-85);
mpu.setZAccelOffset(1688);
// set our DMP Ready flag so the main loop() function knows it's okay to use it
Serial.println(F("DMP ready! Waiting for first interrupt..."));
dmpReady = true;
Serial.println(F(")"));
}
void loop() {
// if programming failed, don't try to do anything
if (!dmpReady) return;
// 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();
}
}
Serial.print("S");
}
Here we see the input and output values of the PID algorithm in the format input => output.
If the bot is perfectly balance the value of output will be 0. The input value is the current
value from the MPU6050 sensor. The alphabet “F” represents that the bot is moving in
forward and “R” represents that the bot in reverse.
Conclusions:
This report presents an experimental, Arduino based, low cost self-balancing robot as an
educational control system. This system helps in future courses building and controlling the
proposed robot will be included as part of the curriculum of control and robotics courses. For
prototypes, the body has been designed in a CAD program and will be built using a 3D
printer.
Through this project we would be able to grasp the underlying concept behind all these
scooters and also learn how PID algorithm works.
References:
[1] AMCI Tech Tutorials. 2015. Stepper vs. Servo. Available at:
http://www.amci.com/tutorials/
tutorials-stepper-vs-servo.asp.
[2] Arduino Uno. 2015. Arduino – Arduino Board Uno . Available at:
http://www.arduino.cc/en/
main/arduinoBoardUno.
[4] Faragher, Ramsey. 2012. Understanding the Basis of the Kalman Filter Via a
Simple and Intuitive Derivation. IEEE signal processing magazine.
[5] Glad, Torkel. Ljung, Lennart. 2006. Reglerteknik - Grundläggande teori. 4th
edn. Studentlitteratur.
[6] InvenSense Inc. 2013. MPU-9150 Product Specification. Sunnyvale, USA. Re-
vision 4.3. Available at: http://www.invensense.com/mems/gyro/documents/PS-
MPU-9150A-00v43.pdf.
[12] MathWorks. 2012. Control Tutorials for MATLAB and SIMULINK, Inverted
Pendulum. Available at: http://ctms.engin.umich.edu/CTMS/index.php.exampleInverted
Pendulumsection-SystemModeling.
https://opensource.com/resources
/what-open-source.
[15] Velleman. 2013. Motor and power shield for Arduino. Gavere, Belgium. Avail-
able at:
http://www.velleman.co.uk/manuals/vma03.pdf
[16] Jin, D. 2015. Development of a Stable Control System for a Segway. Available
at:
http://www.raysforexcellence.se/wp-content/uploads/2013/01/Dennis-Jin-Development-
of-a-stable-control-system-for-a-segway.pdf.