Download PDF Parts List View on YouTube Download Code


The MPU-6050 is a low-cost, highly accurate IMU with 6 degrees of freedom. Don’t fret if that last sentence sounded like a foreign language, all will be explained soon!

Today we will look at the MPU-6050 module to see how it works and how to use it with an Arduino. We will also build a very sensitive electronic level.  Although our level will be constructed on a breadboard it could also serve as the basis for a permanent project.

MPU-6050 IMU

The MPU-6050 belongs to a class of devices known as Inertial Measurement Units, or IMUs.  These devices can measure acceleration, inertia and a number of other parameters to allow you to determine their spatial position and velocity.

MPU-6050 Electronic Level with Arduino

IMUs like the MPU-6050 are used in a number of different applications:

  • UAVs like quadcopters and helicopters. Here an IMU is used to determine yaw, pitch, and roll, and to level the devices while flying.
  • Robotics. From balancing robots to robot arms it is common to make use of IMUs to establish position and velocity.
  • Game Controllers. Games like the Wii use an IMU to detect level and motion.
  • Phones and tablets. It is common to find IMUs in phones and tablets for determining the orientation of the device to switch between portrait and landscape modes.
  • Hard drives. An IMU or accelerometer is included in hard drives designed for portable use. They can detect if the drive is being dropped and take appropriate action, like stopping the platters and locking the heads.


One of the key components of the MPU-6050 is an Accelerometer.  As its name would imply, this is a device that can measure acceleration.

Acceleration is described as being the rate of change of the velocity of an object. An object moving at a constant speed does not have any acceleration.

A common unit of acceleration is G-force. One G-force here on Earth is 9.9 meters per second squared, which is the acceleration of gravity here. On other planets the figure is different.

An accelerometer needs to take into account static acceleration like the force of gravity when making its measurements.

The accelerometer used in the MPU-6050 is a triple-axis accelerometer, meaning that it senses acceleration on an X, Y and Z axis.


Another key component in the MPU-6050 is a Gyroscope.

A gyroscope can measure angular momentum or rotation along the X, Y and Z axis. These components are critical in maintaining balance for aircraft and spacecraft.

A mechanical gyroscope consists of a wheel or disk mounted so that it can spin rapidly about an axis which is free to move in any direction.

The type of gyroscope used in the MPU-6050 is a “Micro Electro Mechanical System” or MEMS gyroscope. It consists of three sensors, one per axis, that produce a voltage when they are rotated. This voltage is internally sampled using a 16-bit analog to digital converter.

External Sensors

The MPU-6050 can also make use of external sensors. These external devices are interfaced to the MPU-6050 using a second I2C bus, independent of the main I2C bus.

A common use for this external connection is to attach a magnetometer, which can measure magnetic fields on three axes.

This adds an extra three Degrees of Freedom, or DOF, to the sensor. By itself, the MPU-6050 has 6 DOF, three each for the accelerometer and the gyroscope.  Adding a magnetometer would give it 9 DOF.

The MPU-6050 also has an internal temperature sensor.


The data from the accelerometer, gyroscope and any third-party sensors is passed to an internal Digital Motion Processor, or DMP.

This device correlates the data and formats it to be used on the I2C bus. It is essentially a high-performance microprocessor that is dedicated to processing motion data.

The term DMP was coined by Invensense, a division of TDK. This is the company that developed the MPU-6050, along with many other IMUs.


The MPU-6050 is available in several different configurations and on several different breakout modules.

Here is an illustration of the pinouts of the module that I am using in these experiments:

MPU-6050 Pinouts

This module has an internal voltage regulator, so it is supplied with 5-volts power. The MPU-6050 chip itself uses 3.3-volt logic. The module also has resistors to change the data levels to 3.3-volts.

The pin descriptions of the module are as follows:

  • VCC – 5-volt DC power supply.
  • GND – Ground
  • SCL – This is the I2C clock line.
  • SDA – The I2C data line.
  • XDA – This is the external I2C data line. The external I2C bus is for connecting external sensors.
  • XCL – This is the external I2C clock line.
  • AD0 – This line allows you to change the internal I2C address of the MPU-6050 module. It can be used if the hmodule is conflicting with another I2C device, or if you wish to use two MPU-6050s on the same I2C bus.
  • INT – This is the Interrupt Output.

