Skip to Content

MPU6050 3-Axis Accelerometer And 3-Axis GyroSensor With Arduino

MPU6050 3-Axis Accelerometer And 3-Axis GyroSensor With Arduino

In this article, you will learn how to use an MPU6050 module. The MPU6050 is a 3-axis  accelerometer and 3-axis gyrosensor.

It helps you build self-balancing cameras, robots, or even a drone.

These gyrosensors are commonly used now in a wide range of products.

The gyrosensors in a smartphone help in navigation maps, taking panorama pictures, detecting active mobile usage, games, fall detection, etc.

Gyro sensors in wearables like watches can help in monitoring steps, sleep activity etc.

I will take you through how to use the MPU6050 gyrosensor with Arduino.

We’ll cover the pin labels and the description, critical MPU6050 specifications, and hardware connections required. 

In the later sections, we will walk through an example Arduino code and see how to efficiently use an MPU6050 with Arduino.

Let’s get started!

Components Needed To Build Arduino And MPU6050 Project

Hardware Components 

Software

Makerguides.com is a participant in the Amazon Services LLC Associates Program, an affiliate advertising program designed to provide a means for sites to earn advertising fees by advertising and linking to products on Amazon.com.

Basics Of A MPU6050 Sensor

Let us have a look at this diagram of an MPU6050 module.

MPU6050 module

You can see the following aspects numbered in the diagram:

  1. Voltage Regulator – Coverts input 5 V from the Arduino UNO to 3.3 V. The 3.3 V is the supply voltage for the MPU6050 IC
  2. Bergstick connector option – You can access I2C lines, Interrupt, ADDress configuration and power on these lines. 
  3. MPU6050 IC – MPU6050 is a 24 pin IC. You can locate Pin 1 of the IC with the help of a small dot. The image above indicates the dot on the top left of the IC.
  4. Power indication LED
  5. Mounting holes

The MPU6050 module has eight pinouts. The table below describes the eight pins present on the MPU module.

Sl. NoPin LabelPin Description
1VCC5 V input. You can connect 5 V on the Arduino UNO to the VCC
2GNDGround connection
3SCLI2C Serial clock line
4SDAI2C Serial data line
5XDAI2C Master data line (for connecting external sensors)
6XCLI2C Master Clock line (for connecting external sensors)
7AD0I2C Slave Address LSB. You can connect it to Low or High. Hence you can have two I2C addresses for MPU6050 ICs on your board
8INTInterrupt Digital Input

Digital Interface

The registers and memory of the MPU6050 can be accessed using I2C. The maximum I2C bus speed supported is 400 kHz. 

The slave address of the MPU6050 is 0b110100x, where x can be either zero or one.

Hence the two possible addresses are 0b1101000 and 0b1101001.

The value of x is the logic level present on the AD0 input pin, as shown in the table below. 

AD0 Pin Logic Level7 bit I2C address of the MPU6050
Low1101000
High1101001

How to correlate the Orientation of the Axes

You use the diagram below to understand the orientation of the axes of the sensitivity. It also gives you the polarity of the rotation.

How to correlate the Orientation of the Axes

Notice the pin number one marking.

Accelerometer specifications of MPU6050

Full scale rangeAFS_SEL = 0±2 g
AFS_SEL = 1±4 g
AFS_SEL = 2±8 g
AFS_SEL = 3±16 g
Initial Calibration Tolerance±3 %
Output Data rateProgrammable4 to 1000 Hz
Initial Calibration Tolerance (Zero-G Output)X and Y axes±50 mg
Z axis±80 mg

Gyroscope specifications of MPU6050

Full scale rangeFS_SEL = 0±250 °/s
FS_SEL = 1±500 °/s
FS_SEL = 2±1000 °/s
FS_SEL = 3±2000 °/s
Sensitivity Scale Factor Tolerance±3 %
Gyroscope start-up time30 ms
Output data rate4 to 8000 Hz

Important links:

MPU6050 Registers:

 MPU-6000 and MPU-6050 Register Map and Descriptions Revision 4.2

MPU6050 datasheet:

MPU-6000 and MPU-6050 Product Specification Revision 3.4

Step-By-Step Instructions To Connect An MPU6050 With An Arduino UNO

In this section, we will go through the connections between Arduino UNO and the MPU6050 gyrosensor module.

Let’s get started.

How To Connect The MPU6050 Sensor Module With Arduino UNO

The connections are simple and take less time to complete. 

