Arduino Uno and the InvenSense MPU6050 6DOF IMU

By | March 28, 2014

A while back I bought the InvenSense MPU-6050 sensor in a “GY-521” breakout board from eBay. For a long time it sat quietly in my box of “possibly cool things to check in the future”. Recently, I decided to finally get to building a self-balancing robot and dug it out. As with almost anything from eBay, it came with no documentation.

The MPU-6050 breakout boards are quite popular in the Arduino community and information was  easy to find. Even too easy: it took me a while  to sift through many partial, or “almost” working implementations before I found a relatively easy to use, clean and reliable set of instructions and Arduino sample code. So here it is documented for future reference!

MPU-6050 Overview

According to the InvenSense MPU-6050 datasheet, this chip contains a 3-axis gyroscope and a 3-axis accelerometer. This makes it a “6 degrees of freedom inertial measurement unit” or 6DOF IMU, for short. Other features include a built in 16-bit analog to digital conversion on each channel and a proprietary Digital Motion Processor™ (DMP) unit.

The DMP combines the raw sensor data and performs some complex calculations onboard to minimize the errors in each sensor. Accelerometers and gyros have different inherent limitations, when used on their own. By combining the data from the two types of sensors and using some math wizardry (a process referred to as sensor fusion), you apparently can get a much more accurate and robust estimate of the heading. The DMP on the MPU6050 does exactly that and returns the result in “quaternions”. These can then can be converted to yaw-pitch-roll, or to Euler angles for us humans to read and understand. The DMP also has a built in auto-calibration function that definitely comes in handy, as we will see later.

The biggest advantage of the DMP is that it eliminates the need to perform complex and resource intensive calculations on the Arduino side. The main downside is that it seems that the manufacturer did not provide much information on the proprietary inner workings of the DMP.  Nevertheless, smart and creative folks figured out how to use its main features, and were nice enough to share the results with the rest of us. You can still pull the raw, accelerometer and gyro data as well, disabling the DMP, if this works better for your application, or you want to apply your own filtering and sensor fusion algorithms.

The MPU-6050 communicates with a microcontroller through an I2C interface. It even has a built in an additional I2C controller, that allows it to act as a master on a second I2C bus. The intention is for the IMU to read data from say, an external magnetometer (hooked up via those XDA / XCL pins you see on the breakout board) and send it to the DMP for processing. I have not found much detail on how to make the DMP use external magnetometer data yet, but fortunately that is not needed for my self-balancing robot at this point.

Lastly, the MPU-6050 has a FIFO buffer, together with a built-in interrupt signal. It can be instructed to place the sensor data in the buffer and the interrupt pin will tell the Arduino, when data is ready to be read.

MPU-6050 / GY-521 break-out board schematics

Below is the schematic of the GY-521 break-out board for the MPU6050 chip.


Hooking the MPU-6050 / GY-521 to an Arduino Uno

The InvenSense MPU6050 chip is a 3.3V IC, with a working voltage range of 2.375V-3.46V, according to its datasheet. As you can see from the schematics above, the GY-521 breakout board has a built in low drop-out voltage regulator, so it is safe to power the chip through the Arduino 5V rail. This is recommended, as due to the voltage drop-out of the regulator on the VCC line, using the Arduino 3.3V rail may not provide enough voltage. I tested powering the chip both with 3.3V and 5V from the Arduino successfully, but in my final set-up opted for the 5V input.

Based on what I have read online and what I saw on my tests, the 3.3V SDA / SCL lines of the IMU work fine connected directly to the corresponding Arduino 5V I2C pins. If you want to be absolutely safe, you could use a level shifter, voltage divider, or an inline 10k resistor to protect the MPU6050 I2C lines. I opted for simplicity over safety, in my set-up and (so far) all is well.


