electroSome

Interfacing MPU-6050 / GY-521 board with Arduino Uno

About MPU-6050

MPU-6050 is a chip manufactured by Invensense which combines 3 axis accelerometer and 3 axis gyroscope with an on-board digital motion processor. It also includes a embedded temperature sensor and an on chip oscillator. It is very accurate and consist of analogue to digital conversion hardware for each channel thereby capturing x,y,z channels at the same time. The arduino can be interfaced with I2C bus.

3-axis Gyroscope

The MPU-6050 consist of a 3 axis gyroscope which can detect rotational velocity along the x,y,z axis with micro electro mechanical system technology (MEMS).

3-axis Accelerometer

The MPU-6050 consist of a 3 axis accelerometer which can detect angle of tilt or inclination along the x,y,z axis with micro electro mechanical system technology (MEMS).

On chip temperature sensor

The output from the temperature sensor is digitized by ADC and can be read off the sensor data register.

Digital motion processor (DMP)

The embedded digital motion processor is used to do computations on the sensor data. The values can be read off the dmp registers.

The raw values can be directly read of the accelerometer and gyroscope registers by the arduino. The MPU-6050 chip also includes a 1024 byte FIFO buffer where data can be placed and read off. The MPU-6050 always acts as a slave when connected to the Arduino with SDA and SCL pins connected to the I2C bus. But it also has its own auxiliary I2C controller which enables it to act as master to another device like a magnetometer. The on-board DMP can be programmed with firmware to do complex calculations with the sensor values.
The AD0 selects between I2C addresses 0x68 and 0x69 enabling 2 of these sensors to be connected in the same project. Most breakout boards either have a pull down or pull up resistor to keep default at high or low.

GY-521 breakout board

Pinout

GY-521 pinout

Connections

Schematic

GY-521 schematic

Connection Diagram

Interfacing MPU-6050 with Arduino Uno – Circuit Diagram

The connections are given as follows:

Pitch and Roll Calculation

Roll is the rotation around x-axis and pitch is the rotation along y-axis.

Both are calculated using the equation below:

Pitch and Roll calculation

The result is in radians. ( It can be converted to degrees by multiplying by 180 and dividing by pi)

Program

#include <Wire.h> //library allows communication with I2C / TWI devices
#include <math.h> //library includes mathematical functions

const int MPU=0x68; //I2C address of the MPU-6050
int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ; //16-bit integers
int AcXcal,AcYcal,AcZcal,GyXcal,GyYcal,GyZcal,tcal; //calibration variables
double t,tx,tf,pitch,roll;

void setup()
{
    Wire.begin(); //initiate wire library and I2C
    Wire.beginTransmission(MPU); //begin transmission to I2C slave device
    Wire.write(0x6B); // PWR_MGMT_1 register
    Wire.write(0); // set to zero (wakes up the MPU-6050)  
    Wire.endTransmission(true); //ends transmission to I2C slave device
    Serial.begin(9600); //serial communication at 9600 bauds
}

void loop()
{
    Wire.beginTransmission(MPU); //begin transmission to I2C slave device
    Wire.write(0x3B); // starting with register 0x3B (ACCEL_XOUT_H)
    Wire.endTransmission(false); //restarts transmission to I2C slave device
    Wire.requestFrom(MPU,14,true); //request 14 registers in total  

    //Acceleration data correction
    AcXcal = -950;
    AcYcal = -300;
    AcZcal = 0;

    //Temperature correction
    tcal = -1600;

    //Gyro correction
    GyXcal = 480;
    GyYcal = 170;
    GyZcal = 210;


    //read accelerometer data
    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)
  
    //read temperature data 
    Tmp=Wire.read()<<8|Wire.read(); // 0x41 (TEMP_OUT_H) 0x42 (TEMP_OUT_L) 
  
    //read gyroscope data
    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) 

    //temperature calculation
    tx = Tmp + tcal;
    t = tx/340 + 36.53; //equation for temperature in degrees C from datasheet
    tf = (t * 9/5) + 32; //fahrenheit

    //get pitch/roll
    getAngle(AcX,AcY,AcZ);
  
    //printing values to serial port
    Serial.print("Angle: ");
    Serial.print("Pitch = "); Serial.print(pitch);
    Serial.print(" Roll = "); Serial.println(roll);
  
    Serial.print("Accelerometer: ");
    Serial.print("X = "); Serial.print(AcX + AcXcal);
    Serial.print(" Y = "); Serial.print(AcY + AcYcal);
    Serial.print(" Z = "); Serial.println(AcZ + AcZcal); 

    Serial.print("Temperature in celsius = "); Serial.print(t);  
    Serial.print(" fahrenheit = "); Serial.println(tf);  
  
    Serial.print("Gyroscope: ");
    Serial.print("X = "); Serial.print(GyX + GyXcal);
    Serial.print(" Y = "); Serial.print(GyY + GyYcal);
    Serial.print(" Z = "); Serial.println(GyZ + GyZcal);
  
    delay(1000);
}

//function to convert accelerometer values into pitch and roll
void getAngle(int Ax,int Ay,int Az) 
{
    double x = Ax;
    double y = Ay;
    double z = Az;

    pitch = atan(x/sqrt((y*y) + (z*z))); //pitch calculation
    roll = atan(y/sqrt((x*x) + (z*z))); //roll calculation

    //converting radians into degrees
    pitch = pitch * (180.0/3.14);
    roll = roll * (180.0/3.14) ;
}

Output

Interfacing MPU-6050 with Arduino Uno

The output can be read from the serial port of Arduino using the serial monitor.

MPU-6050 output

Video

Any doubts or suggestions? Comment below.