|
Arduino_UNO_R3 |
x 1 | |
|
MPU6050 |
x 1 | |
|
Motor driver L298N 5AD type |
x 1 | |
|
DC Motor |
x 2 | |
![]() |
N20 motor wheels |
x 2 | |
|
battery |
x 1 |
![]() |
Soldering Iron Kit |
|
![]() |
arduino IDEArduino
|
Arduino two weel self Balancing Robot
Self Balancing Robot is device that can balance itself from falling to the ground. Its function is to maintain balance using the motor’s axis movement of the wheels and body. There are several types of self-balancing robots, and in this particular case I will present you a way to make a Two-Wheeled Balancing Robot. Actually, I made this robot together with one of my students and it is a high school graduation project. This is the simplest type of balancing robot and only requires a few components to build.
First, let's explain the components used and their functions.
- MPU6050 Accelerometer and Gyroscope sensor with Micro Electro Mechanical System(MEMS) technology, which is used to detect angle of tilt or inclination along the X, Y and Z axes.
- The information from this sensor is transmitted to a microcontroller, and in our case it is an Arduino Uno board. This board is the brain of the robot, processes the sensor data and determines the actions needed to keep the robot upright.
- Processed data from the Arduino is sent to the motor driver board, which in our case is the L298N 5AD type. A motor driver circuit controls the direction and speed of the motors.
- This robot uses two DC motors, each connected to a wheel. These motors adjust the speed of the wheels to correct the robot’s tilt.
- and power source, specifically two Lithium batteries connected in series wich provides energy to the motors and electronics. All components are mounted on a suitable supporting structure made of 5mm thick PVC board.
This project is sponsored by PCBWay. They has all the services you need to create your project at the best price, whether is a scool project, or complex professional project. On PCBWay you can share your experiences, or get inspiration for your next project. They also provide completed Surface mount SMT PCB assemblY service at a best price, and ISO9001 quality control. Visit pcbway.com for more services
Now, let's briefly explain the working principle: The accelerometer gives a measure of the robot’s orientation relative to gravity, and the gyroscope detects the rate of tilt. The Arduino uses a PID (Proportional, Integral, Derivative) controller to process the data from the sensors.
The PID controller calculates the necessary speed and direction adjustments needed to maintain the robot’s balance. If the robot tilts forward, the motors spin faster to move the robot forward and prevent a fall. If it tilts backward, the motors move the robot backward to regain balance. As the robot detects an imbalance, it compensates by adjusting the wheel speed, shifting its center of mass, or moving forward or backward to maintain its position.
A few words about the Arduino code. The method of installing the code has been described many times before, so now I will only focus on the modifications that need to be made individually for each case due to the different characteristics of the components used, as well as the method of their placement.
Now comes the fun part, which is customizing the code specifically for our built device. Depending on the layout of the components, the center of gravity of the robot changes, and also each MPU6050 board has minimal differences that need to be compensated for in part of the code. If we look at the code in more detail, we will see that there is a place where the Gyro offset is set.
In this part of the code, errors are corrected during the manufacturing of the MPU6050 chip. For each individual chip, these values are different. Their value is determined using Arduino code made specifically for this purpose and you can download it at the end of this text.
Next, we need to move on to setting the Accelerometer. In the "double setpoint' line, we need to put a value that corresponds to our device.
To obtain this value, we need to hold the robot in an ideal vertical position, perpendicular to the surface, and read the required value on the serial monitor. In my case, it is about 182.
Finally, we need to experimentally determine the values of Kp, Kd, and Ki, needed for PID control.
For this purpose we set all three values to zero. Now we put some value for Kp and perform testing. Too little Kp will make robot fall over. Too much Kp will make the robot go back and forth wildly. A good Kp will make the robot go slightly back and forth. Next we need to set Kd. A gooD Kd value will lessen the oscilation until the robot is almost steady, and will keep the robot standing. Lastly set the Ki. The correct Ki value will shorten the time it takes for the robot to stabilize. I want to emphasize that the surface needs to be rough enough to increase the friction between it and the wheels.
And finally a short conclusion. This is a relatively simple, visually effective balancing robot project that only requires 3 components to make. However, its setup, although it can be time-consuming, is still a lot of fun trying to get the robot to stand steadily on its "own feet". Just to mention that we created this project together with my students as a final high school exam.
#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; // MPU control/status vars bool dmpReady = false; // set true if DMP init was successful uint8_t mpuIntStatus; // holds actual interrupt status byte from MPU uint8_t devStatus; // return status after each device operation (0 = success, !0 = error) uint16_t packetSize; // expected DMP packet size (default is 42 bytes) uint16_t fifoCount; // count of all bytes currently in FIFO uint8_t fifoBuffer[64]; // FIFO storage buffer // 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 /*********Tune these 4 values for your BOT*********/ double setpoint= 182; //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 double Kp = 15; //21 Set this first double Kd = 0.9; //0.8 Set this secound double Ki = 140; //140 Finally set this /******End of values setting*********/ double input, output; PID pid(&input, &output, &setpoint, Kp, Ki, Kd, DIRECT); 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(); // verify connection Serial.println(F("Testing device connections...")); Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed")); // load and configure the DMP devStatus = mpu.dmpInitialize(); // supply your own gyro offsets here, scaled for min sensitivity mpu.setXGyroOffset(-479); mpu.setYGyroOffset(84); mpu.setZGyroOffset(15); mpu.setZAccelOffset(1638); // make sure it worked (returns 0 if so) if (devStatus == 0) { // turn on the DMP, now that it's ready Serial.println(F("Enabling DMP...")); mpu.setDMPEnabled(true); // enable Arduino interrupt detection Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)...")); attachInterrupt(0, dmpDataReady, RISING); mpuIntStatus = mpu.getIntStatus(); // 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; // get expected DMP packet size for later comparison packetSize = mpu.dmpGetFIFOPacketSize(); //setup PID pid.SetMode(AUTOMATIC); pid.SetSampleTime(10); pid.SetOutputLimits(-255, 255); } else { // ERROR! // 1 = initial memory load failed // 2 = DMP configuration updates failed // (if it's going to break, usually the code will be 1) Serial.print(F("DMP Initialization failed (code ")); Serial.print(devStatus); Serial.println(F(")")); } //Initialise the Motor outpu pins pinMode (6, OUTPUT); pinMode (9, OUTPUT); pinMode (10, OUTPUT); pinMode (11, OUTPUT); //By default turn off both the motors analogWrite(6,LOW); analogWrite(9,LOW); analogWrite(10,LOW); analogWrite(11,LOW); } void loop() { // if programming failed, don't try to do anything if (!dmpReady) return; // wait for MPU interrupt or extra packet(s) available while (!mpuInterrupt && fifoCount < packetSize) { //no mpu data - performing PID calculations and output to motors pid.Compute(); //Print the value of Input and Output on serial monitor to check how it is working. Serial.print(input); Serial.print(" =>"); Serial.println(output); if (input>150 && input<200){//If the Bot is falling if (output>0) //Falling towards front Forward(); //Rotate the wheels forward else if (output<0) //Falling towards back Reverse(); //Rotate the wheels backward } else //If Bot not falling Stop(); //Hold the wheels still } // reset interrupt flag and get INT_STATUS byte mpuInterrupt = false; mpuIntStatus = mpu.getIntStatus(); // get current FIFO count fifoCount = mpu.getFIFOCount(); // 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(); // read a packet from FIFO mpu.getFIFOBytes(fifoBuffer, packetSize); // track FIFO count here in case there is > 1 packet available // (this lets us immediately read more without waiting for an interrupt) fifoCount -= packetSize; mpu.dmpGetQuaternion(&q, fifoBuffer); //get value for q mpu.dmpGetGravity(&gravity, &q); //get value for gravity mpu.dmpGetYawPitchRoll(ypr, &q, &gravity); //get value for ypr input = ypr[1] * 180/M_PI + 180; } } void Forward() //Code to rotate the wheel forward { analogWrite(6,output); analogWrite(9,0); analogWrite(10,output); analogWrite(11,0); Serial.print("F"); //Debugging information } void Reverse() //Code to rotate the wheel Backward { analogWrite(6,0); analogWrite(9,output*-1); analogWrite(10,0); analogWrite(11,output*-1); Serial.print("R"); } void Stop() //Code to stop both the wheels { analogWrite(6,0); analogWrite(9,0); analogWrite(10,0); analogWrite(11,0); Serial.print("S"); }
Arduino two weel self Balancing Robot