MPU6050 / GY-521Arduino UNO Pin
VCC5V (the GY-521 has a voltage regulator)
INTD2 (interrupt #0)

Arduino libraries and example code

Here is where credit and a big thanks is due to Jeff Rowberg for his I2Cdev library and sample code for interfacing with the InvenSense MPU6050 chip and partially reverse-engineering the DMP functions. Also, you might check out the “teapot demo” post from Debra at “Geek Mom Projects” that pointed me to the i2cdev library in the first place.

To get started you need to follow these simple steps:

  1. Download the I2C Device Library ( i2cdevlib ) master zip file and extract the contents to a convenient location on your hard-drive.
  2. You should see a folder called “i2cdevlib-master” that will contain an “Arduino” subfolder in it and a couple of other items, that we do not need.
  3. Open the Arduino folder and locate the “I2Cdev” and “MPU6050” sub-folders. Those are the two Arduino libraries we will need to copy to your Arduino libraries folder (here is how to install an Arduino library, in case you have not done this before).

Under the Sketch->Examples menu, you should now see a menu item for the newly installed MPU6050 library. Load the MPU6050_DMP6 example and follow the instructions in the sketch comments to define what type of serial output you would like to see from the sensor. I suggest using yaw-pitch-roll or Euler while you are testing things out, as the data is a bit more intuitive.

Find the section in the code (around line 100) in the MPU6050_DMP6 example sketch and uncomment the #define OUTPUT_READABLE_YAWPITCHROLL line. Then make sure that all other output options are commented out. Here is the section for the yaw/pitch/roll output for reference:

// uncomment "OUTPUT_READABLE_YAWPITCHROLL" if you want to see the yaw/
// pitch/roll angles (in degrees) calculated from the quaternions coming
// from the FIFO. Note this also requires gravity vector calculations.
// Also note that yaw/pitch/roll angles suffer from gimbal lock (for
// more info, see:

If all is well, when you upload the sketch to the Arduino and open your serial monitor (remember to set it at the correct baud rate), you will be prompted to send a random character via serial.

MPU6050 example output


Once you type any character in the serial input field and hit “Send”, a few status messages will appear and (if all is well)  a steady stream of data from the IMU will follow!


I charted the DMP output of the sensor (the yaw-pitch-roll data), while the breakout board was set still on a “relatively” flat service. As you can see, initially some sort of calibration algorithm is run by the DMP. Once that completes, the sensor values are very stable.


With 6 axis IMUs you can expect yaw drift. After the initial auto-calibration, the DMP compensates for most of that and only a very slight yaw drift remains (the light blue line).

Even better results can be achieved with some additional fine-tuning of the offsets in the sample code of the MPU-6050. Arduino MPU-6050 auto-calibration sketch courtesy of Luis Rodenas.

For my self-balancing robot, I will initially use the roll axis only which is very steady. Next: use the MPU-6050 to get my self-balancing robot to…well, balance!

82 thoughts on “Arduino Uno and the InvenSense MPU6050 6DOF IMU

  1. Farhan

    Thanks for quite useful information.
    I tried the similar code but the values I am getting for yaw,pitch and roll are as follows;
    ypr -68.69, 55.04, 0.55
    ypr -68.63, 55.08, 0.54

    something similar. Why I am getting too much high values for yaw and pitch while the sensor is in static position.

    Could you please help me in this regards.

    1. Stan Post author

      Hi Farah, I would imagine this is a result of the initial position of your sensor. The data I posted is when my sensor is flat on its back (the IC and the passive components on the board are facing up). There might be some calibration issues as well, but I am definitely not an expert there. I suggest checking / posting on the I2CDevLib forum:


  2. Jenish

    Please help me in finding the error. I get the error message ‘DMP Initialization failed (code 1)’.

    What should i do? Reply me, please!!

    1. Nicolás

      Hi! I have the same problem, could you finally resolve it? I’m using an arduino UNO R3.

  3. Rada

    I tried to collect data from mpu6050 but I didn’t get it until I found this site! Thanks a lot!

  4. jihen

    i followed the whole instructions, but once i open my serial monitor, i didn’t receive anything just a white background, what that means? there is an error?

    1. Stan Post author

      Hi jihen, I would suggest to doubleckeck your connections and make sure that you have selected the correct baud rate in the serial monitor (it should match the one you set in your sketch).


  5. Daniel

    hi, great tutorial, i’m too using the mpu6050 for make a self-balancing robot but i’m having a lot o problems can you help me? can i take a look in yours self-balancing robot?

    1. Stan Post author

      Hi Daniel, to be honest I have not done much on this project since the intial prototype here:

      You can find a copy of the code here:

      Warning: The code is a rough first prototype and needs a lot of work. For example: the call to the pid function should be around line 286, near the comment “// other program behavior stuff here”. Also most of this code is from the MPU6050 example and is not really needed for the purpose at hand.

      I would suggest to get things working one by one on your own (motor control, the IMU, the PID function…) . Here is a great resource on PID: that helped me a lot.

      Good luck, and post back if you make progress!

  6. Simone

    that’s a really good post. I’ve read a lot of those in this days and this one is the only
    which make a reference about the 10-20 seconds that the MPU 6050 needs in order
    to stabilize the data (in your example YPR but it is the same also for the other outputs “type”).
    However I still not understand why this period (that you call “Auto Calibration”) is so long. The
    datasheet of the MPU 6050 says it should be about 30ms.
    Moreover, in this days, I have discovered that a lot of “MPU-6050 & I2Cdev users” doesn’t have this “Auto Calibration” time of 20s when they start their sketches.
    Do you know what might causes this problem? I can’t figure it out yet 😐

    Thanks for your attention, and good luck with your blog!

    PS: I’m going to read the segwey one ASAP 😀

  7. deck

    I did test the code and it worked fine, I found one problem thou. It seems, that the Gyro doesn’t go back to the original values, after you pitch or roll it for a few seconds. If you have it lying on a flat table, move it around and then put it back, it should output the same angles as before the movement. But in my case it is off by a degree or so. The effect gets worse when you move it longer or in more extreme angles. What could be the reason?
    Can this be solved with sensor fusion? Any idea?
    thank you and kind regards,


  8. Somesh

    Hi Stan,
    I got my circuit up properly and with the i2c-scanner sketch the slave is detected at 0x68. I got I2CDev and MPU6050 in libraries/ folder. I am trying to get the MPU6050_DMP6 sketch to compile on Arduino IDE (1.0.1 ubuntu) now, but file I2CDev/msp430_i2c.c has a header which the compiler is not able to find.

    Are there any other installations/libraries I need to do use beside the Arduino Core libraries and i2cdevlib ??


  9. Kumar

    First thanks for nice article. Recently I interfaced ADXL335 and it has X,Y,Z pinouts to AVR MCU WORKING FINE.Today i purchaced MPU6050 accelerometer but there is not X,Y,Z pins in it can you please help me on it.

    1. Stan Post author

      Everything you need to get readings from the MPU6050 is covered in the post and in the i2cdevlib sample code by Jeff Rowberg.

  10. SimonR

    Stan – thanks for posting this! I’ve been trying to get this damn board to work all day, but with the addition of your DMP code, suddenly, it produces good values!
    Give yourself a gold star!

  11. Snehal Patel

    cool!!!! You save me lots of my time….
    Good job with ease of code…

    thanks a lot

  12. Firoz Dang

    Great thanks man…. I tried this today and it works great….I was not able to do it with so many other codes…thanks again….

  13. Emsity

    Many thanks for this great article.
    I brought a MPU6050 from ebay (arrived by China post). I hooked it up as instructed, but all I can see is goobledeegook letters.
    Any ideas?

    1. Stan Post author

      I would doubleheader that the baud rate in the serial monitor matches that of the sample sketch.

  14. Guilhem

    Hey Stan and the others,

    Thanks a lot for the sketch and the advices, it compiles well and works quite fine. However I still have a couple of problems:
    – as you say in your post, even after calibration, I always get values that are not equal to 0 whereas I’m on a flat table
    ypr 33.63 0.28 0.55
    ypr 33.63 0.28 0.55

    Is there a way of changing the DMP code or the MPU6050’s library to set the values to 0 when calibrated ? Otherwise this can easily be corrected in the arduino sketch by retrieving the calibrated values at each measurement, so this is not my main concern

    -My may concern is that the angles seem not right at all for the pitch and roll (around 30° for a real 45 degrees angle, around 70° for a 90° angle, and never gets to 90 even by turning the sensor by more than 90 degrees…). Has someone the same problem ? Is it coming from the code ? Or maybe my sensor is fucked…!

    Thanks a lot for your answers!

    P.S.: I guess this is more an electronic problem, but when adding a servo moto which angle depends on the MPU6050 values, after a few seconds is starts turning right and left likre crazy and the accelerometer values start fluctuating a lot, any idea ? (I added a capacitor to limit current fluctuations, but maybe it’s not enough,…)

    1. Shrest

      Im have a similar problem, I get zero offset of around 0.5, about 14deg for 15 deg angle, about 28 deg for 30. I was looking for solutions to make it more accurate. Could you a solution for improving your readings, if yes, please share.Thanks.

    2. xpeace

      I also got severe problems with 90° angles using the default DMP6 YPR example.
      Tilting the sensor to +/-90° results in +/-80° degrees output,
      very slowly increasing to +/-90° in about 10-15 seconds (Pitch + Roll).
      Yaw values seemed more reasonable, …

      Arduino Nano + MPU6050 DMP6 Code Example.
      Any help on this issue is highly appreciated.

    3. Friedemann

      I have a very similar Problem, instead of 90° I get only like 80° – the Values is very slowly increasing (15-20 seconds).
      Arduino Nano V3 DMP6 standard Example.

      1. Jiangyan

        I have the same problem. the pitch value can not reach 90°.
        when i put the sensor vertical , Pitch value can only 70°+.
        when i put the sensor 60, Pitch value can only 45°+.
        when i put the sensor 30, Pitch value can only 20°+.

  15. Tyrone

    Hello Stan,
    I could use your help with the PID you used with the balance robot. After carefully studying the ” int pid() “part.
    I am confused on how the PID ” out”, controlls the motors to keep the bot balanced.
    (int out = (int)pid * (-1); // not worried about correct rounding here
    return out;) Out is only stated here in the code once.

    I understand in the code how ” drive(0,0);” can move the balance bot motors while its balancing.
    But how and where in the code is the PID “out” equal to
    void drive(int leftMotorSpeed, int rightMotorSpeed). To keep the balance bot balanced.
    Now to tell you what I am trying to accomplish with your PID.
    I have spent a great deal of time learning about encoders. So I can be sure that both motors on the balance robot move at the same speed, and return to the correct position if pushed.
    So how do I connect just the ” leftMotorSpeed” to the “out” of the pid, so only that motor is part of the PID?
    There are other PID codes out there I could use, but yours is the one i want to use. Just a little confused.
    Thank you for your help.

  16. Martin

    Hi Stan,
    Really great article. Many thanks. I’m starting out – with almost no experience at all.
    I see you’ve connected the SDA/SCL pinouts from the MPU to Pins A4/A5 on the Arduino.
    I have the latest version of the Arduino, with SDA/SCL pins (I2C bus) on the Digital Data port.
    I would have assumed that the logical” way to connect the GY-521 board to the Arduino would be to linkup both of the SDA/SCL pairs, on each side.
    My question is: why did you not use the SDA/SCL pins on the Arduino?

    1. Stan

      Hi Martin, glad to see you found the write-up helpful! As far as I know, the SDA and SCL pins that are near to the AREF pin on the Arduino Uno are essentially connected to the A4/A5 pins. The Atmega328p on an Uno uses the A4/A5 pins for I2C. The pins were duplicated near the AREF pin to allow for compatibility of shields across certain Arduino boards. Bottom line, you can use either pin combo, but if you communicate via I2C, you can’t use the A4 / A5 pins on the Uno for anything else. See the notes here: and here:,141609.0.html.

      Cheers, Stan

  17. Morduino

    Thank you for your effort. I have trouble with serial monitor outputs. Also, when the baud rate is as listed above 115200, the serial monitor screen goes blank. Trying with a different baud rate, it initializes but no further data appears and the readings are zero.

  18. Xavier

    Hey there! Thanks for the tutorial! 🙂

    I just want to ask you one silly question! Those Roll angles that you get from the DMP correspond to the rotation around the X axis indicated on the chip? Or do they correspond to the Y axis on chip?

    1. riz

      stan your blog is very helpful indeed. i’ve chosen inverted pendulum as my final year project. i have this confusion though. euler angles that we get by using DMP example sketch, does it need any more filtering like complementary filter or kalman filter. or these values can be used as it is further without sensor fusion and things? looking forward to your answer!

      1. Stan Post author

        Thanks, Riz, I am glad you found the post helpful. From what I read about this sensor, you have two possible paths: (1) get the raw output of the accelerometer and gyro and do your own filtering and merging of the sensor data (2) get the output of the proprietary, built in DMP module, which does that for you. The advantage of option (1) is that you have more control and can merge the data with readings from other sensors, like a compass. I have only tried the second approach, but Jeff Rowberg’s library definitely allows you to pull the raw readings from the sensors as well.

  19. Hohite Fetene

    I wanted a code to compile a raw data thats detects an angle for a segway. I havea 6 axis gyro sensor with an arduino. can you please help me out.

  20. Kashifa

    Hi Stan

    I followed all the steps listed but when I compiled the sketch it gave me the problems:
    Exception in thread “Thread-309” java.lang.NoClassDefFoundError: Could not initialize class

    Im searching for the solution online but cant find anything helpful to remove them.’
    Please help!

  21. Kashifa

    I managed to solve the problems listed above but after compiling it says MPU6050 connection failed and DMP initialization failed (code 1).

    I tested all my connections and they are fine, can’t seem to find the reason why the MPU6050 failed.

  22. Kashifa


    I followed all the steps and when I ran the code it said MPU connection failed and DMP initialization failed(code 1)

    Please help!

  23. Jacob Williams

    whats the solution for ‘MPU6050’ does not name a type ???? 🙁

  24. Pingback: UBOARD » GY521 (MPU6050) Basic Theories + Testing (1)

  25. bharath

    If i am moving my palm having imu sensor vertically,Then can i have the height of the hand raised from initial position…If u can calculate it how presice is it..plz do reply


    I managed to solve the problems listed above but after compiling it says MPU6050 connection failed and DMP initialization failed (code 1).

    I tested all my connections and they are fine, can’t seem to find the reason why the MPU6050 failed.

    Reply ↓

  27. Clonkex

    Does the MPU-6050 REQUIRE the interrupt to be connected to the Arduino? Because without the pin connected, the I2C bus can’t see the device. From what I can tell (by reading a couple of registers on the MPU-6050), the motion interrupt is turned on, so why on earth is the pin required??

    1. Clonkex

      Ah, don’t worry, I finally figured it out. I wasn’t using a common ground between the power supply of the MPU-6050 and that of the Arduino. Now it works just fine without the interrupt pin connected 🙂

  28. Heather

    Just wondering was is the interrupt time/at what speed are samples being taken?

  29. Heather

    What is the interrupt time/ how often are samples being taken for this code? cheers

  30. James

    I’m trying to use an Arduino Pro Mini (ATmega328 5V 16MHz), I keep getting the error during compile:

    /Documents/Arduino/libraries/MPU6050/MPU6050.h:611:17: error: candidate is: uint8_t MPU6050::getMotionStatus()
    uint8_t getMotionStatus();

    Any help is appreciated.

    Thank You

  31. Linden

    This is a great little tutorial and had me up and running about 5 minutes after reading it! There are so many half baked tutorials out there for this board, I wish I had found this first as it would have saved me a lot of wasted reading and searching time!
    Thanks very much Stan!!!

  32. AmieraSyafika

    Hai Stan;

    i’m now doing a project for balancing a rov. i use mpu 6050 as my imu sensor. i have some problem on how to connect my motor with the sensor. i use l293d. i take the reading value from #define OUTPUT_READABLE_YAWPITCHROLL

    my question is, how i can modified the coding? let say if my yaw value is >30 i need to on the motor until it reach 30. can you help me? thank you

  33. AmieraSyafika


    i’m now doing a project for balancing a rov. i use mpu 6050 as my imu sensor. i have some problem on how to connect my motor with the sensor. i use l293d. i take the reading value from #define OUTPUT_READABLE_YAWPITCHROLL

    my question is, how i can modified the coding? let say if my yaw value is >30 i need to on the motor until it reach 30. can you help me? thank you

  34. Sarvesh Thakur

    I have included all these header files and still my code is not compiling. It is stuck.

    —code removed—
    can anyone help?

    1. Stan Post author

      Hi Sarvesh, if you followed the wiring instructions above, installed both the i2cdev and MPU6050 libraries, then this should work (I tested it over the week-end as I re-started my work on a self-balancing robot). Usually, compiling errors occur if a library is missing. If you are still having problems, you may have more luck posting your question on the The specific error message you are getting when you run the vanilla examples from the MPU6050 libraries will help.

  35. Sam

    The yaw is probably drifting because it can’t be corrected with the gravity vector from the accelerometers. Even a perfect gyro will drift in heading from the earth’s rotation. Thus 9 DOF sensors with magnetic feelers. But I wonder if it isn’t already doing a true north calculation by finding the axis with the least angular change relative to gravity. Thanks to earth’s rotation it’s possible to fix yaw drift everywhere except at the poles… as exploited by the gyrocompass.

  36. Mayur

    Hi Stan,
    First of all I really appreciate all the efforts you put in making such a great article. So thanks for that. Second of all, I’m posting here just to realize what tool did you use to draw the circuit diagram ? As I can guess, you didn’t use Proteus, because It doesn’t have MPU-6050 library in it and Eagle is also out of question. It’s just that I need to draw this circuit for my project but with minor modifications.
    So if you could please help me out.
    To other readers, I’m all ears.
    Thanks again. Have a good day ahead.


    1. Stan Post author

      Hi Mayur, I believe I started with Fritzing, but then edited the image directly in an image editing program.

  37. Pingback: MPU6050 learning notes | tlfong01

  38. afzal

    how i can interface two or more mpu6050 and how i can i made connection and pin interrupt ?

  39. Abhishek

    Hi Stan,
    I’m working on “AIR MOUSE”(final year project).
    I have a MPU6050 gyro/accelerometer/temperature sensor for mouse control. And “how can I make use of accelerometer values from your code to position mouse cursor on computer”. I want real co-ordinates of mouse on PC from the tilt of the MPU6050 IMU sensor. How to do that? I am using Arduino UNO R3. Sorry for my bad English. Please help me out in this.

  40. Rhythm khanna

    Hello author,
    First of all thank you so much for a useful and complete guide on how to use the sensor with arduino to build cool projects. My project is smewhat different as I want to build a gesture recognition algorithm that can determine arm length gestures using this mpu6050. The pitch, roll and yaw values are great for determining static orientation but I am confused about detecting complete movement of the hand. It will be of great help if you or anyone can guide me on this. I will mention you on my capstone project report as contributors. 🙂
    Thank you.

  41. Pingback: Estabilizador Parte 2 – Proyectos Personales

  42. Maddo

    First thanks to the author for this good guide and the Sketch.
    I tried it out with a LED. It schuld light up when I move the MPU. That worked prettx fine.
    Now I tried to Control a servo, but it always tells me “FIFO oveflow”.
    What coauld be a reason for this?
    Here you can see how I want to control the servo:

    if(euler[1] * 180/M_PI >5 || euler[1] * 180/M_PI 5 || euler[2] * 180/M_PI <-10)
    for (pos = 0; pos = 0; pos -= 5) {

    I hope somebody can help me to solve the Problem.
    Thanks in advance.

    1. Maddo

      And here is the missing “else-part”
      for (pos = 180; pos >= 0; pos -= 5) {

  43. Mimansa

    I am getting very drastic fluctuations when in editing the same DMP_6 example code as per my requirement.I just added few simple lines for blinking of led along with my the examples line present.

  44. whiletrue

    Nice post, thanks for that. Can you please share how to stop/sleep the MPU6050? I want to be able to activate/desactivate it remotely but I’m not finding how to deactivate it anywhere. Thanks in advance.

  45. bala

    Hi im getting this error when i try to add the library to my Arduino. can anyone help please.
    Specified folder/zip file does not contain a valid library .

  46. sid

    Hi Stan,
    i tried for the example code from MPU6050 example MPU6050_DMP6 it gave no error in compiling.when i uploaded it serial monitor was showing MPU6050 connection failed but i2c scanner detected i2c device at port 0x68 what should i do

  47. JaJoMa

    thank you for your article.
    we use it for an scoll projekt but after the message “Initializing I2C devices…”.
    I don’t know what to do know. Hope you can help.

  48. Len Manning

    I have set this up as per instructions, and it communicates and talks to the serial monitor.
    However I appear to get a set of random numbers generated.
    Do you think the board is broken?
    It is lying on the desk with the IC upwards not moving.
    Printout below.

    euler 18.49 nan 44.46
    euler -180.00 -1.95 -173.34
    euler 10.85 3.89 -3.89
    euler -179.60 -0.06 179.99
    euler 30.31 nan 61.53
    euler -29.27 42.85 156.64
    euler 180.00 0.00 -180.00
    euler -55.09 nan 106.28
    FIFO overflow!


Leave a Reply

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