Microcontroller Tutorials

Arduino, Raspberry Pi, PIC, Beaglebone Resources

Get Orientation with Arduino and MPU6050

by Roland Pelayo

The MPU6050 is a six-axis gyroscope and accelerometer in one package. With its easy-to-use breakout board, it became one of the more popular sensors for the Arduino platform. This article looks into this sensor and teaches how to use it to determine the orientation of an object.


The MPU6050 breakout board comes with 8 pins as shown:

The sensor communicates, as a slave, with a microcontroller through I2C. It can also become an I2C master by connecting another device, most likely a magnetometer, to the XDA and XCL pins. The breakout board also has an 16-bit ADC input pin (AD0). The GY-521 breakout board pictured takes on 5 V as power source.

The breakout board follows the schematic below:

Notable here is that pull-up resistors are already connected to the SDA and SCL pins.

Since the sensor uses I2C and the Arduino has fixed I2C pins, this is the most likely connection you’ll use when using the MPU6050:

You might notice that I attached the INT pin of the MPU6050 to digital pin 2. This is because the MPU6050 can issue an interrupt to the Arduino every time there’s new data available.

More information about the MPU6050 is on its datasheet:


Next, we’ll write a sketch to print out the orientation of the MPU6050.

Gyroscope vs Accelerometer

Before we proceed to how the MPU6050 can give orientation, let me discuss first what a gyroscope and accelerometer do.

A gyroscope can measure angular velocity, which is the rate of change of the angle an object makes with the x, y and z axes.

Consider the disk below:

The disk can rotate in six-ways: clockwise and counterclockwise on each of the three axes. If the disk is the MPU6050 then its gyroscope will give an output that describes how fast the disk is rotating on a given axis.

Meanwhile, an accelerometer measures linear acceleration over the same three axes.

Similarly, the disk can move in six ways: back and forth in each of the three axes. If the disk is attached to the MPU6050 then its accelerometer will give an output that describes how fast the disk is moving on a given axis.

Knowing Orientation

Orientation is more formally called Euler angles or yaw (θ) , pitch (ρ) and roll (Φ).

Both pitch and roll can be calculated if the linear acceleration for particular axes are known:

The yaw angle is trickier because it tends to drift with time and thus needs a constant reference such as a magnetometer or a GPS device. This is exactly the purpose of the XDA and XCL pin: for attaching a magnetometer that can help measure yaw angle.

Another issue is that the formulas above is usable only if the accelerometer values are noiseless. This is hardly the case with most accelerometers.

Thus, determining the Euler angles from raw accelerometer and gyroscope values are not that easy.

The Essential MPU6050 Library

Thankfully, the MPU6050 is different from all other motion sensing devices because of Invensense’s proprietary Digital Motion Processor (DMP).

The DMP takes on both acceleration and gyroscope data and gives out the needed Euler angles and other data.

The DMP is not fully documented until engineers figured it out by reverse engineering Invensense’s MPU6050 dev-kit. The result is the only Arduino MPU6050 library you’ll need: Jeff Rowberg’s library.

Printing Out Orientation

The library comes with several examples for you to get acclimated with it. The MPU6050_DMP6 example will give the acceleration, euler angles and quaternions if you desire. I managed to edit that example to print out just the yaw, pitch and roll values:

Explaining the Sketch

The code might be overwhelming specially to beginners.

Basically the MPU6050 object is initialized:

Then a bunch of variable declaration follows:

The MPU6050 sends out an interrupt every time there’s new data available. But the interrupt must only be enabled after the DMP is done. Hence, this part:

Inside setup(), we initialize the MPU6050:

Initialization involves several steps including waking up the device. The DMP also needs to be initialized and the function that does this returns a flag to tell the status:

The offset values, is then provided:

If the DMP successfully initialized, devStatus will be zero, hence:

Here, the DMP is turned on, the interrupt is attached to interrupt 0 (pin 2) and the MPU6050 interrupt status is read. The dmpReady flag is also set to true to signal the loop() function that everything’s good to go. Finally, the expected FIFO packet size is read.

If the devStatus returns a value other than zero, the error handler will trigger:

Inside loop(), the sketch waits for an interrupt from the MPU6050 and extra packets from the FIFO:

The sketch never exits this line unless these conditions are met. If the condition are finally met, the interrupt is reset, the interrupt status is acquired and the FIFO data is read:

In this case, we only want an interrupt status equal to 0x02 (according to the datasheet). If this is the value of the interrupt status register then it’s now safe to read the data we want.

Otherwise, we reset the FIFO.

That’s it! If you encounter any issues with the sketch, feel free to drop a comment below.




One thought on “Get Orientation with Arduino and MPU6050

Leave a Reply

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