This project demonstrates a two-wheel self-balancing robot built around an Arduino Nano and an MPU-6050 IMU. The sketch estimates the robot pitch with a Kalman filter and drives the motors in short pulses to keep the chassis upright.
Project notes and build photos were originally published at https://dryetch.blogspot.com/.
- Arduino Nano V3.0 ATmega328P 5 V board
- MPU-6050 3-axis accelerometer and gyroscope module
- Two DC gear motors with wheels
- Rhino 610 mAh 2S 7.4 V 20C LiPo battery
- HobbyKing E4 battery charger
- L293D motor driver - Quadruple Half-H Driver
- 33 x 70 mm single-sided PCB
- 100 x 90 x 4.74 mm acrylic chassis
- Screws, spacers, and other mounting hardware
Self_Balancing_Robot.ino: main robot control loop, IMU setup, and motor controlI2C.ino: helper routines for MPU-6050 I2C communicationKalman.h: Kalman filter implementation from TKJ Electronics
The sketch currently uses these Arduino pins for the L293D motor driver:
D8: left motor forwardD7: left motor backwardD4: right motor forwardD3: right motor backward
The MPU-6050 connects over I2C:
A4: SDAA5: SCL5V: VCCGND: GND
Double-check motor polarity before final assembly. If the robot moves in the wrong direction when it leans, swap the motor wires or adjust the direction helpers in the sketch.
- Arduino IDE or Arduino CLI with support for
arduino:avr:nano - The standard Arduino
Wirelibrary
No additional third-party Arduino library is required because the Kalman filter implementation is included in this repository.
- Open
Self_Balancing_Robot.inoin the Arduino IDE. - Select the correct board and processor for your Nano.
- Connect the Nano by USB.
- Upload the sketch.
- Open the serial monitor at
115200baud if you want to see startup errors.
The current control loop uses a fixed pitch offset:
kPitchOffsetDeg = 81.80
That value is used to convert the raw filtered pitch into the robot's balance error. In practice, you will likely need to retune it for your own frame, wheel diameter, battery position, and sensor mounting angle.
A simple way to recalibrate:
- Hold the robot at the mechanical position you consider "balanced".
- Print
kalAngleYto the serial monitor temporarily. - Set
kPitchOffsetDegto that measured value. - Test with the wheels off the ground first.
The drive thresholds and pulse timings are also empirical and may need adjustment:
kBackwardDriveMinDegkBackwardDriveMaxDegkForwardDriveMinDegkForwardDriveMaxDegkDefaultPwmOnMskBoostPwmOnMs
This repository includes GPLv2-licensed code from TKJ Electronics in Kalman.h and I2C.ino. See the LICENSE file for the full license text.