A self-balancing robot using an Arduino microcontroller, MPU6050/MPU6500 IMU sensor, and PID control algorithm to maintain equilibrium on two wheels.
This robot uses a gyroscope (and accelerometer from the MPU6050/MPU6500) to measure its tilt angle in real-time. A PID controller processes this data to adjust motor speeds, keeping the robot balanced even when pushed or tilted. The system operates without using the MPU's Digital Motion Processor (DMP).
- Arduino UNO, Arduino Nano, or compatible board
- MPU6050/MPU6500 - 6-DOF IMU sensor (accelerometer + gyroscope)
- L298N - Dual H-Bridge motor driver module
- 2x DC Motors - With wheels attached (5V-12V)
- Power Supply - Battery pack (5V-12V depending on motors)
- Wires - Jumper and connecting wires
- Structural Frame - Robot chassis/body
| MPU Pin | Arduino Pin | Notes |
|---|---|---|
| VCC | 5V (or 3.3V) | Power for sensor |
| GND | GND | Common ground |
| SCL | A5 (UNO/Nano) / 21 (MEGA) | I²C clock |
| SDA | A4 (UNO/Nano) / 20 (MEGA) | I²C data |
| INT | D2 (optional) | Not used in this sketch |
| Function | Arduino Pin | L298N Pin | Description |
|---|---|---|---|
| ENA | D5 (PWM) | ENA | Left motor speed control |
| IN1 | D6 | IN1 | Left motor direction 1 |
| IN2 | D7 | IN2 | Left motor direction 2 |
| IN3 | D9 | IN3 | Right motor direction 1 |
| IN4 | D8 | IN4 | Right motor direction 2 |
| ENB | D10 (PWM) | ENB | Right motor speed control |
| +5V | — | +5V | Logic power for L298N |
| GND | GND | GND | Common ground |
- Left Motor: Connect to OUT1 and OUT2
- Right Motor: Connect to OUT3 and OUT4
- +12V IN / GND: Connect to battery (for motor power)
Install these libraries in the Arduino IDE (Sketch → Include Library → Manage Libraries):
-
MPU6050_tockn - IMU sensor library
- Search: "MPU6050_tockn"
- Author: tockn
-
PID_v1 - PID controller library
- Search: "PID"
- Author: Brett Beauregard
-
Wire - Built-in (I²C communication)
- Clone/Download the project files
- Open
self_balancing.inoin Arduino IDE - Install the required libraries (see Software Requirements)
- Connect your Arduino board via USB
- Select the correct board and COM port
- Upload the sketch to your Arduino
Adjust these values to fine-tune balancing behavior:
double Kp = 60; // Proportional gain
double Ki = 270; // Integral gain
double Kd = 2.2; // Derivative gain- Kp: Increases responsiveness. Higher values = faster response but may cause oscillation.
- Ki: Corrects steady-state errors. Use carefully to avoid instability.
- Kd: Dampens oscillations. Helps smooth out movements.
Adjust to balance left and right motor speeds:
double motorSpeedFactorLeft = 0.6; // Multiply left motor speed
double motorSpeedFactorRight = 0.5; // Multiply right motor speedIf the robot drifts left, increase motorSpeedFactorRight or decrease motorSpeedFactorLeft.
If using different Arduino pins, update these:
int ENA = 5; // Left motor PWM
int IN1 = 6; // Left motor direction
int IN2 = 7; // Left motor direction
int IN3 = 9; // Right motor direction
int IN4 = 8; // Right motor direction
int ENB = 10; // Right motor PWM- Sensor Reading: The MPU6050 measures the robot's pitch angle (tilt)
- Error Calculation: The PID controller compares actual angle vs. setpoint (0°)
- Motor Adjustment: Based on PID output, motor speeds are adjusted to correct the tilt
- Feedback Loop: This repeats ~100 times per second (10ms interval)
The balancing principle: If the robot tilts forward, the motor speeds increase to move forward and restore balance. If it tilts backward, motors move backward.
- Power on the robot and observe serial output (9600 baud)
- Keep the robot still during gyroscope calibration (takes ~5 seconds)
- Place the robot on a flat surface at a slight angle (15-30°)
- Gradually adjust PID values starting with small increments
- Test responsiveness to gentle pushes
- Fine-tune motor speed factors if drifting occurs
| Issue | Solution |
|---|---|
| Robot doesn't balance | Check MPU6050 connection; recalibrate gyro offsets |
| Robot unresponsive | Verify L298N connections; check PWM pins |
| Drifts left/right | Adjust motor speed factors |
| Vibrates/oscillates | Decrease Kp or increase Kd |
| Slow response | Increase Kp |
| Power issues | Verify battery voltage matches motor specs |
- Gyro Calibration: Performed automatically on startup with robot held still
- Serial Monitor: Set baud rate to 9600 to view sensor data
- Optimal Balance: Robot balances around pitch angle ≈ 0° (vertical)
- No DMP: Uses direct gyro/accel integration instead of MPU's Digital Motion Processor
- Add wireless remote control (Bluetooth/RF)
- Implement smartphone app control
- Add obstacle avoidance (distance sensors)
- Improve balance algorithm (use Kalman filter)
- Add speed/direction control via joystick
This project is open-source. Feel free to modify and improve it!
Created for Arduino-based robotics learning and experimentation.