Complete Tutorial: Motion Sensing with Gyroscope & Accelerometer
The MPU-6050 is a popular 6-axis Inertial Measurement Unit (IMU) that combines a 3-axis gyroscope and a 3-axis accelerometer on a single chip. Made by InvenSense (now TDK), it's widely used in drones, robots, game controllers, and motion-tracking applications.
This sensor can detect linear acceleration (movement) and angular velocity (rotation), making it perfect for determining orientation, detecting gestures, balancing robots, or stabilizing camera gimbals.
| Parameter | Specification |
|---|---|
| Operating Voltage | 2.375V – 3.46V (module: 3.3V – 5V) |
| Interface | I2C (up to 400kHz) / SPI |
| Gyroscope Range | ±250, ±500, ±1000, ±2000 °/s |
| Accelerometer Range | ±2g, ±4g, ±8g, ±16g |
| I2C Address | 0x68 (AD0=LOW) or 0x69 (AD0=HIGH) |
| ADC Resolution | 16-bit |
| Current Consumption | 3.9mA (normal mode) |
The MPU-6050 measures motion in 3 dimensions:
Accelerometer: Measures linear acceleration including gravity. When stationary, it reads 1g on the Z-axis (9.8 m/s²).
Gyroscope: Measures rotation speed (degrees per second). When stationary, it reads 0 on all axes.
| MPU-6050 Pin | Description | ESP32 | Arduino Uno |
|---|---|---|---|
| VCC | Power (3.3V-5V) | 3.3V | 5V |
| GND | Ground | GND | GND |
| SCL | I2C Clock | GPIO 22 | A5 |
| SDA | I2C Data | GPIO 21 | A4 |
| AD0 | Address Select | GND (for 0x68) | GND (for 0x68) |
| INT | Interrupt (optional) | Any GPIO | Any Digital Pin |
Figure 1: MPU-6050 I2C wiring with ESP32
Install Adafruit MPU6050 and Adafruit Unified Sensor via Arduino Library Manager.
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>
Adafruit_MPU6050 mpu;
void setup() {
Serial.begin(115200);
Serial.println("MPU-6050 Motion Monitor");
if (!mpu.begin()) {
Serial.println("ERROR: MPU-6050 not found!");
while (1) delay(10);
}
// Configure sensor ranges
mpu.setAccelerometerRange(MPU6050_RANGE_8_G);
mpu.setGyroRange(MPU6050_RANGE_500_DEG);
mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);
Serial.println("MPU-6050 Ready!");
delay(1000);
}
void loop() {
sensors_event_t a, g, temp;
mpu.getEvent(&a, &g, &temp);
// Accelerometer (m/s^2)
Serial.print("Accel X:"); Serial.print(a.acceleration.x, 2);
Serial.print(" Y:"); Serial.print(a.acceleration.y, 2);
Serial.print(" Z:"); Serial.print(a.acceleration.z, 2);
// Gyroscope (rad/s)
Serial.print(" | Gyro X:"); Serial.print(g.gyro.x, 2);
Serial.print(" Y:"); Serial.print(g.gyro.y, 2);
Serial.print(" Z:"); Serial.print(g.gyro.z, 2);
// Temperature
Serial.print(" | Temp:"); Serial.print(temp.temperature, 1);
Serial.println(" C");
delay(100);
}
// Simple tilt detection using accelerometer
void loop() {
sensors_event_t a, g, temp;
mpu.getEvent(&a, &g, &temp);
// Calculate tilt angles (in degrees)
float pitch = atan2(a.acceleration.y, a.acceleration.z) * 180.0 / PI;
float roll = atan2(-a.acceleration.x,
sqrt(a.acceleration.y*a.acceleration.y +
a.acceleration.z*a.acceleration.z)) * 180.0 / PI;
Serial.print("Pitch: "); Serial.print(pitch, 1);
Serial.print("° | Roll: "); Serial.print(roll, 1);
Serial.println("°");
delay(100);
}