Step 1: Start with the GND connection.

Start with the GND connection

Connect the GND pin of the MPU6050 sensor to the Arduino GND pin. Always start with the GND connections. 

Step 2: Connect the I2C Clock line

Connect the I2C Clock line

I2C clock on the Arduino is Pin A5. Connect Pin A5 on UNO to the SCL pin of the MPU6050 sensor.

If you are using Arduino Mega, connect Pin 21 on the Mega to the SCL pin of the sensor. 

Step 3: Connect the I2C data line.

Connect the I2C data line

I2C Data on the Arduino is Pin A4. Connect Pin A4 on UNO to the SDA pin of the MPU6050 sensor.

If you are using Arduino Mega, connect Pin 20 on the Mega to the SDA pin of the sensor. 

Step 4: Connect the 5 V line.

Connect the 5 V line

Connect 5 V of Arduino UNO to the VCC of the MPU6050 sensor. The MPU6050 sensor module has an onboard 5 V to 3.3 V converter.

Congratulations. You have now completed the connections between Arduino UNO and the MPU6050 sensor.

Simple Arduino Projects On MPU6050 And Arduino UNO

Simple Arduino Projects On MPU6050 And Arduino UNO

MPU6050 Project 1:

This Arduino sketch will read the MPU sensor data and print it on the serial terminal.

// Basic demo for accelerometer readings from Adafruit MPU6050
 
#include "Adafruit_MPU6050.h"
#include "Adafruit_Sensor.h"
#include "Wire.h"
 
Adafruit_MPU6050 mpu;
 
void setup(void) {
  Serial.begin(115200);
  while (!Serial)
    delay(10); // will pause Zero, Leonardo, etc until serial console opens
 
  Serial.println("Adafruit MPU6050 test!");
 
  // Try to initialize!
  if (!mpu.begin()) {
    Serial.println("Failed to find MPU6050 chip");
    while (1) {
      delay(10);
    }
  }
  Serial.println("MPU6050 Found!");
 
  mpu.setAccelerometerRange(MPU6050_RANGE_8_G);
  Serial.print("Accelerometer range set to: ");
  switch (mpu.getAccelerometerRange()) {
  case MPU6050_RANGE_2_G:
    Serial.println("+-2G");
    break;
  case MPU6050_RANGE_4_G:
    Serial.println("+-4G");
    break;
  case MPU6050_RANGE_8_G:
    Serial.println("+-8G");
    break;
  case MPU6050_RANGE_16_G:
    Serial.println("+-16G");
    break;
  }
  mpu.setGyroRange(MPU6050_RANGE_2000_DEG);
  Serial.print("Gyro range set to: ");
  switch (mpu.getGyroRange()) {
  case MPU6050_RANGE_250_DEG:
    Serial.println("+- 250 deg/s");
    break;
  case MPU6050_RANGE_500_DEG:
    Serial.println("+- 500 deg/s");
    break;
  case MPU6050_RANGE_1000_DEG:
    Serial.println("+- 1000 deg/s");
    break;
  case MPU6050_RANGE_2000_DEG:
    Serial.println("+- 2000 deg/s");
    break;
  }
 
  mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);
  Serial.print("Filter bandwidth set to: ");
  switch (mpu.getFilterBandwidth()) {
  case MPU6050_BAND_260_HZ:
    Serial.println("260 Hz");
    break;
  case MPU6050_BAND_184_HZ:
    Serial.println("184 Hz");
    break;
  case MPU6050_BAND_94_HZ:
    Serial.println("94 Hz");
    break;
  case MPU6050_BAND_44_HZ:
    Serial.println("44 Hz");
    break;
  case MPU6050_BAND_21_HZ:
    Serial.println("21 Hz");
    break;
  case MPU6050_BAND_10_HZ:
    Serial.println("10 Hz");
    break;
  case MPU6050_BAND_5_HZ:
    Serial.println("5 Hz");
    break;
  }
 
  Serial.println("");
  delay(100);
}
 
