Skip to content
My Account

Reference

MPU6050 Accelerometer + Gyroscope Complete Guide

The MPU6050 (GY-521) six-axis motion sensor: real specifications, pins, I2C addresses, wiring, code with raw registers, calibration, and the traps that give drifting readings.

  • 3-axis gyro + 3-axis accel
  • I2C 0x68 or 0x69
  • 2.375 to 3.46 V chip supply
  • 16-bit
No ratings yet, be the first.

The MPU6050 is a six-axis motion sensor from InvenSense (now TDK): a 3-axis gyroscope and a 3-axis accelerometer in one 4 × 4 × 0.9 mm chip, with a Digital Motion Processor (DMP) and a 1024-byte FIFO. It is usually sold on the purple GY-521 breakout. It tells you how a thing is tilted and how fast it turns, which makes it the basis of self-balancing robots, gimbals, drones and gesture projects.

This guide covers the real specifications from the InvenSense datasheet and register map, the pins of the GY-521 board, the I2C addresses, wiring, code with raw registers, calibration, and the traps that give drifting or wrong readings. The chip data comes from the MPU-6000/MPU-6050 product specification and register map (InvenSense). The board pins describe the common GY-521, and other boards may differ.

What is in the chip

ItemValue
Gyroscope3 axes, full scale ±250, ±500, ±1000 or ±2000 °/s, 16-bit
Accelerometer3 axes, full scale ±2, ±4, ±8 or ±16 g, 16-bit
Temperature sensorOn-chip, −40 to 85 °C, for compensation
Digital Motion ProcessorRuns sensor fusion on the chip
FIFO1024 bytes
InterfaceI2C up to 400 kHz (MPU-6050). The MPU-6000 also has SPI
Auxiliary I2CExtra I2C port for a magnetometer
PackageQFN 4 × 4 × 0.9 mm

The MPU6050 does not have a magnetometer, so it cannot give an absolute compass heading. For a nine-axis solution look at the BNO055, which does sensor fusion on the chip.

Source: InvenSense MPU-6000/MPU-6050 product specification.

Getting started

1. What you needA GY-521 (MPU6050) board, an ESP32 or Arduino, four jumper wires and a breadboard.
2. Wire it upVCC to 3.3 V, GND to GND, SDA to GPIO21 and SCL to GPIO22 on a classic ESP32. Leave AD0, INT, XDA and XCL open.
3. Upload the sketchInstall the Adafruit MPU6050 library, upload the example below, and tilt the board while you watch the serial monitor.

Specifications

Sensor chip

Supply voltage (VDD)2.375 to 3.46 V
Logic reference (VLOGIC)1.71 V up to VDD, 1.8 V ± 5 % or VDD
Gyroscope sensitivity131, 65.5, 32.8 and 16.4 LSB per °/s for the four ranges
Accelerometer sensitivity16384, 8192, 4096 and 2048 LSB per g for the four ranges
Gyroscope current3.6 mA operating
Total current3.9 mA with all six axes and the DMP on
Standby current5 µA
Temperature sensor340 LSB per °C, untrimmed, range −40 to 85 °C
Zero-rate offset variation±20 °/s over −40 to 85 °C
Accelerometer sensitivity change±0.02 % per °C
I2C address0x68 (AD0 low) or 0x69 (AD0 high)
Operating temperature−40 to 85 °C

GY-521 breakout (typical)

SupplyTypically 3.3 to 5 V on VCC, through an on-board regulator
PinsVCC, GND, SCL, SDA, XDA, XCL, AD0, INT
SizeNot given. Measure your own board

Source: InvenSense MPU-6000/MPU-6050 product specification. The GY-521 data is typical and differs between sellers.

Dimensions

The chip is a QFN package of 4 × 4 mm and 0.9 mm high. The GY-521 breakout is a small board of roughly 21 × 16 mm in many shops, but sizes vary, so measure yours before you design a mount. Orientation matters: the chip has X, Y and Z axes marked in the datasheet, and the printed arrows on your board tell you which way is which.

Source: package size from the InvenSense datasheet. The board size is not from a datasheet.

Pins of the GY-521

PinTypeFunction
VCCPowerSupply, 3.3 to 5 V on most boards (regulated on the board)
GNDPowerGround
SCLI2CClock
SDAI2CData
XDAI2C (aux)Auxiliary data, to connect a magnetometer
XCLI2C (aux)Auxiliary clock
AD0InputAddress select: low 0x68, high 0x69
INTOutputInterrupt output, for data ready, motion or FIFO events

The order and the pull-ups differ between boards, so check yours. Most GY-521 boards have pull-up resistors on SDA and SCL.

