Build pathAdvancedA weekend

Build a Self-Balancing Robot With an MPU6050 and PID

A two-wheeled robot that stands up by itself, stays upright when you push it, and holds its spot on the floor instead of drifting away.

Build a Self-Balancing Robot With an MPU6050 and PID technical schematicθTILT → PID → DRIVE UNDER IT

What you are building

A robot that stands on two wheels with nothing holding it up but arithmetic.

The mechanical build is genuinely simple — two motors, a frame, a sensor, a battery. What makes this project worth doing is that the control problem has no soft failure. A line follower with mediocre gains still follows the line, badly. A balancing robot with mediocre gains lies on the floor. That sharpness is what makes it the best possible way to actually understand PID.

By the end you will have a robot that stands up, resists a push, and stays roughly where you put it.

Why it is hard

All of the robot’s mass sits above the axle. That makes it an inverted pendulum: vertical is an equilibrium the way a pencil balanced on its point is an equilibrium — real in principle, hopeless without constant correction. Tip it slightly and gravity produces a torque that tips it further, faster.

The robot’s only defence is that it can move its own base. Driving the wheels forward pushes the axle back under the centre of mass and rotates the body upright again. Which gives the counter-intuitive rule that governs the whole project: to stop falling forward, drive forward.

Two consequences follow, and they shape everything below:

  1. You cannot control position directly. Driving the motors from position error accelerates the base out from under the mass, and the robot falls in the direction opposite to the one you asked for. Position has to be controlled through tilt.
  2. There is a hard recovery limit, around 35°. Past it, the acceleration needed exceeds what the wheels can deliver before the body reaches the floor, and no gain helps.

Build order

Do these in order. Each step is verifiable on its own, which matters enormously on a project where the end state is binary.

1 — Get a trustworthy tilt angle. Wire the MPU6050 and follow reading tilt from an MPU6050. Do not move on until the angle reads near zero when upright, moves the right way when you tip it, and holds still when the robot is still. Everything downstream is built on this number.

2 — Make the angle survive motion. An accelerometer alone is unusable on a moving robot and a gyro alone drifts within seconds. The complementary filter fuses them in one line. Test it by shaking the robot bodily without rotating it — the angle should barely move.

3 — Tune the inner loop in the simulator. Before any hardware can fall over, use the balance simulator to build intuition for what each gain does. Set derivative gain to zero on a robot that is currently balancing and watch the oscillation grow until it goes down; that failure is much cheaper to see there than on your desk.

4 — Make it stand up. Write the inner loop from cascaded PID balance control, with the outer loop disabled. Success here is a robot that stays upright and is allowed to wander. Do not try to fix the wandering yet.

5 — Add encoders and the outer loop. With quadrature counting giving real wheel position, enable the outer loop so the robot holds a spot. Start its gain far lower than feels reasonable — its effect is indirect and it is easy to make the two loops fight.

Hardware notes that actually matter

Mount the battery high. This is counter-intuitive and it is the single most useful mechanical choice in the project. Raising the centre of mass increases the pendulum’s period, so the robot falls more slowly and the loop gets more chances to catch it. A short, bottom-heavy robot is much harder to balance than a tall one.

Use metal gearboxes. A balancing robot reverses direction hundreds of times a second. Plastic-gearbox motors have enough backlash that each reversal wastes the first few degrees doing nothing, which the loop cannot tune around. N20 encoder motors are the usual answer.

Use a TB6612FNG, not an L298N. The TB6612FNG drops far less voltage across its output stage. On an L298N, small correction commands fall below the voltage at which the motor moves at all — creating a dead zone exactly where the fine corrections live.

Give the motors their own supply. A battery pack that sags under stall current will brown out the microcontroller mid-correction. The robot then falls for reasons that have nothing to do with your control loop, which is a miserable thing to debug.

Verifying as you go

Check What it proves
Angle reads ~0° held upright by hand No mounting trim left in the measurement
Shaking without rotating barely moves the angle The filter is trusting the gyro during acceleration
Wheels drive forward when tipped forward The inner loop sign is right
Robot resists a push and settles without growing wobble Derivative gain is doing its job
Robot stops drifting once the outer loop is on Encoders and the outer loop are wired correctly

When it does not work

Almost every failure is one of five things, and they look different enough to tell apart:

  • Slams down instantly on power-up — the inner loop sign is inverted.
  • Growing oscillation until it falls — derivative gain too low, or D taken from a differenced angle instead of the gyro rate.
  • Buzzes while upright — proportional gain too high, or the loop running too slowly for those gains.
  • Sags to the floor without fighting — proportional gain too low, or the motors saturating.
  • Balances but drives away — mounting trim, with too little integral to absorb it.

The failure-mode table goes through each one in more detail, and every one of them can be reproduced deliberately in the simulator — which is the fastest way to learn to recognise them.

Project roadmap

The build path

Follow the tech tree from parts to a robot that follows a taped line. Each node unlocks when its prerequisites are done, and your progress saves on this device.

0 / 16 done

100%
Build

Make it stand up

Build

Goal

Make it hold its spot

Goal

Components

Tutorials in this path

Practise before you wire

Tune it in the live simulator

The build path routes through a browser lab. Find gains that follow the track cleanly here, then transfer them to the real robot.

Frequently asked questions

How hard is a self-balancing robot for a first project?

It is a poor first project and an excellent third one. Nothing about the wiring is difficult, but the plant is unstable, which means there is no partial credit—the robot either stands or it does not, and a wrong sign looks identical to bad gains until you know what you are looking at. Build a line follower first so that PID tuning and motor drivers are already familiar, then this becomes a focused problem about one loop rather than five unknowns at once.

Why does my balancing robot vibrate instead of standing still?

Usually proportional gain that is too high for your loop rate, or gearbox backlash. Try lowering Kp first. If the vibration persists at low gain, watch the wheels at the moment they reverse: if there is a visible dead zone before they move, the gearbox is the problem and a metal-geared motor will fix what no amount of tuning can.

Do I really need encoders?

Not to stand up. The inner loop only needs a tilt angle, so a robot with no encoders at all will balance perfectly well—it will simply drift, because nothing tells it where it is. Encoders are what the outer loop needs to hold position. Build it without them first if you like, get it balancing, then add them.

How fast does the control loop need to run?

200 Hz is a sensible minimum for the inner loop and faster is better. The robot's natural fall time sets the deadline: a small robot goes from upright to unrecoverable in well under a second, so a loop running at 50 Hz has very few chances to intervene. Run it from a hardware timer rather than delay(), because consistent timing matters more to the derivative term than the exact rate.

Why does it balance but slowly drive across the room?

IMU mounting trim. If the sensor sits a degree off vertical, the loop holds that wrong angle, and holding a constant lean means constant acceleration. Measure the offset with the robot genuinely upright by hand, subtract it as a constant, and let the integral term absorb what is left. You can reproduce this exactly with the trim slider in the simulator.