void loop() {
 
  /* Get new sensor events with the readings */
  sensors_event_t a, g, temp;
  mpu.getEvent(&a, &g, &temp);
 
  /* Print out the values */
  Serial.print("Acceleration X: ");
  Serial.print(a.acceleration.x);
  Serial.print(", Y: ");
  Serial.print(a.acceleration.y);
  Serial.print(", Z: ");
  Serial.print(a.acceleration.z);
  Serial.println(" m/s^2");
 
  Serial.print("Rotation X: ");
  Serial.print(g.gyro.x);
  Serial.print(", Y: ");
  Serial.print(g.gyro.y);
  Serial.print(", Z: ");
  Serial.print(g.gyro.z);
  Serial.println(" rad/s");
 
  Serial.print("Temperature: ");
  Serial.print(temp.temperature);
  Serial.println(" degC");
 
  Serial.println("");
  delay(500);
}

MPU6050 Project 2: 

Here is another interesting Arduino project. This Arduino sketch will read the MPU sensor data and control the rotation of a 3-D image on an OLED display.

MPU6050 Project

You also get an option to read the temperature from the MPU6050 sensor. Based on the temperature, you control the color of the LED connected to the Arduino.

LED connected to the Arduino

Link

// Example sketch for the MPU-6050.
//
// Version 1, 9 August 2021, by Koepel with help from Wokwi community.
// Based on:
//   (1)
//     3D_Cube for Arduino OLED module by Colin Ord, 9/1/2015
//     A port of my (Colin Ord) original JustBasic Cube_3D demo to the Arduino Uno using U8G library.
//     http://colinord.blogspot.com/2015/01/arduino-oled-module-with-3d-demo.html
//     (no known copyrights)
//
//   (2)
//     MPU-6050 Short Example Sketch
//     By Arduino User JohnChi
//     August 17, 2014
//     Public Domain
//     https://playground.arduino.cc/Main/MPU-6050/#short
//
//   (3)
//     The Adafruit GFX library with the SSD1306 driver.
//
 
#include "Wire.h"
#include "Adafruit_SSD1306.h"
#include "Adafruit_GFX.h"
#include "Adafruit_NeoPixel.h"
 
Adafruit_SSD1306 display(128, 64);   // 128 pixels width, 64 pixels height
 
