Self-balancing Part 2

If you haven’t already read the first part of this Self-balancing robot series, I would encourage you to do so now! The first section below deals with a little bit of theory behind the sensors, so if you want to get straight to the programming/building part, please feel free to skip to the second section…


Deciding which Gyroscope Module to Use

So you have decided to go ahead with the project and construct your own self-balancing robot? That’s great! Now we can start by looking at one of the most significant elements of this project; the sensor. Traditionally the sensor of preference for stabilisation is a gyroscope. Now-days gyroscopes are extremely small and very cheap to buy, so they are ideal for amateur electronics projects. Unfortunately these gyroscopes (both the cheap and the not-so-cheap versions) also come with their own problems. They are good for short-term and quick movements, but tend to drift over time as the error accumulates. They also record a lot of jitter and noise, which needs to be filtered by the micro-controller before the data can be used.

To reduce this drifting effect of the gyroscope, it is possible to combine the sensor data with that from an accelerometer. The accelerometer is good at sensing slower and more prolonged movements, rather than the fast motion. Therefore if we take the best of both worlds and fuse the data together, we will be left with an extremely accurate picture of the motion of the robot.

As a result I decided to use a combined accelerometer & gyroscope breakout module (the MPU-6050), which is slightly more expensive than a simple gyro, but should lead to a superior stabilisation performance. Note: the MPU-6050 comes with a library which does all of the calculations and filtrations for you, so that definitely is a plus!


Getting started with the Accel-Gyro Module

The MPU-6050 uses I2C to communicate with the micro-controller, so I started by connecting up the pins as shown in the schematics: the SDA line connects to the Analogue pin 4, the SCL to Analogue pin 5, power input to the 3.3v pin and the ground to the GND pin.

Schematic for wiring the accel-gyro to the Galileo. (Made using Fritzing)
Schematic for wiring the accel-gyro to the Galileo. (Made using Fritzing)

As I am using an Intel Galileo Gen2 board, I did not use the interrupt pin. In general it is very bad practice to disregard the interrupts, as it might cause the buffer holding the sensor data to overflow, but for some reason the Galileo does not support normal interrupts! In order to get the sensor working correctly on the Galileo Board, I spent a lot of time on getting the timing right so that there is no overflow of incoming sensor data.For all other Arduino-compatible board, you should use the interrupt so that the micro-controller deals with new sensor data the moment that it is sent. (The interrupt pin is connected to Arduino I/O pin 2)

Now it is time to get some data from the accel-gyro module! To do this I simply used the sample code which came with the documentation of the MPU6050 in order to read the raw sensor data. For this sample to work, the I2Cdev and the MPU6050 libraries need to be installed. Here is the code:


The result I got on the Serial Monitor looked like this:

In this data we can see the readings from the accelerometer already divided into the x/y/z values, and the readings from the gyroscope divided into its x/y/z components. This is a great first step, but unfortunately this data is not very usable in its current form. We still have to fuse the accelerometer and gyroscope data together, and then filter it to remove all of the noise!

The MPU6050 module connected to a Galileo Gen 2 Board
The MPU6050 module connected to a Galileo Gen 2 Board


Manipulating the data

It is possible to calculate the tilt of the sensor manually through the use of a number of formulas, but fortunately (at least for the MPU-6050) there is a library to do this for us! As a matter of fact, the MPU-6050 has a builtin “Motion Processing Unit” (hence the initials) which can be used to process the sensor data, therefore minimising the load on the micro-processor. This library also automatically filters the data so that we get a clean and usable result straight away.
tan^{-1} \frac{A_x}{A_y} = sin^{-1} \frac{A_x}{\sqrt{A^2_x + A^2_y}} = sin^{-1} \frac{A_x}{g}

Above is the equation used to calculate the angle of inclination from the accelerometer data. As I opted to use the lazier method (using the library), I don’t think that I am in a good position to explain all of these formulas to you. If you want to find out about calculating the angles manually, please visit: Kerry Wong does an awesome job at describing the whole system, so I would encourage you to check it out! He covers all of the main topics such as the calculations, sensor fusion and the Kalman filter.

As regards the filtering, here is another great post which looks at the main advantages and disadvantages of using the a complimentary filter instead of the MPU6050 motion-apps library:


In Part 3: Using the MPU6050 motion apps, and calibrating the accelerometer-gyroscope module. View Part 3


Please leave a comment below if you have any questions or suggestions. You could consider subscribing if you want to be notified the moment I post the next part of this series!

This Post Has 5 Comments

  1. Hi .
    what’s the differences between ADXL345 , and MPU6050 ??

    1. I’ve never used the ADXL345, but it appears to be a 3-axis accelerometer. The MPU6050 contains both a 3-axis accelerometer and a 3-axis gyroscope. You can find the datasheets online for more detailed comparison.

  2. Initializing I2C devices…
    Testing device connections…
    MPU Connection failed
    a/g: 0 0 0 0 0 0
    a/g: 0 0 0 0 0 0
    a/g: 0 0 0 0 0 0
    a/g: 0 0 0 0 0 0
    a/g: 0 0 0 0 0 0
    a/g: 0 0 0 0 0 0
    a/g: 0 0 0 0 0 0

    and it goes on…

    I checked the pin connections and they were right.
    Do you the chip is damaged?

  3. When I run the code,
    the monitor shows only zeroes as the values

    What should I do?

    1. To be able to help you, I’ll need a little bit more information.
      > What micro-controller are you using?
      > What other text do you see in the serial monitor (such as the first three lines in my sample)?
      > Have you connected all of the pins properly and set to serial monitor to the right baud rate?

Leave a Reply

ten − one =