Interfacing Triple Axis Accelerometer and Gyro Breakout MPU6050 with Arduino

Interfacing Triple Axis Accelerometer and Gyro Breakout MPU6050 with Arduino

Today I will be explaining how to interface Accelerometer and Gyro MPU6050 breakout board GY-521. I will show how to take raw data from the sensor without using any MPU6050 libraries.

Table of Contents

What is MPU6050/GY-521

MPU6050 is a 6 axis (Gyro + Accelerometer)MEMS(Micro-Electro-Mechanical Systems,) motion tracking device. MPU6050 is one of the first MotionTracking devices with Low power consumption and low cost.
This sensor now comes with every smartphone nowadays. The MPU6050 is a combination of 3 axis accelerometer and a 3 axis gyroscope. The sensor comes with a Digital Motion Processor. that can process complex 6 axis motion algorithms.
GY-521 is the breakout board for the MPU6050.

MPU6050 Pinout

Wiring Diagram

I2C Communication

The GY-521 module uses I2C to communicate Arduino. Most of the Arduino variant boards have SDA and SCL pins. If you can’t find it then connect it analog pin A4 (SDA) and A5 (SCL). If you’re using different Arduino boards please refer to the pinouts.

GY-521 ModuleArduino Pin
VCC5v
GNDGND
SCLA5
SDAA4

Code to Read Raw Value from MPU6050

/*
   Interfacing Triple Axis Accelerometer and Gyro Breakout MPU6050 with Arduino
   Mayoogh Girish, https://mgprojecthub.com
*/

#include<Wire.h>                                        // Wiew library for I2C communication 
#define MPU6050_register 0x68                           // I2C address of the MPU-6050.

int16_t accelerometerX,accelerometerY,accelerometerZ;   // Variable for acceleometer raw values
int16_t gyroX,gyroY,gyroZ;                              // Variable for gyroscope raw values
int16_t temperature;                                    // Variable for temperature 

void setup(){
  Wire.begin();                                         // Initialize comunication
  Wire.beginTransmission(MPU6050_register);             // Begin I2C communication
  Wire.write(0x6B);                                     // PWR_MGMT_1 Register [https://invensense.tdk.com/wp-content/uploads/2015/02/MPU-6000-Register-Map1.pdf]
  Wire.write(0);                                        // Place 0 to the 6B register, wakes up the MPU6050
  Wire.endTransmission(true);
  Serial.begin(9600);
}
void loop(){
  Wire.beginTransmission(MPU6050_register);             
  Wire.write(0x3B);                                     // Begin with register 0x3B (ACCEL_XOUT_H) [https://invensense.tdk.com/wp-content/uploads/2015/02/MPU-6000-Register-Map1.pdf]
                                                        // MPU-6050 Register Map and Descriptions Revision 4.2 - Page 7
  Wire.endTransmission(false);                          // will send a restart, keeping the connection active.
  Wire.requestFrom(MPU6050_register,14,true);           // Request 14 registers. [7*2=14]. Value for each axis is stored in 2 bytes. 3 Acceleromter + 3 Gyro + 1 Temperature
  
  accelerometerX=Wire.read()<<8|Wire.read();            // Registers 0x3B (ACCEL_XOUT_H) + 0x3C (ACCEL_XOUT_L)
  accelerometerY=Wire.read()<<8|Wire.read();            // Registers 0x3D (ACCEL_YOUT_H) + 0x3E (ACCEL_YOUT_L)
  accelerometerZ=Wire.read()<<8|Wire.read();            // Registers 0x3F (ACCEL_ZOUT_H) + 0x40 (ACCEL_ZOUT_L)
  temperature=Wire.read()<<8|Wire.read();               // Registers 0x41 (TEMP_OUT_H)  + 0x42 (TEMP_OUT_L)
  gyroX=Wire.read()<<8|Wire.read();                     // Registers 0x43 (GYRO_XOUT_H) + 0x44 (GYRO_XOUT_L)
  gyroY=Wire.read()<<8|Wire.read();                     // Registers 0x45 (GYRO_YOUT_H) + 0x46 (GYRO_YOUT_L)
  gyroZ=Wire.read()<<8|Wire.read();                     // Registers: 0x47 (GYRO_ZOUT_H) + 0x48 (GYRO_ZOUT_L)
  
  Serial.print("AccX = ");
  Serial.print(accelerometerX);
  Serial.print(" || AccY = ");
  Serial.print(accelerometerY);
  Serial.print(" || AccZ = ");
  Serial.print(accelerometerZ);
  Serial.print(" || Temp = ");
  Serial.print(temperature/340.00+36.53);               // Temperature in degrees C = (TEMP_OUT Register Value as a signed quantity)/340 + 36.53
  Serial.print(" || GyroX = ");
  Serial.print(gyroX);
  Serial.print(" || GyroY = ");
  Serial.print(gyroY);
  Serial.print(" || GyroZ = ");
  Serial.println(gyroZ);
  delay(100);
}

For better visualization of the output open Serial Plotter.