If you are using a different module you can still perform the experiments listed here., Pay attention to the power requirements of your module as some do not have an internal voltage regulator and operate on 3.3-volt logic.

Note that the module also has orientation markings, to allow you to position it correctly in your device.

MPU-6050 with Arduino

Before we build our electronic level let’s do an experiment using the MPU-6050. To make things a bit easier we will use a couple of libraries and run a demonstration sketch that is included with one of them

I2C and MPU-6050 Libraries

The libraries we are going to be using in our demo are part of the collection of libraries developed by Jeff Rowberg for working with the I2C bus and some common I2C sensors. You can find the complete set of libraries on Github.

This is an extensive collection of libraries, not only for the Arduino but for a number of other common microcontrollers as well.

As it is a bit overwhelming you might find it useful just to get the two libraries we are going to use today – the I2C Development library and the MPU-6050 library.

If you would like more information regarding this excellent set of libraries visit Jeff’s webpage dedicated to I2C development.

These libraries are provided in ZIP format. You can install the ZIP files directly into your Arduino IDE.

  • Open the Arduino IDE.
  • Select the Sketch menu from the top menu bar.
  • Select Include Library. A sub-menu will open.
  • Select Add ZIP Library.
  • A dialog box will open. Navigate to where you saved the libraries and select one of them.
  • The library will be installed into your Arduino IDE.
  • You will need to repeat this step for the second library.

Now that you have the two libraries added to your Arduino IDE it’s time to hook up the MPU-6050 to the Arduino/

MPU-6050 and Arduino Hookup

Here is the hook up that we will use for the experiment:

MPU-6050 Arduino Hookup

The connections are pretty simple, as the MPU-6050 interfaces using the I2C bus. On the Arduino Uno the I2C connections are made using the Analog input pins, A4 is the SDA connection and A5 is the SCL.

We are also using the interrupt output from the MPU-6050. This connects to pin 2 on the Arduino Uno, which is interrupt number 0.

Demo Sketch

When you have everything hooked up try running one of the demo sketches provided in the MPU-6050 library we just installed.

  • Open the Arduino IDE.
  • Select the File menu from the top menu bar.
  • Select Examples. A sub-menu will open up.
  • Scroll down the sub-menu to the section entitled Examples from Custom Libraries.
  • Look for the MPU6050 entry and select it.
  • Another sub-menu will open that says Examples. Select it and two example sketches will be listed
  • Select the MPU6050_DMP6 sketch.

The sketch is quite complex but is very well commented. It will give you a taste of how much math is involved in extracting useful information from the MPU-6050 sensor.

Note that you will need to set your serial monitor to a speed of 115200 baud to try the sketch. There is a lot of data being sent back from the IMU and it requires this higher speed to display it.

MPU-6050 Demo

When you open the serial monitor with the sketch loaded to the Arduino you should see a message saying that the connection to the MPU-6050 has been made successfully.  In order to start running the sketch you need to place your cursor in the serial monitor input box and type a letter, then press Send (or just hit Enter on your keyboard).

You will see a wealth of data displaying the Yaw, Pitch and Roll values. Try moving your sensor around and note how the data changes.

Electronic Level Project

Now onto our electronic level project.

We will build a sensitive level that has both a digital and LED display. The LED display will show you if you are within a degree of being level, if you dare close or if you are over 2 degrees off.

Although I am building this on a solderless breadboard as an experiment this is a good candidate for a permanent project, as it is a truly useful device. If you do decide to build a permanent version of this device you may want to use an Arduino Nano or Pro Mini to save space.

Electronic Level Hookup

Here is the hookup diagram for our electronic level:

MPU-6050 Arduino Electronic Level

The LCD display I am using has an I2C adapter on it to make it easier to connect. It is a 2-line, 16-character display, a very common item.

I used a green LED to indicate that it is level, yellow LEDs to indicate that you are close and red LEDs to indicate you are more than 2 degrees off. You can substitute other colors if you wish, or just use a LED bargraph display.

