Arduino Self Balancing Robot – Homemade DIY

Arduino Self Balancing Robot – Homemade DIY
(Last Updated On: June 19, 2019)

The Arduino Self balancing robot is a self-balancing robot that one can build on its own and can use it as a school project, college projects or for fun time and learning. Apart from other balancing robots, this robot uses stepper motor rather than the normal dc(direct current) motors. As the dc motors have a lot of mechanical friction and electrical resistance. But the dc motors are very precise and have no bad performance when the current drops down. As a result, the robot will move perfectly and in a straight line.

The total cost for building up this project is around $80 according to the hardware lists below.

You can download the complete YMFC-AL software package below.

Hardware requirements – Arduino Self Balancing Robot

1 x arduino pro mini
1 x FTDI USB to TTL programmer for thhe Arduino pro mini
1 x Arduino Uno
1 x MPU-6050 gyro accelerometer
2 x 2.4G wireless serial transceiver module
2 x Stepper motor
2 x Geeetech stepstick DRV8825
1 x Wired nunchuck controller for Wii
1 x Mini DC 7-28v to DC 5v Step-down converter
1 x 11.1v 2200mah 30C li-polymer Battery
1 x B3AC 2S/3S Lipo balance Charger
1 x 1/4w Ceramic metal film resistor set (600 PCS)
1 x Glass fiber Prototypng PCB
1 x 3-Pin toggle Switch (5-Pack)
2 x Robot tyres

One will also need some simple tools like soldering iron, screwdrivers, a fretsaw, compact drill, etc.
You ready?
So let us build it now

You can Cut the wood or cardboard or any hard substance for your Arduino self balancing robot according to the diagrams and measurement gave below.

The Diode and Resistors – Arduino Self Balancing Robot

arduino self balancing robotThe resistor named R1 on the schematic is in need of uploading a program to the Arduino self balancing robot. The TXD output of the transceiver is either forced high or low. Which results in the FTDI programmer cannot change this output anymore and we will get an upload error.  By adding the resistors Ftdi programmer we can change the voltage on the Rx-pin of the Arduino self balancing robot despite the state the transceiver output and the program is uploaded without any problems.

The other two named resistors (R2 and R3) from a voltage divider. It means that the 12.6 volts of the battery minus the 0.6 voltage dropdown over the diode is divided by 2.5. Resulting in a 4.8 volt on the analogue input where the battery is fully charged in the main program and the analogue input will be used to protect the battery. This is because the lithium polymer batteries can be damaged when the voltage drops below 3volt per cell.

The diode D1 protects all the electronics against reversed polarity. So if e accidentally reverse the connections of the batteries the components won’t go up and start smoking.

Wiring of the Arduino self balancing robot is given below

The connection of the Arduino self balancing robot for the joystick is given below.

Top15 Banned Android Apps Free Download | One of a kind

The Hardware test – Arduino Self Balancing Robot

The soldering of the wires is done in the back side of the PCB. So there is a need to double check all the connections before powering the PCB.

When everything is in its place it is time to connect the Arduino pro mini. If the Led don’t light up then there is a short circuit in the wiring connection and then you will need to disconnect the FTDI programmer as soon as possible. ( Arduino self balancing robot )Generally, the Arduino pro mini is already programmed with a blink led so the Arduino should start to flash.

To check is the gyroscope is correctly adjusted and to check the balancing of the robot you have to Upload the “hardware-check” program that you will find in the upload package that you have already downloaded earlier.

Test the Balancing of the Arduino self balancing robot and fix it in the required position.

After uploading the program, open the serial monitor and set the baud rate to 9600.

This program will be checking whether if there is any l2C device is connected and if this is an MPU-6050. And is everything is working as desired in the program then the program will output several raw gyro values on the screen.
How to Limit the Motor Current

We need to connect the correct drive current for the stepper motors as the current is set to high stepper motor controllers can get heated up and also damaged.

Kindly set the potentiometer at the same position as shown. A good alternative is to use a small dc fuse as shown in the pic This fuse blows off if there is a short circuit.

The safest way to check it correctly is by setting the power supply to 500mili amperes. First, connect one motor than the other.

Playstore Alternative get Free Apps on Your Smartphone Now

The Remote Control – Arduino Self Balancing Robot

If you open the remote you can note the various wire colours that are connected to the different pins. The remote works o 3.3volts and you can use the 3.3volt output of the Arduino to power this remote and the 5volt can be used for the transceiver.

Upload the hardware program which you have downloaded earlier to check the working of the remote after uploading the program open the serial monitor and set the baud rate as 9600.

The program will basically check whether any 12c device is connected. If everything works as per expected then the raw joystick values will appear on the screen.

You will need to upload the YABR-remote program to the Arduino Uno and the YABR-robot program to the Arduino pr mini. The programs do not need any changes

To start the Arduino self balancing robot you will need to lay the remote on the back and switch the power on. The led will blink indicating that the gyro is calibrating and working properly. When the blinking stops you can slowly lift the robot and then the robot will start to balance itself.

Arduino Self-balancing Robot Code

#include <PID_v1.h>
#include <LMotorController.h>
#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps20.h"

#include "Wire.h"

#define MIN_ABS_SPEED 20

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

double originalSetpoint = 173;
double setpoint = originalSetpoint;
double movingAngleOffset = 0.1;
double input, output;

//adjust these values to fit your own design
double Kp = 50;   
double Kd = 1.4;
double Ki = 60;
PID pid(&input, &output, &setpoint, Kp, Ki, Kd, DIRECT);

double motorSpeedFactorLeft = 0.6;
double motorSpeedFactorRight = 0.5;
int ENA = 5;
int IN1 = 6;
int IN2 = 7;
int IN3 = 8;
int IN4 = 9;
int ENB = 10;
LMotorController motorController(ENA, IN1, IN2, ENB, IN3, IN4, motorSpeedFactorLeft, motorSpeedFactorRight);

volatile bool mpuInterrupt = false; // indicates whether MPU interrupt pin has gone high
void dmpDataReady()
mpuInterrupt = true;

void setup()
// join I2C bus (I2Cdev library doesn't do this automatically)
TWBR = 24; // 400kHz I2C clock (200kHz if CPU is 8MHz)
Fastwire::setup(400, true);


devStatus = mpu.dmpInitialize();

// supply your own gyro offsets here, scaled for min sensitivity
mpu.setZAccelOffset(1788); // 1688 factory default for my test chip

// make sure it worked (returns 0 if so)
if (devStatus == 0)
// turn on the DMP, now that it's ready

// enable Arduino interrupt detection
attachInterrupt(0, dmpDataReady, RISING);
mpuIntStatus = mpu.getIntStatus();

// set our DMP Ready flag so the main loop() function knows it's okay to use it
dmpReady = true;

// get expected DMP packet size for later comparison
packetSize = mpu.dmpGetFIFOPacketSize();

//setup PID
pid.SetOutputLimits(-255, 255); 
// 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 "));

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 
motorController.move(output, MIN_ABS_SPEED);


// 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
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);
mpu.dmpGetGravity(&gravity, &q);
mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
input = ypr[1] * 180/M_PI + 180;

Use the above code to et your rduino working

Jason Gomes

A passionate blogger by heart .Founder of, Life motto: You can do many things in life. The only limit is your imagination

This Post Has One Comment

  1. I really want to try this project but the resource files link is dead.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Close Menu