Library for Arduino and MPU-6050 communication

As you probably already know from my project "Fuelino", I have been using a cheap and easy-to-use IMU (Inertial Measurement Unit) called MPU-6050. This board mounts a cheap integrated circuit capable of acquiring acceleration and gyroscope (and temperature) signals with 16 bits resolution. Such raw data can be read from the main microcontroller unit (for example Arduino, Raspberry Pi, ESP8266) using I2C communication protocol.

At the beginning, it is not so simple to understand how to communicate with MPU-6050, this is why I decided to create a simple library which "abstracts" the communication with MPU-6050, and lets you simply read the values of acceleration, gyroscope, temperature. The library is available on GitHub, inside the sub-folder "MPU6050mgr". Inside the GitHub repository, I also provided a simple example which shows how to send automatically the measurements to your PC, using Serial communication, once a second (MIN_TIME_BETWEEN_PRINTS set to 1000ms). This is done by setting:

#define MIN_TIME_BETWEEN_PRINTS 1000
#define AUTOMATIC_PRINT 1

In order to test the sketch, you can use both the Serial Monitor embedded in Arduino IDE (as shown above), or RealTerm (as shown below).

Alternatively, by setting "AUTOMATIC_PRINT" to 0, the example sketch below works in "polling mode". This means that, whenever you send, from your PC, an ASCII character "m", Arduino replies with a packet (binary data) which contains the raw signals read from MPU-6050.

When the sketch is compiled in "polling mode", you should use RealTerm or similar tools to visualize the binary data (HEX format below) received from Arduino. The polling is done by simply sending an "m" ASCII character to Arduino (serial communication should be initialized at 57600 baud). When you send this command to Arduino, it replies with a packet composed by 21 bytes, which have the following meaning:

  • 1 byte is the "packet type". The value is always 0x49 (ASCII character "I").
  • 4 bytes are the "time stamp", in milliseconds, from the time at which Arduino did the Power On.
  • 12 bytes are the "acceleration and gyroscope raw data". There are 3 axis for acceleration signals (X, Y, Z axis), and then also 3 axis for gyroscope signals. In total, 6 info, each one is a signed integer with 16 bits (2 bytes). The raw data received from MPU-6050 is encoded into "big endian format" (higher byte comes first, lower byte comes after). However, since the PC (and Arduino) works with "little endian format", the MPU6050mgr library takes care of this conversion by switching the order of the bytes. In addition to that, it is possible to apply a filter to the raw data by setting the filtering coefficient "MPU6050_SIG_FILT_CNST" inside "MPU6050mgr.cpp". When this constant is set to "0", no filtering is done. The filter implemented is a simple IIR filter, which composes the last sample and the previous one.
  • 2 bytes are the "temperature" signal. In order to convert to Celsius degrees, you should divide by 340.0 and then sum 36.53. You can manually perform this operation using a calculator, or any program (you should first cast the integer number to float or double, and then operate).
  • 2 bytes are the "checksum", in case you want to implement error detection.

Now, let's analyze deeply the most important parts of the library. In order to understand better how it works, you should have a look at the files "MPU6050mgr.cpp" and "MPU6050mgr.h" which are available here.

There are just few "defines" that you need to check, and update if necessary.

  • MPU6050_I2C_ADDRESS is the I2C address of MPU6050. The standard is 0x68
  • MPU6050_TASK_TIME_TARGET is the time, in ms, at which MPU6050 is polled (example 1 time every 20ms)
  • MPU6050_TASK_TIME_MULT is the number of polling after which the buffer is filled. For example, if you set 5 here, and the previous period is 20ms, one buffer will be filled once every 100ms
  • MPU6050_SIG_FILT_CNST is the filtering constant of IIR filter. The max value is (2^15 -1).

Author: Davide Cavaliere

I am an Italian Electrical Engineer graduated at Politecnico di Milano. My interests are motorcycles and cars, electronics, programming, Internet of Things, and Japanese culture.

Leave a Reply

Your email address will not be published. Required fields are marked *