The dropping resistors I used were 220 ohms, but any value from 150 to 470 ohms will suffice.

Electronic Level Sketch

Here is the sketch I used to make the electronic level work:

This sketch requires another library, the NewLiquidCrystal Library for I2C. You can download the latest version from BitBucket. It is a ZIP file, once again you will need to install this into your Arduino IDE.

Unlike the last sketch, it does not use any custom libraries for the MPU-6050. Instead, the Arduino Wire library for I2C is used and the registers in the MPU-6050 are manipulated directly.

At the beginning of the sketch in the Setup, we calibrate the sensor by reading the acceleration and gyroscope data 100 times. This is then averaged to get a baseline.  Because of this operation, the device will delay a few seconds before it gives its first readings.

Again there is a lot of math in the sketch. Unlike the previous sketch, we are just interested in obtaining the Pitch and Roll values in degrees.

As the data is extracted too quickly for the LCD display to handle we use a counter and just take a reading for every 100 passes.

During the pass that we take to update the display we also look at the Pitch value and use it to determine which LED to illuminate.

MPU-6050 Electronic Level Demo

Load the sketch and run it. After a delay of a few seconds, the LCD display should show the angles, both pitch and roll. The LEDs should light appropriately.

Try moving the level around and note the readings and the LED display.  If you have a conventional level try comparing readings.


The MPU-6050 is a very useful device that has brought a lot of advanced technology to Arduino makers, at a very low price. It has many uses, and we will be using it again in several projects in the future (including the DB1 Robot project).

So get out your breadboard and dream up some well-balanced projects!


Parts List

Here are some components that you might need to complete the experiments in this article. Please note that some of these links may be affiliate links, and the DroneBot Workshop may receive a commission on your purchases. This does not increase the cost to you and is a method of supporting this ad-free website.




Electronic Level Sketch – The sketch used to create the electronic level.

Jeff Rowberg’s I2C Dev Library – The I2C development library for Arduino, by Jeff Rowberg.

Jeff Rowberg’s MPU-6050 Library – The MPU-6050 library for Arduino, by Jeff Rowberg.


Build a Digital Level with MPU-6050 and Arduino
Build a Digital Level with MPU-6050 and Arduino
Article Name
Build a Digital Level with MPU-6050 and Arduino
We will look at the MPU-6050, an Inertial Measurement Unit that contains both a gyroscope and accelerometer. We will use the MPU-6050 to build a digital level with both an LCD and LED display.
Publisher Name
DroneBot Workshop
Publisher Logo
Tagged on:     
Notify of

Inline Feedbacks
View all comments
Michael S
5 years ago

I love all your tutorials a lot, including this one.
You’re one of the best providers of clean and useful information on the subjects of your projects.

Only one shortcoming I see is that you don’t provide any references to the websites where components used in the projects can be purchased.

Thanks again for your great tutorials.

philip wamutitu
5 years ago

hi am a keen follower of your articles from kenya. i recently got an upgrade on my computers operating system to windown 7 ultimate. however my arduino cannot communicate with my laptop. on the device manager the coms and Lpt are not visible, so are other devices hence i cannot configure the arduino drivers. any assistance is welcome.

Thomas Borns
5 years ago

First of all I have to praise you for these really well done tutorials. There are a lot of them on you tube, but yours are among the best. But now to my problem: I copied the mpu-6050-level tutorial, but get an error message when trying to upload the sketch to the arduino. In line 23 ” LiquidCrystal_I2C lcd(i2c_addr, en, rw, rs, d4, d5, d6, d7, bl, POSITIVE); appears the message : ‘POSITIVE’ was not declared in this scope What could be the reason? Unfortunately I can’t find my mistake. Maybe you can help me with a solution. That would… Read more »

Walter Hynson
3 years ago
Reply to  Thomas Borns

look at the exemple I2C lcd sketch and copy and past while // out all that does not work

Thomas Borns
5 years ago

First of all I have to praise you for these really well done tutorials. There are a lot of them on you tube, but yours are among the best. But now to my problem: I copied the mpu-6050-level tutorial, but get an error message when trying to upload the sketch to the arduino. In line 23 ” LiquidCrystal_I2C lcd(i2c_addr, en, rw, rs, d4, d5, d6, d7, bl, POSITIVE); appears the message : ‘POSITIVE’ was not declared in this scope What could be the reason? Unfortunately I can’t find my mistake. Maybe you can help me with a solution. That would… Read more »

