This project presents the design and implementation of a two-wheeled self-balancing robot using an ESP32 microcontroller and MPU6050 inertial measurement unit. The system employs a PID control algorithm to maintain vertical equilibrium by continuously adjusting motor responses based on real-time orientation data. The implementation demonstrates effective closed-loop control in an inherently unstable mechanical system.
Self-balancing robots represent a classic control systems problem, where an inverted pendulum must be stabilized through active feedback control. This project implements such a system using cost-effective components and demonstrates the practical application of complementary filtering and PID control theory.
- Achieve autonomous vertical stabilization using sensor fusion and PID control
- Implement gyroscope calibration with persistent storage
- Design a state machine to handle different operational modes (waiting, balancing, fallen)
- Optimize control parameters for stable operation
The system comprises three primary subsystems: sensing, control, and actuation. Data flows from the MPU6050 sensor through the ESP32 processor to the motor driver system, forming a closed-loop control architecture.
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ MPU6050 │────▶│ ESP32 │────▶│ Motors │
│ Sensor │ │ Controller │ │ (L298N) │
└─────────────┘ └─────────────┘ └─────────────┘
▲ │ │
│ │ │
└───────────────────┴────────────────────┘
Feedback Loop (Tilt Angle)
- ESP32: Main processing unit featuring dual-core processor and built-in I2C interface
- Operating Voltage: 3.3V logic level
- Clock Speed: 240 MHz
- MPU6050: 6-axis IMU (3-axis accelerometer + 3-axis gyroscope)
- Communication: I2C protocol (SDA: GPIO21, SCL: GPIO22)
- I2C Address: 0x68
- DC Motors: Two geared motors for differential drive
- Motor Driver: L298N Dual H-bridge motor driver
- PWM Channels: GPIO26, GPIO27 (Motor A), GPIO25, GPIO14 (Motor B)
- PWM Frequency: 2 kHz with 8-bit resolution
The system employs a complementary filter to combine accelerometer and gyroscope data:
angle = α × (angle + gyroRate × dt) + (1 - α) × accAngle
Where α = 0.95, balancing the stability of accelerometer data against the responsiveness of gyroscope measurements.
The control system implements a Proportional-Integral-Derivative controller:
output = Kp × error + Ki × ∫error dt + Kd × dTerm
Tuned Parameters:
- Kp = 13.2 (Proportional gain)
- Ki = 0.75 (Integral gain)
- Kd = 0.7 (Derivative gain)
- Integral limit = ±60 (anti-windup)
Note: The derivative term uses the negative gyroscope rate (-gyroY/131.0) directly rather than the traditional derivative of error, providing faster response by predicting the system's angular velocity.
The robot operates in three distinct states:
- WAIT_UPRIGHT: Motors disabled, waiting for angle < 5°
- BALANCING: Active PID control, monitoring for falls (angle > 35°)
- FALLEN: Motors disabled, waiting for manual recovery
To compensate for sensor bias, the system performs a 2000-sample calibration during initialization. Calibration data is stored in EEPROM for persistence across power cycles, reducing startup time.
A-Self-Balancing-Robot/
├── Final_Code/
│ └── Final_Code.ino # Main implementation
└── Sensors Testing/
├── Motor_test/ # Motor driver validation
└── MPU6050_test/ # IMU sensor validation
- Connect MPU6050 to ESP32 via I2C (SDA→21, SCL→22)
- Wire motor driver to GPIO pins: 26, 27, 25, 14
- Ensure adequate power supply for motors (separate from ESP32 if possible)
- Install Arduino IDE with ESP32 board support
- Required libraries (built-in with ESP32 core):
- Wire (I2C communication)
- EEPROM (calibration storage)
- Upload
Final_Code.inoto ESP32 - Open Serial Monitor (115200 baud) for diagnostics
- Power on the system with robot lying flat
- Wait for gyroscope calibration (or automatic load from EEPROM)
- Lift robot to vertical position (within ±5°)
- System automatically enters balancing mode
The implemented system successfully achieves:
- Stable balancing within ±5° of vertical
- Recovery from disturbances up to 35° tilt angle
- Fast response time through optimized PID parameters
- Minimal steady-state error through integral control
Key Performance Metrics:
- Balance angle threshold: ±5°
- Fall detection threshold: ±35°
- Control loop frequency: ~100-200 Hz
- Motor PWM resolution: 8-bit (0-255)
This project is open-source and available for educational purposes.
Authors: Shass27, sumedha2932-source Platform: Arduino IDE