#define LED_PIN   6
#define LED_COUNT 1
Adafruit_NeoPixel neoPixel( LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
 
const int mpuAddress = 0x68;          // I2C address of the MPU-6050
 
float xByGyro, yByGyro, zByGyro;      // Global variables for the rotation by gyro
 
// Set the origin in the middle of the display
const int xOrigin = 64;
const int yOrigin = 32;
 
const float viewDistance = 150.0;     // higher for less perspective, lower for more.
 
// Vertices for a cube
// A cube has 8 corners and each coordinate has x,y,z values.
#define NUM_VERTICES 8
const int cube_vertex[NUM_VERTICES][3] =
{
  { -20, -20,  20 },     // x, y, z
  {  20, -20,  20 },
  {  20,  20,  20 },
  { -20,  20,  20 },
  { -20, -20, -20 },
  {  20, -20, -20 },
  {  20,  20, -20 },
  { -20,  20, -20 }
};
 
// The wirefram is to display the lines on the OLED display
// It contains the corners of the shape in 2D coordinates
int wireframe[NUM_VERTICES][2];
 
void setup()
{
  Serial.begin( 115200);
 
  Wire.begin();
 
  // Initialize the OLED display and test if it is connected.
  if( !display.begin( SSD1306_SWITCHCAPVCC, 0x3C))
  {
    Serial.println(F( "SSD1306 allocation failed"));
    for(;;);                                   // halt the sketch if error encountered
  }
 
  // Initialize the MPU-6050 and test if it is connected.
  Wire.beginTransmission( mpuAddress);
  Wire.write( 0x6B);                           // PWR_MGMT_1 register
  Wire.write( 0);                              // set to zero (wakes up the MPU-6050)
  auto error = Wire.endTransmission();
  if( error != 0)
  {
    Serial.println(F( "Error, MPU-6050 not found"));
    for(;;);                                   // halt the sketch if error encountered
  }
 
  // Initialize the NeoPixel
  neoPixel.begin();
}
 
void loop()
{
  Wire.beginTransmission( mpuAddress);
  Wire.write( 0x3B);                   // Starting with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission( false);        // No stop condition for a repeated start
 
  // The MPU-6050 has the values as signed 16-bit integers.
  // There are 7 values in 14 registers.
  int16_t AcX, AcY, AcZ, Tmp, GyX, GyY, GyZ;
 
  Wire.requestFrom( mpuAddress, 14);   // request a total of 14 bytes
  AcX = Wire.read()<<8 | Wire.read();  // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)    
  AcY = Wire.read()<<8 | Wire.read();  // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
  AcZ = Wire.read()<<8 | Wire.read();  // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
  Tmp = Wire.read()<<8 | Wire.read();  // 0x41 (TEMP_OUT_H)   & 0x42 (TEMP_OUT_L)
  GyX = Wire.read()<<8 | Wire.read();  // 0x43 (GYRO_XOUT_H)  & 0x44 (GYRO_XOUT_L)
  GyY = Wire.read()<<8 | Wire.read();  // 0x45 (GYRO_YOUT_H)  & 0x46 (GYRO_YOUT_L)
  GyZ = Wire.read()<<8 | Wire.read();  // 0x47 (GYRO_ZOUT_H)  & 0x48 (GYRO_ZOUT_L)
 
  // The acceleration is directly mapped into the angles.
  // That is rather artificial.
  // The combined gravity could be used for an angle, while ignoring the strength.
  //
  // The gyro sets the rotation speed.
  // The angle created by the rotation speed is added to the angle by the accelerometer.
  //
  // The conversion from the sensor values to the rotation is just a value
  // that makes it look good on display.
 
  float xByAccel = (float) AcX * 0.0001;      // static angle by accelerometer
  float yByAccel = (float) AcY * 0.0001;
  float zByAccel = (float) AcZ * 0.0001;
 
  xByGyro += (float) GyX * 0.00001;           // moving angle by gyro
  yByGyro += (float) GyY * 0.00001;
  zByGyro += (float) GyZ * 0.00001;
 
  float x = xByAccel + xByGyro;               // combine both angles
  float y = yByAccel + yByGyro;
  float z = zByAccel + zByGyro;
 
  // Keep the radians in range (although the cos/sin functions accept every value)
  if( x < 0.0)
    x += 2.0 * M_PI;
  else if( x > 2.0 * M_PI)
    x -= 2.0 * M_PI;
  if( y < 0.0)
    y += 2.0 * M_PI;
  else if( y > 2.0 * M_PI)
    y -= 2.0 * M_PI;
  if( z < 0.0)
    z += 2.0 * M_PI;
  else if( z > 2.0 * M_PI)
    z -= 2.0 * M_PI;
 
  // Draw 3D picture
  for (int i = 0; i < NUM_VERTICES; i++)
  {
    // Rotate Y
    float rotx = cube_vertex[i][2] * sin(y) + cube_vertex[i][0] * cos(y);
    float roty = cube_vertex[i][1];
    float rotz = cube_vertex[i][2] * cos(y) - cube_vertex[i][0] * sin(y);
 
    // Rotate X
    float rotxx = rotx;
    float rotyy = roty * cos(x) - rotz * sin(x);
    float rotzz = roty * sin(x) + rotz * cos(x);
 
    // Rotate Z
    float rotxxx = rotxx * cos(z) - rotyy * sin(z);
    float rotyyy = rotxx * sin(z) + rotyy * cos(z);
    float rotzzz = rotzz;
 
    // Add depth perspective
    rotxxx *= viewDistance / (viewDistance + rotzz);
    rotyyy *= viewDistance / (viewDistance + rotzzz);
 
    // Bring to middle of screen
    rotxxx += (float) xOrigin;
    rotyyy += (float) yOrigin;
 
    // Store new vertices values for wireframe drawing
    wireframe[i][0] = (int) rotxxx;
    wireframe[i][1] = (int) rotyyy;
    wireframe[i][2] = (int) rotzzz;
  }
  draw_wireframe();
 
 
  // Set the color of the NeoPixel according to the temperature
  // Temperature by the MPU-6050 is -40 to 85.
  // According to the datasheet:
  //   Temperature in Celsius = (raw_value / 340) + 36.53
  // The Hue range for the NeoPixel is the full uint16_t range.
  float Celsius = ((float) Tmp / 340.00) + 36.53;
  float hue = (Celsius + 40.0) / 125.0 * 65535.0;
  uint32_t rgbcolor = neoPixel.ColorHSV( (uint16_t) hue);
  neoPixel.setPixelColor( 0, rgbcolor);
  neoPixel.show();                        // update new values to NeoPixel
}
 
void draw_wireframe(void)
{
  // Start with a empty buffer
  display.clearDisplay();
 
  // A cube has 8 points and 12 sides.
  // The wireframe contains the 8 points, and the 12 lines are drawn here.
  display.drawLine( wireframe[0][0], wireframe[0][1], wireframe[1][0], wireframe[1][1], SSD1306_WHITE);
  display.drawLine( wireframe[1][0], wireframe[1][1], wireframe[2][0], wireframe[2][1], SSD1306_WHITE);
  display.drawLine( wireframe[2][0], wireframe[2][1], wireframe[3][0], wireframe[3][1], SSD1306_WHITE);
  display.drawLine( wireframe[3][0], wireframe[3][1], wireframe[0][0], wireframe[0][1], SSD1306_WHITE);
 
  display.drawLine( wireframe[4][0], wireframe[4][1], wireframe[5][0], wireframe[5][1], SSD1306_WHITE);
  display.drawLine( wireframe[5][0], wireframe[5][1], wireframe[6][0], wireframe[6][1], SSD1306_WHITE);
  display.drawLine( wireframe[6][0], wireframe[6][1], wireframe[7][0], wireframe[7][1], SSD1306_WHITE);
  display.drawLine( wireframe[7][0], wireframe[7][1], wireframe[4][0], wireframe[4][1], SSD1306_WHITE);
 
  display.drawLine( wireframe[0][0], wireframe[0][1], wireframe[4][0], wireframe[4][1], SSD1306_WHITE);
  display.drawLine( wireframe[1][0], wireframe[1][1], wireframe[5][0], wireframe[5][1], SSD1306_WHITE);
  display.drawLine( wireframe[2][0], wireframe[2][1], wireframe[6][0], wireframe[6][1], SSD1306_WHITE);
  display.drawLine( wireframe[3][0], wireframe[3][1], wireframe[7][0], wireframe[7][1], SSD1306_WHITE);
 
  // Extra cross face on one side
  display.drawLine( wireframe[1][0], wireframe[1][1], wireframe[3][0], wireframe[3][1], SSD1306_WHITE);
  display.drawLine( wireframe[0][0], wireframe[0][1], wireframe[2][0], wireframe[2][1], SSD1306_WHITE);
 
  // Write the new picture to the display
  display.display();
}

FAQs About The MPU6050 And The Arduino Projects

I have answered the most frequently asked questions about the MPU6050.

If you have any other questions, please post them in the comments section. 

1) What is MPU6050 used for?