Thomas Borns
5 years ago

Hi Bill
Thank you very much for the very quick reply. She helped me a lot. The problem was actually a second LiquidCrystal library. Now everything runs as expected. I am looking forward to more interesting workshops.

Jason B
5 years ago

Great tutorial! You always go into detail with all your projects and I find your videos to be some of the best. I subscribed to you on youtube and here but cant find where to suggest an idea or ideas. So I figured I would do it on here via comments.

Project 1: 4xi Draw Machine (Super Cool) –
Project 2: Transmit music via laser or any data (plain text documents) for that matter

Thanks again for all the great videos. I’m not an engineer by trade. I just find everything super cool! Thanks!

5 years ago

Great project, and well written as well as easy to follow. I do have a question, though. When you power on the project, does it record that position as level, and reference it, or does it store “true” level and reference that? (I don’t have a two line display handy, else I’d test it for myself.) I ask because I’d love to have a remote level for my RV (caravan) so when I am parking I can choose the spot that is closest to level in order to save time and frustration.


5 years ago

Thanks a lot for your tutorial. It works great. By the way your sketches work as is and I do not have any problems to run them. I have a question. I would like to make this project as small as possible. I would like to replace the display with 0.96″ oled. I know you are very busy but it would be great if you be so kind and add a scketch with the 0.96″ oled display. Thanks a lot.

4 years ago
Reply to  Prompt


Did you get the code sorted for use with an OLED display?

Would you share it please?



3 years ago
Reply to  Prompt

I have modified the code to display on a NOKIA 5110 if that is any help?

Bob Nowacki
5 years ago

Hi Bill, First, thanks for the great work you do in creating your videos! You’re very clear in your explanations, and you cover many topics that have value for me. However, I am confused about something after trying your “Electronic Level” sketch. After putting in the correct I2C address for my particular display, everything works. But despite the fact that my solderless breadboard (with the MPU-6050 plugged into it) is sitting on a flat and level desk, it shows a pitch of over 16 degrees, and a roll of nearly 8. Just in case I was going crazy, I checked… Read more »

4 years ago
Reply to  Bob Nowacki

Hi, Steve hear,

Do you have the code that included using an OLED display rather than the LCD?

I am a little stuck getting this to show on an OLED display.

I could do with a helping hand.

Nic Mann
4 years ago

Hi, I’ve been working on an arduino project for school in which I am using an MPU 5060 to determine weather an object is level or not. I was wondering if there were a way to edit your code so that the data could be displayed with in the serial monitor. I have tried to take your code and edit it but so far have has no luck as this is my first experience with arduino and am still having a bit of trouble when It comes to deciphering how the code works. Any advice you have would be much… Read more »

Joseph TETE
4 years ago

Hello, My Name is Joseph TETE, and yesterday, I saw your video entitled : “Build an Electronic Level with MPU-6050 and Arduino”, and I found it amazing. Everything is well explained, and you take time to detail everything : all the objects to use, the connections to make, the code to write, etc. So, even if I’m a beginner on Arduino, I decided to make this electronic level, my first Arduino project. However, I have every object needed (Arduino UNO, LEDs, MPU-6050 and resistances) but I don’t have the LCD screen. So, I copied the code and put in comment… Read more »

Umit Ozdemir
4 years ago

Very good explanation, good pronanciation and slow speaking is well to understand.
Thank you !

4 years ago

Excellent articles even layperson ca follow .
Teaching in a different way that is commendable and adorable. I thank you very much for producing tutorials and video with informative and technical never experienced before .
Thanking you for your continuous ambition to impart good technological matter without cost.
God bless you with good health and happiness.

4 years ago

thanks for the code and tutorial. I wanted to get the output in terms of pwm signal. But whenever i connect a pwm wire, the output gets stuck. display gets stuck. can you please help me out?

Bambang Wibawa
4 years ago

I like your tutorials !
God Bless U

A. Rod
4 years ago

