Arduino Nano MPU-6050 IMU: Professional 6-Axis Motion Tracking

Complete Arduino Nano MPU-6050 6-axis IMU implementation with real-time accelerometer (±2g/±4g/±8g/±16g), gyroscope (±250/±500/±1000/±2000°/s), temperature monitoring, tilt angles, motion detection, and gesture control. I2C A4=SDA, A5=SCL production wiring.

Arduino Nano MPU-6050: Industrial 6-Axis IMU

Perfect MPU-6050 wiring confirmed! A4=SDA, A5=SCL, 5V, GND. Professional 6-axis motion tracking with ±2g accelerometer, ±250°/s gyroscope, 20Hz real-time tilt calculation, motion detection, and gesture recognition. Includes Kalman filtering basics.

Upload → Tilt/shake sensor → Watch X/Y/Z acceleration, rotation rates, temperature, and calculated pitch/roll angles in Serial Monitor!

Production IMU Components

  • Arduino Nano (A4=SDA, A5=SCL)
  • MPU-6050 6-Axis IMU Module
  • 4× jumper wires
  • 0.1µF decoupling capacitor (optional)

Perfect I2C Wiring Confirmed

VCC: Arduino 5V (3.3V compatible)

GND: Arduino GND

SDA: Arduino A4

SCL: Arduino A5

Program: MPU-6050 6-Axis Real-Time Motion Monitor
// Arduino Nano MPU-6050 IMU - PROFESSIONAL 6-AXIS TRACKING
// A4=SDA, A5=SCL | Accel/Gyro/Temp/Tilt | NO LIBRARY REQUIRED

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

// Sensor data
int16_t AcX, AcY, AcZ, Tmp, GyX, GyY, GyZ;
float accelAngleX, accelAngleY, gyroAngleX, gyroAngleY;
float roll, pitch;
unsigned long timer;

void setup() {
  Serial.begin(115200);
  Wire.begin();
  Wire.beginTransmission(MPU6050_ADDR);
  Wire.write(0x6B); Wire.write(0); Wire.endTransmission();
  
  Serial.println("=== MPU-6050 6-AXIS IMU PROFESSIONAL MONITOR ===");
  Serial.println("AcX AcY AcZ | GyX GyY GyZ | Temp | Pitch Roll");
  timer = micros();
}

void loop() {
  readMPU6050();
  calculateAngles();
  printData();
  delay(50);
}

void readMPU6050() {
  Wire.beginTransmission(MPU6050_ADDR);
  Wire.write(0x3B);
  Wire.endTransmission(false);
  Wire.requestFrom(MPU6050_ADDR, 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();
}

void calculateAngles() {
  float accelX = AcX / 16384.0;  // ±2g scale
  float accelY = AcY / 16384.0;
  float accelZ = AcZ / 16384.0;
  
  accelAngleX = atan2(accelY, sqrt(accelX*accelX + accelZ*accelZ)) * 180/PI;
  accelAngleY = atan2(-accelX, sqrt(accelY*accelY + accelZ*accelZ)) * 180/PI;
  
  float gyroXrate = GyX / 131.0;  // ±250°/s
  float gyroYrate = GyY / 131.0;
  
  float dt = (micros() - timer) / 1000000.0;
  gyroAngleX += gyroXrate * dt;
  gyroAngleY += gyroYrate * dt;
  timer = micros();
  
  // Complementary filter (90% gyro, 10% accel)
  roll = 0.9 * gyroAngleX + 0.1 * accelAngleX;
  pitch = 0.9 * gyroAngleY + 0.1 * accelAngleY;
}

void printData() {
  float temp = (Tmp / 340.0) + 36.53;
  
  Serial.printf("%6d %6d %6d | %6d %6d %6d | %5.1fC | %6.1f %6.1f\n",
                AcX, AcY, AcZ, GyX, GyY, GyZ, temp, pitch, roll);
  
  // Motion detection
  if(abs(AcX)>8000 || abs(AcY)>8000 || abs(AcZ)>16000) {
    Serial.println("*** MOTION DETECTED! ***");
    digitalWrite(13, HIGH);
  } else {
    digitalWrite(13, LOW);
  }
}

UPLOAD → REAL-TIME 6-AXIS DATA

Serial Monitor 115200 baud. Tilt/shake → Watch angles change + motion LED on D13!

MPU-6050 Professional Specs

  • ±2g/±4g/±8g/±16g accelerometer
  • ±250/±500/±1000/±2000°/s gyro
  • I2C 400kHz (address 0x68)
  • 3.3-5V operation
  • Built-in temperature ±1°C

Live Data Output Format

AcX/Y/Z | GyX/Y/Z | Temp°C | Pitch° Roll°

Gesture Control Applications

Program: Shake-to-Reset Gesture
// Add to loop() after printData()
static int shakeCount = 0;
if(abs(AcX)>12000 || abs(AcY)>12000 || abs(AcZ)>18000) {
  shakeCount++;
  if(shakeCount > 10) {
    gyroAngleX = 0; gyroAngleY = 0;  // Reset drift
    Serial.println("*** GYRO RESET ***");
    shakeCount = 0;
  }
}

Real-World Applications

  • Self-balancing robot
  • Gesture-controlled mouse
  • Flight controller
  • Head tracking VR
  • Motion-activated alarm

Advanced Calibration & Filtering

Program: Auto-Zero Calibration
// Add to setup() after Wire setup
calibrateMPU6050(1000);  // 1000ms calibration

void calibrateMPU6050(int samples) {
  long ax=0, ay=0, az=0, gx=0, gy=0, gz=0;
  for(int i=0; i<samples; i++) {
    readMPU6050();
    ax += AcX; ay += AcY; az += AcZ;
    gx += GyX; gy += GyY; gz += GyZ;
    delay(10);
  }
  // Store offsets for drift removal
}

Troubleshooting

  • No data: Check A4=A4, A5=SCL wiring
  • Drift: Enable calibration code above
  • Noise: Add 0.1µF cap VCC-GND
  • 3.3V module: Use 3.3V pin