The MPU6050 monitors the rotation rate of the X, Y, and Z axes. The MPU6050 also provides an accelerometer in all three axes.

Hence, you can use MPU6050 as a gyrosensor. The MPU6050 also has an internal temperature sensor. 

You can find MPU6050 sensors in HMI controllers, Mobile phones, wearables, navigation tools, drone cameras, etc. 

2) What does the MPU6050 output?

The MPU6050 outputs the current position of the sensor. The data output of the MPU6050 is listed below.

  • X, Y, and Z angular rotation rate in degrees per second
  • X, Y, and Z axis acceleration value in ‘g’ units
  • Temperature sensor data

3) How do you make MPU6050 work with Arduino?

MPU6050 communicates with the Arduino via I2C lines. MPU6050 provides all the measurements via registers.

Arduino can read the internal registers of MPU6050 via I2C and get the measurements periodically. 

You need to connect the I2C SDA line, I2C Data Line and an Arduino GPIO as an interrupt input pin.

The MPU6050 IC does all the signal processing and filtering and provides final digital data. Hence, it makes the software part easy. 

3) How accurate is the temperature sensor on the MPU6050?

MPU6050 has an onboard temperature sensor whose accuracy is ±1 degree. The ± 1-degree accuracy is for the entire operating range of -40 to +85 °C.

Conclusion

In this article, we learnt about the basics of the MUP6050 module and understood all the necessary specifications and features it offers.

Later we built an example project which we tested using the Arduino code. 

The MPU6050 is a genuinely versatile motion-tracking device. You will find a lot of applications in your subsequent projects.

I am sure you are excited to use MPU6050 in your following Arduino projects. 

If you have suggestions to improve the article, please write them in the comments section.

It will help me to enhance the article, which will benefit all our readers.

It will be fantastic to know which projects you were working on where you are involving an MPU6050.

Please share your articles in the comments section. We will enjoy reading the new project ideas.

Don’t forget to share the article with your friends and Arduino enthusiasts.

bill Smith

Monday 11th of March 2024

Issues I find of interest (from my experienes). 1) Filtering of the outputs so they are not so widely fluctuating. 2) My Temperatures always read very High... not sure why. 3) More information on the Accelerometer and itgs usage.