Source: InvenSense MPU-6000/MPU-6050 product specification, pin functions. The GY-521 layout is typical.

Wiring

MPU6050 pinESP32Arduino Uno / NanoRaspberry Pi
VCC3.3 V3.3 V3.3 V (pin 1)
GNDGNDGNDGND (pin 6)
SCLGPIO22A5GPIO3 (pin 5)
SDAGPIO21A4GPIO2 (pin 3)
INTAny free GPIO (optional)D2 (optional)Any free GPIO (optional)
AD0GND (0x68) or 3.3 V (0x69)GND or 5 VGND or 3.3 V

The chip runs at 3.46 V at most. The board has a regulator, but its I2C pull-ups may go to VCC, so with 5 V on VCC the SDA and SCL lines also swing to 5 V. For a 3.3 V ESP32, power the board from 3.3 V.

Software setup

PlatformWhat to do
Arduino IDEInstall Adafruit MPU6050 from the Library Manager (it also installs Adafruit BusIO and Adafruit Unified Sensor)
PlatformIOAdd adafruit/Adafruit MPU6050 to lib_deps
ESP-IDFUse the I2C master driver and the registers below

Read the sensor

#include <Wire.h>
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>

Adafruit_MPU6050 mpu;

void setup() {
  Serial.begin(115200);
  Wire.begin(21, 22);
  if (!mpu.begin()) {
    Serial.println("Failed to find MPU6050");
    while (1) delay(10);
  }
  mpu.setAccelerometerRange(MPU6050_RANGE_8_G);
  mpu.setGyroRange(MPU6050_RANGE_500_DEG);
}

void loop() {
  sensors_event_t a, g, temp;
  mpu.getEvent(&a, &g, &temp);

  Serial.print("Accel (m/s^2): ");
  Serial.print(a.acceleration.x); Serial.print(", ");
  Serial.print(a.acceleration.y); Serial.print(", ");
  Serial.println(a.acceleration.z);

  Serial.print("Gyro (rad/s): ");
  Serial.print(g.gyro.x); Serial.print(", ");
  Serial.print(g.gyro.y); Serial.print(", ");
  Serial.println(g.gyro.z);

  delay(200);
}

I did not run this sketch on a board, it follows the library example.

Reading the registers yourself

You do not need a library to read the MPU6050. Wake the chip (it starts in sleep mode), then read 14 bytes from 0x3B: accelerometer X, Y, Z, temperature and gyroscope X, Y, Z, each a signed 16-bit value, high byte first.

#include <Wire.h>
#define MPU 0x68

void setup() {
  Serial.begin(115200);
  Wire.begin(21, 22);
  Wire.beginTransmission(MPU);
  Wire.write(0x6B); Wire.write(0x00);     // PWR_MGMT_1: clear the sleep bit
  Wire.endTransmission();
  Wire.beginTransmission(MPU);
  Wire.write(0x75); Wire.endTransmission(false);
  Wire.requestFrom(MPU, 1);
  Serial.printf("WHO_AM_I = 0x%02X (expect 0x68)n", Wire.read());
}

void loop() {
  Wire.beginTransmission(MPU);
  Wire.write(0x3B); Wire.endTransmission(false);
  Wire.requestFrom(MPU, 14);
  int16_t v[7];
  for (int i = 0; i < 7; i++) v[i] = (Wire.read() << 8) | Wire.read();
  float ax = v[0] / 16384.0f, ay = v[1] / 16384.0f, az = v[2] / 16384.0f;   // g, range +-2 g
  float tc = v[3] / 340.0f + 36.53f;                                          // degC
  float gx = v[4] / 131.0f,  gy = v[5] / 131.0f,  gz = v[6] / 131.0f;       // deg/s, range +-250
  Serial.printf("a %.2f %.2f %.2f g  g %.1f %.1f %.1f dps  %.1f Cn", ax, ay, az, gx, gy, gz, tc);
  delay(100);
}

Registers

RegisterUse
0x6BPWR_MGMT_1: bit 6 is sleep (set after a reset), the device starts asleep
0x75WHO_AM_I: reads 0x68
0x3B to 0x40ACCEL_XOUT_H to ACCEL_ZOUT_L
0x41, 0x42TEMP_OUT_H and TEMP_OUT_L, in °C = value / 340 + 36.53
0x43 to 0x48GYRO_XOUT_H to GYRO_ZOUT_L
0x1BGYRO_CONFIG: selects the gyroscope range
0x1CACCEL_CONFIG: selects the accelerometer range
0x19SMPLRT_DIV: sample rate divider
0x1ACONFIG: digital low-pass filter

