The MPU6050 is one of the most powerful and affordable sensor modules available to hobbyists and engineers in India. This tiny IC packs a 3-axis accelerometer and a 3-axis gyroscope into a single chip, communicating over I2C, and costs under Rs 100. It powers everything from self-balancing robots and drone flight controllers to gesture-recognition gloves and activity trackers.
This comprehensive tutorial covers everything from first principles and wiring to full Arduino sketch implementations, Python code for Raspberry Pi, DMP (Digital Motion Processor) usage, calibration techniques, and practical project ideas. By the end, you will understand the MPU6050 deeply enough to integrate it confidently into any project.
1. What Is an IMU Sensor?
An Inertial Measurement Unit (IMU) is a device that measures a body’s specific force, angular rate, and sometimes magnetic field. A 6-DOF (Degrees of Freedom) IMU like the MPU6050 combines two key sensors:
- Accelerometer (3-axis): Measures linear acceleration in X, Y, and Z axes, including gravitational acceleration. It can tell you the static tilt angle of a device and detect dynamic motion like shaking or impact.
- Gyroscope (3-axis): Measures angular velocity — how fast the device rotates around each axis. It cannot tell you absolute orientation, but integrating its output over time gives you rotation angle.
The two sensors complement each other: the accelerometer is stable long-term but noisy short-term; the gyroscope is accurate short-term but drifts over time. Combining them (sensor fusion) produces accurate, stable orientation estimates — exactly what the MPU6050’s DMP does internally.
2. MPU6050 Overview & Key Features
The MPU6050 from InvenSense (now TDK) debuted in 2010 and remains a benchmark in low-cost 6-DOF motion sensing. The GY-521 breakout board is the common module form factor used by hobbyists.
Specifications
- Supply Voltage: 3.3 V (logic); GY-521 board includes a 3.3 V regulator, accepts 3.3-5 V input
- Interface: I2C (up to 400 kHz Fast Mode) plus auxiliary I2C master for external sensors
- Accelerometer Range (selectable): +/-2g, +/-4g, +/-8g, +/-16g
- Gyroscope Range (selectable): +/-250, +/-500, +/-1000, +/-2000 deg/s
- ADC Resolution: 16-bit for both accelerometer and gyroscope
- On-chip Temperature Sensor: +/-1 deg C accuracy
- Digital Motion Processor (DMP): On-chip processor for quaternion computation, reducing host CPU load
- FIFO Buffer: 1024 bytes
- Interrupt Output: Configurable on INT pin
- Power Consumption: 3.9 mA normal; 10 µA in sleep mode
3. Wiring MPU6050 to Arduino
GY-521 to Arduino Uno
GY-521 Pin --> Arduino Uno
VCC --> 3.3V (or 5V via onboard regulator)
GND --> GND
SCL --> A5 (SCL)
SDA --> A4 (SDA)
INT --> Digital Pin 2 (optional, for DMP interrupt)
AD0 --> GND (I2C address 0x68) or 3.3V (address 0x69)
Pull-up resistors: The I2C bus requires 4.7 kOhm pull-up resistors from SDA and SCL to 3.3 V. The GY-521 module includes these onboard, so no external resistors are needed when using a single device.
4. I2C Address & AD0 Pin
The MPU6050 has two possible I2C addresses:
- 0x68 — AD0 pin connected to GND (default on GY-521 via onboard pull-down)
- 0x69 — AD0 pin connected to 3.3 V
This allows two MPU6050 modules on the same I2C bus simultaneously — useful for dual-IMU projects like comparing two body segments or building redundant flight controllers.
#include <Wire.h>
void setup() {
Wire.begin(); Serial.begin(9600);
for (byte addr = 1; addr < 127; addr++) {
Wire.beginTransmission(addr);
if (Wire.endTransmission() == 0) {
Serial.print("I2C device at 0x");
Serial.println(addr, HEX);
}
}
}
void loop(){}
5. Reading Raw Registers in Arduino
#include <Wire.h>
const int MPU = 0x68;
int16_t AcX, AcY, AcZ, Tmp, GyX, GyY, GyZ;
void setup() {
Wire.begin();
Wire.beginTransmission(MPU);
Wire.write(0x6B);
Wire.write(0);
Wire.endTransmission(true);
Serial.begin(9600);
}
void loop() {
Wire.beginTransmission(MPU);
Wire.write(0x3B);
Wire.endTransmission(false);
Wire.requestFrom(MPU, 14, true);
AcX = Wire.read()<<8 | Wire.read();
AcY = Wire.read()<<8 | Wire.read();
AcZ = Wire.read()<<8 | Wire.read();
Tmp = Wire.read()<<8 | Wire.read();
GyX = Wire.read()<<8 | Wire.read();
GyY = Wire.read()<<8 | Wire.read();
GyZ = Wire.read()<<8 | Wire.read();
Serial.print("AcX:"); Serial.print(AcX);
Serial.print(" AcY:"); Serial.print(AcY);
Serial.print(" AcZ:"); Serial.println(AcZ);
delay(100);
}
6. Using the MPU6050 Library
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>
Adafruit_MPU6050 mpu;
void setup() {
Serial.begin(115200);
if (!mpu.begin()) {
Serial.println("MPU6050 not found!");
while (1) delay(10);
}
mpu.setAccelerometerRange(MPU6050_RANGE_8_G);
mpu.setGyroRange(MPU6050_RANGE_500_DEG);
mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);
}
void loop() {
sensors_event_t a, g, temp;
mpu.getEvent(&a, &g, &temp);
Serial.print("Accel X:"); Serial.print(a.acceleration.x); Serial.print(" m/s^2");
Serial.print(" Y:"); Serial.print(a.acceleration.y);
Serial.print(" Z:"); Serial.println(a.acceleration.z);
delay(100);
}
7. Converting Raw Values to Physical Units
| Range | Scale Factor (LSB/unit) | Physical Unit |
|---|---|---|
| Accel +/-2g | 16384 | g (9.81 m/s^2) |
| Accel +/-4g | 8192 | g |
| Accel +/-8g | 4096 | g |
| Gyro +/-250 deg/s | 131 | deg/s |
| Gyro +/-500 deg/s | 65.5 | deg/s |
| Gyro +/-2000 deg/s | 16.4 | deg/s |
Example: Raw AcZ = 16384 then 16384/16384 = 1.0 g, meaning the sensor is sitting flat with Z axis pointing up against gravity.
8. Using the DMP for Quaternions & Euler Angles
The DMP (Digital Motion Processor) is an on-chip processor that runs InvenSense’s proprietary sensor fusion algorithm. It reads the accelerometer and gyroscope at up to 8 kHz internally and outputs quaternions to the FIFO buffer at your chosen output data rate.
// Install: I2Cdevlib-MPU6050 from Library Manager
// Full DMP example: File > Examples > MPU6050 > MPU6050_DMP6
// Key output variables after DMP processing:
float ypr[3]; // ypr[0]=yaw, ypr[1]=pitch, ypr[2]=roll (in radians)
// Convert to degrees: ypr[i] * 180/M_PI
9. Calibration Procedure
Every MPU6050 has manufacturing offsets. Without calibration, gyro drift accumulates at 0.1-3 deg/s. The I2Cdevlib includes a calibration sketch (IMU_Zero) that iteratively adjusts the offset registers:
- Place the sensor on a perfectly flat, stable surface.
- Upload the IMU_Zero example sketch from the I2Cdevlib MPU6050 examples.
- Open Serial Monitor at 115200 baud. The sketch runs for about 5 minutes, printing offset values as it converges.
- Note the final XA_OFFSET, YA_OFFSET, ZA_OFFSET, XG_OFFSET, YG_OFFSET, ZG_OFFSET values.
- Hardcode them in your main sketch: mpu.setXAccelOffset(-1234); etc.
10. Python on Raspberry Pi
# Install: pip3 install mpu6050-raspberrypi
from mpu6050 import mpu6050
import time
sensor = mpu6050(0x68)
while True:
accel = sensor.get_accel_data()
gyro = sensor.get_gyro_data()
temp = sensor.get_temp()
print(f"Accel: X={accel['x']:.2f} Y={accel['y']:.2f} Z={accel['z']:.2f} m/s2")
print(f"Gyro: X={gyro['x']:.2f} Y={gyro['y']:.2f} Z={gyro['z']:.2f} deg/s")
print(f"Temp: {temp:.1f} C")
time.sleep(0.1)
11. Real Project Ideas
Self-Balancing Robot
The classic MPU6050 project: a two-wheeled robot that stays upright using PID control. The DMP provides pitch angle; PID outputs a motor correction signal. Tune Kp, Ki, Kd for your specific motor, wheel, and weight combination.
DS18B20 Programmable Resolution Temperature Sensor
High-accuracy 1-Wire temperature sensor — pair with MPU6050 to apply real-time thermal drift correction in precision applications.
Gesture-Controlled Glove
Mount the MPU6050 on the back of a glove. Map specific hand orientations (pitch plus roll combinations) to robot commands: tilt forward = move forward, tilt left = turn left, twist wrist = spin. Transmit wirelessly via NRF24L01 or HC-05 Bluetooth module.
Step Counter and Activity Tracker
Configure the MPU6050’s built-in motion detection hardware. The step counting algorithm detects the characteristic acceleration pattern of walking. Store step counts in EEPROM and display on an OLED screen for a wearable fitness tracker project.
Drone Flight Controller
The MPU6050 is the heart of nearly every DIY drone flight controller. The DMP provides 100 Hz quaternion updates; the flight controller translates these into motor ESC commands via PID loops for roll, pitch, and yaw axes.
Vibration and Shock Logger
In industrial applications, log peak g-forces during shipping or machinery operation. Configure the accelerometer at +/-16g range and use FIFO-based burst recording triggered by a threshold interrupt. Store to an SD card for later analysis.
12. Troubleshooting
- MPU6050 not found / I2C scanner shows nothing: Check SDA/SCL wiring, confirm power is 3.3 V or 5 V depending on your module, and verify Wire.begin() is called before any MPU communication.
- Erratic readings when stationary: Poor power supply — add 10 µF plus 100 nF decoupling capacitors close to the VCC pin. EMI from nearby motors or servos can corrupt I2C.
- Gyro drifts significantly: Run the calibration procedure and apply offsets. Ensure the sensor is at stable temperature before use.
- DMP fails to initialize: The DMP firmware upload via I2C requires a stable 400 kHz I2C bus. Use Wire.setClock(400000) and ensure pull-up resistors are correct.
- Yaw drifts without magnetometer: This is expected — yaw from a 6-DOF IMU always drifts over time. Add a compass (HMC5883L or QMC5883L) to the auxiliary I2C port for a 9-DOF system with stable yaw.
Frequently Asked Questions
What is the difference between MPU6050 and MPU9250?
The MPU9250 adds a built-in AK8963 3-axis magnetometer (compass), making it a 9-DOF IMU. The magnetometer enables stable yaw (heading) estimation without drift. If you need accurate heading for a robot or drone navigating large distances, the MPU9250 is worth the extra cost. For short-term orientation or balance applications, the MPU6050 is sufficient and cheaper.
Can I use MPU6050 with ESP32?
Yes, perfectly. The ESP32’s I2C runs at 3.3 V, compatible with the GY-521 module. Use Wire.begin(SDA_pin, SCL_pin) with your chosen GPIO pins (default on ESP32: GPIO 21 = SDA, GPIO 22 = SCL). The ESP32’s WiFi can cause I2C glitches; keep I2C wires short (under 15 cm).
How do I get pitch, roll, yaw from MPU6050?
Three approaches: (1) Accelerometer-only pitch/roll (stable, no gyro needed, but noisy during motion); (2) Complementary filter combining accelerometer and gyroscope (good balance of simplicity and accuracy); (3) DMP quaternions via I2Cdevlib (most accurate, uses on-chip sensor fusion). For yaw stability, you must add a magnetometer or use GPS heading.
How many MPU6050 sensors can I connect to one Arduino?
Two — one at address 0x68 (AD0=GND) and one at address 0x69 (AD0=3.3V). For more than two, use a TCA9548A I2C multiplexer that supports 8 I2C buses. This is commonly used in motion capture suits that track multiple body segments simultaneously.
What causes buzzing when MPU6050 is powered near motors?
The MPU6050 itself operates silently. Vibration noise from motors appears as high-frequency accelerometer readings. Mount the sensor on vibration-damping foam to reduce mechanical noise coupling from motors and drive belts into the sensor.
Add comment