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

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).

  • When the sensor is rotated along any axis a vibration is produced due to Coriolis effect which is detected by the MEMS.
  • 16-bit ADC is used to digitize voltage to sample each axis.
  • +/- 250, +/- 500, +/- 1000, +/- 2000 are the full scale range of output.
  • Angular velocity is measured along each axis in degree per second unit.

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).

  • Acceleration along the axes deflects the moving mass which in turn unbalances the differential capacitor which is detected with electro mechanical system technology (MEMS). Output amplitude is proportional to acceleration.
  • 16-bit ADC is used to digitize the values.
  • +/- 2g, +/- 4g, +/- 8g, +/- 16g are the full scale range of output.
  • In normal position that is when the device is placed on a flat surface the values are 0g on x axis, 0g on y axis and +1 on z axis.

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

GY-521 pinout

  • VCC (the GY-521 board has a onboard voltage regulator therefore either 5v or 3.3v can be connected.)
  • GND (Ground pin)
  • SCL (Serial clock line for I2C)
  • SDA (Serial Data Line for I2C)
  • XDA (Auxiliary data)
  • XCL (Auxiliary clock)
  • AD0 (when this pin set to low the I2C address of the board will be 0x68, when it is set to high the I2C address will be 0x69)
  • INT (Interrupt digital output)

Connections

Schematic

GY-521 schematic

GY-521 schematic

Connection Diagram

Interfacing MPU6050 with Arduino Uno - Circuit Diagram

Interfacing MPU-6050 with Arduino Uno – Circuit Diagram

The connections are given as follows:

  • VCC to any 5v out pin of Arduino Uno.
  • GND to any ground pin of Arduino Uno.
  • SDA to A4 pin of Arduino Uno.
  • SCL to A5 pin of Arduino Uno.

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

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 //library allows communication with I2C / TWI devices
#include //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

Interfacing MPU-6050 with Arduino Uno

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

MPU-6050 output

MPU-6050 output

Video


Any doubts or suggestions? Comment below.

Share this post