It works without a LCD display?

4 years ago

I tried to upload the libraries but audrion said that the file doesn’t contains a valid library. Please help, thanks

Kostis Panagiotou
4 years ago

Really great tutorial. Can you help me expand this circuit? I want to make an application that uses mpu6050 in order to control a motor that controls a laser module, with cross line as output, through gears.

4 years ago

Thanks for do this tutorial. As a beginner in Arduino its helpful to have the code explained to me. I would like to use your code into a inclinometer project for my Jeep, so that I can keep an eye on pitch and roll as I drive offload.
I may not be able to mount the IMU level. Is there a way to calibrate for the varience in your code? If not, do you have suggestions on what I might add, or I resource that I can look into?
Thanks again

None Of Your Business
4 years ago

Yeah, I would love it if you didn’t shove your stupid newsletter down our throats and leave this annoying comment box on the screen with apparently no way to remove it.

Crazy Minds
3 years ago

good project . i have subscribed your channel hope you will support me too. my channel name is crazy minds with symbol of a brain and a bulb. thanks…

3 years ago

As always a great tutorial. I modified the code to display on a NOKIA 5110 but when I make large movements of the sensor the program freezes. I’ll ask on the forum but any suggestions here?

3 years ago

Thanks for taking the time to produce this. I do have a query though. If I raise the module to affect the angle on the Y axis, say up to 80 degrees, it takes a while for the readings to catch up. They will go to, say 76 degrees then take 5-6 seconds to reach 80. When I then lower the unit flat. it drops to 3 or 4 and then takes several seconds to reach 0 again. Has anyone else had this issue? Also, it would be nice to have a little more information on the maths involved, even… Read more »

3 years ago


Amit Meyuhas
3 years ago


It is very good and ordered tutorial.
You wrote: “The module also has resistors to change the data levels to 3.3-volts”
which is not right! all the pins are up to 3.3V only. the I2C may work but only in case you are not using any pullups to 5V (as well as connecting other I2C with 5V like serial LCD…)

Gary M. Oosta
3 years ago

I just built the first example. Today, it is running smoothly – even the euler output.
At first, I kept having FIFO overflows and shutdowns. That sent me to the Arduino forums which were not too helpful. It turned out that on my breadboard the interrupt wire was not completely solidly connected. I soldered the lead wires to the MPU-6050 and the FIFO overflows disappeared. Onward now.

Gary M. Oosta
3 years ago

Just got the second demo to work. Toughest part was getting the code for my LCD 1602 I2C to work in the sketch. Thanks.

3 years ago

with 5 leds, you can make it more precise swap your led code with this for common anode led chain [code]  if (angle_pitch_output <= -3 )   digitalWrite(levelLED_neg1, LOW);  else   digitalWrite(levelLED_neg1, HIGH);  if (angle_pitch_output <= -.5 and angle_pitch_output >= -4 )   digitalWrite(levelLED_neg0, LOW);  else   digitalWrite(levelLED_neg0, HIGH);  if (abs(angle_pitch_output) <= 1 )   digitalWrite(levelLED_level, LOW);  else   digitalWrite(levelLED_level, HIGH);  if (angle_pitch_output >= .5 and angle_pitch_output >= 4 )   digitalWrite(levelLED_pos0, LOW);  else   digitalWrite(levelLED_pos0, HIGH);  if (angle_pitch_output >= 3 )   digitalWrite(levelLED_pos1, LOW);  else   digitalWrite(levelLED_pos1, HIGH); [/code] outside leds for over 3deg next led for .5 to 4deg center led for 1deg 2 leds can be on… Read more »

Andrew Steenbuck
3 years ago

Hi, I’ve been following along with your tutorials for a while now, but I’m having problems with the MPU sketch with an ESP32. I am running the code as downloaded, with the exception of commenting out the LCD code, and I’m using Serial.print to print out the pitch and roll. The MPU is sitting on the breadboard on my desk without being touched, however the numbers for roll seem to be counting up while the pitch number seem to be counting down. If I do touch the MPU to try and test a change, both pitch and roll numbers both… Read more »

Last edited 3 years ago by Andrew Steenbuck
NZ Mark
11 months ago