The sketch has not been run on a board. Use 16384 as the divisor for the ±2 g range, and 131 for the ±250 °/s range. If you change the range with the config registers, use the matching sensitivity from the specification table.

Source: InvenSense MPU-6000/MPU-6050 register map and product specification.

Calibration and angles

Raw readings are not zero at rest, so you have to calibrate:

  • Gyro offset. Keep the board still, average a few hundred gyroscope readings, and subtract that offset. The zero-rate offset can be up to ±20 °/s over temperature.
  • Accelerometer offset. With the board flat, Z should read 1 g and X and Y 0 g. Correct the difference.
  • Tilt from the accelerometer. Roll = atan2(ay, az) and pitch = atan2(−ax, sqrt(ay² + az²)). It is stable over time but noisy when the board moves.
  • Angle from the gyroscope. Integrate the rate over time. It is smooth but drifts.
  • Combine them. A complementary or Kalman filter blends both: angle = 0.98 × (angle + gyro × dt) + 0.02 × accel angle.
  • No yaw from the accelerometer. Without a magnetometer the heading drifts. The DMP and a magnetometer on the auxiliary port can help.

Source: InvenSense datasheet for the offsets. The angle formulas are standard and not from the datasheet.

Getting stable readings

  • Mount it rigidly. A loose board picks up vibration as noise.
  • Keep it away from motors and magnets. The chip has no magnetometer, but a vibrating motor shakes the accelerometer.
  • Choose the lowest range that fits. ±2 g and ±250 °/s give the best resolution. Use larger ranges only when you need them.
  • Set the digital low-pass filter in CONFIG to reduce noise at the cost of delay.
  • Use the INT pin. Read data when the sensor says it is ready, not on a fixed delay.
  • Wait after power-up. Let the sensor warm up for a few seconds before you calibrate.
  • Let the temperature settle before a calibration, because the offsets change with temperature.

Real gotchas

  • It starts in sleep mode. You must write 0 to PWR_MGMT_1 (0x6B), or every reading is zero.
  • The chip is a 3.3 V part. VDD is 2.375 to 3.46 V. Only the regulated GY-521 board takes 5 V on VCC.
  • Two addresses. AD0 low is 0x68, high is 0x69. A fake chip (marked MPU6050 but a clone) can answer with a different WHO_AM_I, so check it.
  • Gyroscope drift. Integrating gives an angle that drifts. Always combine it with the accelerometer.
  • No heading. The MPU6050 has no magnetometer.
  • Orientation of the axes. Follow the arrows printed on the board and the datasheet, not your assumption.
  • Wrong scale factor. The divisor depends on the range you set. Using 16384 after you set ±8 g gives values four times too large.
  • I2C speed. The chip runs at 400 kHz at most. Keep the wires short, because the GY-521 pull-ups are often weak.
  • Temperature is for compensation. The built-in temperature value is not an accurate room thermometer.

Compared with other motion sensors

SensorAxesGood forWeak point
MPU60506 axes, gyro and accel, DMPCheap, many examplesNo magnetometer, old chip
BNO0559 axes with fusionGives orientation directlyMore expensive
ADXL345 type accelerometers3 axesTilt onlyNo gyro

The ADXL345 row is general knowledge and not from a datasheet read for this guide.

What to build with it

  • Tilt/orientation sensing: self-balancing robots, gimbals.
  • Step counting / activity detection: wearable projects.
  • Vibration/impact detection: accelerometer-only use cases.
  • Drone/RC flight controllers: a common low-cost IMU choice for hobby builds.
  • A self-balancing robot with a PID loop on the tilt angle.
  • A motion-triggered light that wakes up when the board is picked up, using the INT pin.

Safety notes

Before you wire anything up

  • Keep the chip supply below 3.46 V. Power the GY-521 from 3.3 V on a 3.3 V microcontroller.
  • Check the pin order on your own board before you apply power.
  • Never connect the board to mains voltage. Keep it on a low-voltage supply.
  • Disconnect the power before you change the wiring.
  • An accelerometer or gyroscope is not a safety device. Do not use it as the only protection in a drone, a balancing robot or a machine.

Conclusion

The MPU6050 is a cheap and well-documented way to add six-axis motion sensing to a project. Wake it from sleep mode, calibrate the offsets, pick the lowest range that fits, and combine the accelerometer and the gyroscope for stable angles. For a compass heading you need a magnetometer, or a chip like the BNO055.

Chip data is from the InvenSense MPU-6000/MPU-6050 product specification and register map. The filter formula and the comparison row are general knowledge.

Advertisement
All guides

More guides

Keep building.

From ESP32 HomeKit accessories to Arduino and ATtiny reference guides, there’s more where this came from.

All guides