Raspberry Pi 5 7 Inch Touch Screen IPS 1024x600 HD LCD HDMI-compatible Display for RPI 4B 3B+ OPI 5 AIDA64 PC Secondary Screen(Without Speaker)
BUY NOW
ESP32-S3 4.3inch Capacitive Touch Display Development Board, 800×480, 5-point Touch, 32-bit LX7 Dual-core Processor
BUY NOW
Raspberry Pi 5 7 Inch Touch Screen IPS 1024x600 HD LCD HDMI-compatible Display for RPI 4B 3B+ OPI 5 AIDA64 PC Secondary Screen(Without Speaker)
BUY NOW- Comments(0)
- Likes(0)

- 0 USER VOTES
- YOUR VOTE 0.00 0.00
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
More by Mirko Pavleski
-
DIY ESP32 Bioresonance Rife Machine with ZAPPER function Rife machine therapy is an alternative treatment developed by Dr. Royal Raymond Rife in the 1930s. H...
-
Arduino VFO Project with a Large LCD Display A Variable Frequency Oscillator (VFO) is an electronic oscillator whose output frequency can be adj...
-
Exploring the Tesla Coil Driver Board, Full Review & Test Results Some time ago I presented you a video in which I analyzed a super cheap Tesla Coil driver that cost...
-
Arduino Eatrthquake alarm and protection system with D7S seismic Sensor Earthquakes are extremely common events around the world. On average, there are fifty earthquakes a...
-
Review and Comparison of Three Inexpensive Metal Detector Kits A metal detector is a device used to detect the presence of metal objects in the ground or other ma...
-
How to make simple Arduino RGB Led strip VU Meter VU meter or volume unit meter is a device intended for visual presentation of the audio signal. It ...
-
Arduino 3D Printed self Balancing Cube Self-balancing devices are electronic devices that use sensors and motors to keep themselves balanc...
-
OpenWebRX - Simplest Rasprberry Pi + RTLSDR Web SDR Radio Software-Defined Radio is a radio communication system where components that have traditionally bee...
-
Colorful Arduino Tetris Game - WS2812B LED Matrix Tutorial Tetris is a puzzle video game created in 1985 by Alexey Pajitnov. Players manipulate falling geomet...
-
Ultra cheap Ultrasonic levitation Device - functionality and testing Ultrasonic levitation is phenomenon where objects are suspended in mid-air using the power of sound ...
-
DIY -Spirit PI- ESP32 + Smartphone Sensitive Metal Detector Pulse Induction (PI) metal detector operates on a principle based on sending short pulses of electr...
-
ESP32 Analog style VU meter with GC9A01 Round Dispalys + Peak Meters A typical VU meter measures audio signals and displays them with a visual indicator. In the classic...
-
Arduino two weel self Balancing Robot Self Balancing Robot is device that can balance itself from falling to the ground. Its function is ...
-
ELECROW CrowPanel ESP32 4.2” E-paper Wi-Fi Info-Dispaly Project An e-paper display (also known as an electronic paper display or E Ink display) is a type of screen...
-
ESP32 Fluid simulation on 16x16 Led Matrix Fluid simulation is a way of replicating the movement and behavior of liquids and gases in differen...
-
Simple GU50 VTTC Tesla Coil with MOT (25+cm Spark) Vacuum Tube Tesla Coils are a common choice for homebuilders for several practical reasons. At Soli...
-
Hourglass ESP8266 Code A hourglass, also known as an sand clock, is a device used to measure the passage of time. It consi...
-
Tug of War Arduino Game on WS2812 Led strip A Tug of War is a classic team-based game where two opposing teams compete to pull a rope in opposi...
-
DIY ESP32 Bioresonance Rife Machine with ZAPPER function Rife machine therapy is an alternative treatment developed by Dr. Royal Raymond Rife in the 1930s. H...
-
Arduino VFO Project with a Large LCD Display A Variable Frequency Oscillator (VFO) is an electronic oscillator whose output frequency can be adj...
-
Exploring the Tesla Coil Driver Board, Full Review & Test Results Some time ago I presented you a video in which I analyzed a super cheap Tesla Coil driver that cost...
-
Arduino Eatrthquake alarm and protection system with D7S seismic Sensor Earthquakes are extremely common events around the world. On average, there are fifty earthquakes a...
-
Review and Comparison of Three Inexpensive Metal Detector Kits A metal detector is a device used to detect the presence of metal objects in the ground or other ma...
-
How to make simple Arduino RGB Led strip VU Meter VU meter or volume unit meter is a device intended for visual presentation of the audio signal. It ...
-
Arduino 3D Printed self Balancing Cube Self-balancing devices are electronic devices that use sensors and motors to keep themselves balanc...
-
OpenWebRX - Simplest Rasprberry Pi + RTLSDR Web SDR Radio Software-Defined Radio is a radio communication system where components that have traditionally bee...
-
Colorful Arduino Tetris Game - WS2812B LED Matrix Tutorial Tetris is a puzzle video game created in 1985 by Alexey Pajitnov. Players manipulate falling geomet...
-
Ultra cheap Ultrasonic levitation Device - functionality and testing Ultrasonic levitation is phenomenon where objects are suspended in mid-air using the power of sound ...
-
DIY -Spirit PI- ESP32 + Smartphone Sensitive Metal Detector Pulse Induction (PI) metal detector operates on a principle based on sending short pulses of electr...
-
ESP32 Analog style VU meter with GC9A01 Round Dispalys + Peak Meters A typical VU meter measures audio signals and displays them with a visual indicator. In the classic...
-
Commodore 64 1541-II Floppy Disk Drive C64 Power Supply Unit USB-C 5V 12V DIN connector 5.25
124 1 2 -
Easy to print simple stacking organizer with drawers
74 0 0 -
-
-
-
Modifying a Hotplate to a Reflow Solder Station
1116 1 6 -
MPL3115A2 Barometric Pressure, Altitude, and Temperature Sensor
627 0 1 -
-
Nintendo 64DD Replacement Shell
478 0 2 -
V2 Commodore AMIGA USB-C Power Sink Delivery High Efficiency Supply Triple Output 5V ±12V OLED display ATARI compatible shark 100W
1398 4 3