Hi Andrew,
Your post is quite old, but I’ve experienced the same issue. If I use an ESP32, I get NaN. If I use an arduino uno, it all works OK.
Strangely, If I boot the ESP 32, with the sensor upside down, it does initially show numbers, but if I apply any inclination angle, the numbers are disproportionate to the angle e.g. -729degrees and it eventually becomes NaN and stays stuck that way until reboot. No conclusions / solutions as to the problem yet.

Alan T
3 years ago

Tried to import the sketch to a XIAO but it didn’t like TWBR and refused to compile. Any ides?

Walter Hynson
3 years ago

the lcd script does not work ,so I copied and pasted from a test sketch for the I2C lcd and bingo it compiles next I will test to insure it works

eya nagazi
3 years ago

I love your tutorials thank you

3 years ago

i want to do rc car with MPU6050 but i can’t used …..can i have some help?

Angelo Miguel Nascimento
2 years ago

Kann i add on led outputs a motor to going UP an down?

Tobias L
2 years ago

Can someone please explain the derivation of the two following formulas to me:

  //If the IMU has yawed transfer the roll angle to the pitch angle
  angle_pitch += angle_roll * sin(gyro_z * 0.000001066);
  //If the IMU has yawed transfer the pitch angle to the roll angle              
  angle_roll -= angle_pitch * sin(gyro_z * 0.000001066);   

I’ve been sitting over it for days and just can’t figure it out.
And thanks for the gread video!

Stuart Blair
2 years ago

Loved this. It was just what I was looking for. I was looking through the listing trying to reference the MPU 6050 register map on page 14. I know the comment at line 270 indicates that we’re configuring the unit to have a full scale range of 500 degrees per second, but unless I’m mistaken, line 266 is configuring it to have a full scale range of 2000 degrees per second when it sends hex value 0X08. Also loved the damping approach. After I read that, I was picturing a spirit level with filled molasses, allowing the bubble to slowly… Read more »

2 years ago

Love the info in these videos, It’s helped me along a project I’ve been working greatly. I need some help with changing the function of the code though. I’m building a digital inclinometer for a lapidary machine and need horizontal to be 90 deg and vertical to be 0. Is there a way to do this in the code?
Thanks again for all the great videos.

Wayne H
2 years ago

Hi Bill,
In my 50+ years of electronics and engineering, I find your tutorials very well done.
I am enjoying what you are doing.

All The Best,

2 years ago

I am sorta like a newbie with this arduini/raspberrypi thing and all I can really do is send you a big thank you and let you know that I am really appreciative for all your hard work.
Again thank you and god bless you and family/

2 years ago

Bro, fantastic !! and I like it very much. But just a question, what is the unit of pitch and roll data on the LCD ? in degree/ sec or radian/ sec or degree? I m confused. Btw, I see there is no yaw data, could you advise how to dedrive the Yaw information too? thanks.

2 years ago


Thank you for the work you do here at the DronebotWorkshop! I have thoroughly enjoyed every single one of those I’ve watched.

I’m trying to add the zip library to my Arduino IDE but the IDE complains with “Zip doesn’t contain a library”. It is only 2.6k in size. Am I missing something here?

BTW: the was added without any problems.

2 years ago
Reply to  Bob

Hi Bob, I could not attach it here, but if you go to Github, you will find it; you are right. The file is missing.

2 years ago

Hello Bill,

I’m trying to download the library, but when I try to open the bitbucket link you gave, It says that there’s an error.

Please help, Thanks

2 years ago

As always, this is one of the best videos in the world; very important information and high-quality material. I have a question that I hope someone can answer; after following the exact steps and testing the same, I am facing values shift in the pitch and roll; after holding the MPU6050 in my hand and starting moving it, after some time all values will shift even if I put it back to the exact location, I tried 2 MPU6050 and 2 Arduinos but I got the same issue again and again.

tarek EL-mahallawy
1 year ago

great tutorials thank you

9 months ago

How can we make this communicate using RS485 instead of I2C?

17 days ago

I have successfully used this application with Arduino Uno but with Arduino Uno R4 WiFi I have some problems. The sketch is compiled and loaded without errors but nothing works. thanks.