Accelerometer values on Serial Plotter

Accelerometer
X-Axis Y-Axis Z-Axis

Gyroscope Values on Serial Plotter

Gyroscope
X-Axis Y-Axis Z-Axis

Code Explanation

#include<Wire.h>                                        // Wiew library for I2C communication 
#define MPU6050_register 0x68                           // I2C address of the MPU-6050.

int16_t accelerometerX,accelerometerY,accelerometerZ;   // Variable for acceleometer raw values
int16_t gyroX,gyroY,gyroZ;                              // Variable for gyroscope raw values
int16_t temperature;                                    // Variable for temperature 

Initially, the library for I2C communication Wire.h is imported.
followed by we define the I2C address of MPU6050. The default value of the register is 0x68. If the AD0 pin is HIGH then the register will be 0x69.
The variables for storing the accelerometer gyroscope and temperature raw values are defined.

void setup(){
  Wire.begin();                                         // Initialize communication
  Wire.beginTransmission(MPU6050_register);             // Begin I2C communication
  Wire.write(0x6B);                                     // PWR_MGMT_1 Register [https://invensense.tdk.com/wp-content/uploads/2015/02/MPU-6000-Register-Map1.pdf]
  Wire.write(0);                                        // Place 0 to the 6B register, wakes up the MPU6050
  Wire.endTransmission(true);
  Serial.begin(115200);
}

Inside setup, the wire library is initialized and set the MPU6050 power management register

Source : MPU-6050 Register Map and Descriptions Revision 4.2 https://invensense.tdk.com/
void loop(){
  Wire.beginTransmission(MPU6050_register);             
  Wire.write(0x3B);                                     // Begin with register c (ACCEL_XOUT_H) [https://invensense.tdk.com/wp-content/uploads/2015/02/MPU-6000-Register-Map1.pdf]
                                                        // MPU-6050 Register Map and Descriptions Revision 4.2 - Page 7
  Wire.endTransmission(false);                          // will send a restart, keeping the connection active.
  Wire.requestFrom(MPU6050_register,14,true);           // Request 14 registers. [7*2=14]. Value for each axis is stored in 2 bytes. 3 Acceleromter + 3 Gyro + 1 Temperature

In the main loop, we begin I2C communication. and start reading from the register 0x3B. The value for each axis is stored in two registers.

Registers for accelerometer
Registers for gyroscope
Registers for temperature Measurement

We post the request for 14 register by Wire.requestFrom(MPU6050_register,14,true);

  accelerometerX=Wire.read()<<8|Wire.read();            // Registers 0x3B (ACCEL_XOUT_H) + 0x3C (ACCEL_XOUT_L)
  accelerometerY=Wire.read()<<8|Wire.read();            // Registers 0x3D (ACCEL_YOUT_H) + 0x3E (ACCEL_YOUT_L)
  accelerometerZ=Wire.read()<<8|Wire.read();            // Registers 0x3F (ACCEL_ZOUT_H) + 0x40 (ACCEL_ZOUT_L)
  temperature=Wire.read()<<8|Wire.read();               // Registers 0x41 (TEMP_OUT_H)  + 0x42 (TEMP_OUT_L)
  gyroX=Wire.read()<<8|Wire.read();                     // Registers 0x43 (GYRO_XOUT_H) + 0x44 (GYRO_XOUT_L)
  gyroY=Wire.read()<<8|Wire.read();                     // Registers 0x45 (GYRO_YOUT_H) + 0x46 (GYRO_YOUT_L)
  gyroZ=Wire.read()<<8|Wire.read();                     // Registers: 0x47 (GYRO_ZOUT_H) + 0x48 (GYRO_ZOUT_L)

The outputs are 2’s complement we need to combine it to get the proper value. If you have a doubt regarding this part of the code please refer to these 2 articles. article1, article2

  Serial.print("AccX = ");
  Serial.print(accelerometerX);
  Serial.print(" || AccY = ");
  Serial.print(accelerometerY);
  Serial.print(" || AccZ = ");
  Serial.print(accelerometerZ);
  Serial.print(" || Temp = ");
  Serial.print(temperature/340.00+36.53);               // Temperature in degrees C = (TEMP_OUT Register Value as a signed quantity)/340 + 36.53
  Serial.print(" || GyroX = ");
  Serial.print(gyroX);
  Serial.print(" || GyroY = ");
  Serial.print(gyroY);
  Serial.print(" || GyroZ = ");
  Serial.print(gyroZ);
  Serial.println();
  delay(100);
}

Here the values are printed using serial.print to the serial monitor/plotter. The temperature in degree Celsius for a register is calculated using the formula from the datasheet
Temperature = (TEMP_OUT)/340 + 36.53

Get Pitch Yaw and Roll values

To make things less complicated we will be using a library. I am using MPU6050.h by Korneliusz Jarzębski. You can download the library from here.

Upload MPU6050_gyro_pitch_roll_yaw example sketch



Pitch Roll Yaw values

Leave a Reply

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