Self-balancing ARM (updated and improved)

Simplicity is the ultimate sophistication. In the previous version of the self-balancing robot I used in total 3 microprocessors but have now designed and programmed on a faster ARM microprocessor. Greater processor performance provides a host of benefits:

  • Fewer components
  • Simple circuit diagram
  • Robust mechanical design because of fewer cables
  • No communication between processors is necessary which gives a very simplified code
  • A small RTOS takes care of scheduling (which did not work on AVR)

How do you build a similar (or better)


Mechanical design

Read the oldest posts on the projects page to see photos of how to build up the. The only thing that needs to be manufactured are the three plates of which there are CAD drawings.


Many have asked for schematics so I did one in Altium Designer.


All code located on Github.

Basic control theory

In short I am using cascaded PID controllers. The outer loop is regulating the speed of the robot which is measured with encoders on the motors. The internal loop controls the robot's angle, which is measured with an IMU. The outer loop has slow dynamics and the internal loop is much faster. Theoretically it should be possible to program a self balancing robot using only the inner loop but you get very easily a behaviour of the robot inching forward or backward across the floor because of the missing feedback from the wheel speeds.

To gain additional performance gain scheduling is used on the inner loop, which means that the regulator parameters will change depending on the robot's angle. A small angle near the equilibrium means conservative regulator parameters where only small adjustments are made to keep the robot standing. If the angle of the robot is close to falling, the aggressive paramter settings are activated in order to do everything to regain stability.

Information flow

Information flow

Cascade PID implementation theory

Cascade PID implementation theory

Change parameters

Likely all parameters will not work without being adjusted slightly. In the code there is a struct that can be put in setConfiguration(). Smarter, however, is to use a serial terminal to change parameters while the code is running. In this way there is no need to reprogram the processor every time you want to change a parameter. Open the Serial Monitor in Arduino. Test writing "print configuration" to the Arduino. If everything works as it should, it will respond by printing all parameters. All variables can be set in the struct Configuration from the Terminal. Just type "set" followed by the variable name and value. For example "set speedPIDKp 1.5". To activate debug type "set debugLevel 2". If you want to debug the IMU then type "set angleRawDebug 1". To turn off a debug variable write, for example, "set angleRawDebug 0".

Finding the right regulator parameters

Use a realtime plotter when you configure your controller parameters to make stuff less difficult.

Tagged with: , , , ,

Better filtering makes all the difference on self-balancing robot

I programmed a simple moving average filter. This will remove the rapid changes and make the robot calmer and with less overshoots.

It also handles pushes much better than before.

The self-balancing robot is working quite well

In the video you can see that the robot stays at roughly the same spot on the floor and handles a lighter push without any problem. To achieve this I have two cascade PID controllers and low pass filter on both wheel speed and the robot's angle.


As an Arduino does not have a lot of processing power, I chose to use a total of 3 microprocessors:

  1. A standalone Arduino Uno takes pulses from the tachometer on each wheel and converts it to a speed. The speed is sent to the main micro processor.
  2. One more stand alone Arduino Uno to view and adjust parameters. Also drives the display. The parameters are sent to the main micro processor.
  3. Arduino Leonardo is the brain. It receives information from the console and the engine speed sensor via I2C.

Basic control theory

Two cascaded PID controllers. The first has speed as setpoint (always 0 in this case) and angle as output. If the robot is moving forward, the controller will have a positive input value and send a negative output value. This means that the robot will want to lean back to slow down.

PID number 2 takes care of the robot's angle relative to the floor. The setpoint is the output of the previous PID controller. Normally the set point will range from -3 to 3. Zero corresponds to the robot standing completely straight up. The output signal is connected to the engine management system and range from -100 to 100. -100 corresponds to full voltage to the motors in reverse direction.

To get cleaner inputs I use FIR filters for both angle and wheel speed. Low-pass filter blocks rapid change (for example, sensor noise) from passing through.

For the angle relative to the floor, a IMU with accelerometer and gyro is used. A complementary filter combines the signals from these and provides an output signal that can be used.


I had the objective that all code for this project should be open sourced and available for download from github. The readme contains links to libraries I have used.

Improvements that could be made

  • Better parameters to the FIR filter. Much could probably be done on the wheel speed.
  • On-the-fly programming over the air with Xbee. This means that you can send new code to the robot without USB cable. Will make programming more flexible.
  • Radio control would be nice.



I am also publishing cad and drawings.

Tagged with: , ,

Early test of self-balancing robot

I will have to adjust the PID to get it truly self-balancing. It has too large overshoots and it restless behaviour. I will update when I get better stability.

Tagged with: , ,

The second step to a self-balancing robot

I now have enough parts to start to assemble the robot.

I had to drill out the holes slightly to get them to fit M3.

The accelerometer is as close as possible to the motor shaft.

To tighten all the nuts use a screwdriver, a piece of tape and then rotate the threaded rod. Hold the nut with your fingers and let the tool do the work. Otherwise, it takes a while to get it into all 24 nuts.

Here's how it looks right now:

Tagged with:

The first step to a self-balancing robot

This evening I made cad and ordered the parts to make my own self-balancing robot. I will use Arduino microprocessor and a small 6 degrees of freedom as tilt-sensor.

The cad in the pictures is not entirely done but I think most parts are in their proper place.

I will update with new blog posts when progress is made.

[Update 2012-06-12] Bolted connections in place

Added the bolts to the engine mount, wheels and the rails. Updated pictures:

Tagged with: