Preview build — page text is a draft awaiting human review. Code badges come from real compiles. The flasher is real but not yet hardware-tested; the Playground is still a preview.

MPU6050 with Arduino Nano — pitch and roll over I2C

Wire an MPU6050 (GY-521) to an Arduino Nano on A4/A5, read acceleration and rotation, and print pitch and roll angles in degrees.

Arduino C++Verified — core avr 1.8.8, Adafruit MPU6050 2.2.9, 3 Nov 2026Compile-only

Community draft — report a mistake

The MPU6050 is the motion sensor in self-balancing robots, gesture controllers and tilt alarms. On the Nano it is an I2C device on A4 (SDA) and A5 (SCL), powered from 5V through the GY-521’s regulator.

The sketch prints pitch and roll worked out from gravity, plus the gyro’s Z-axis rate and the chip’s internal temperature (which reads a few degrees above room temperature — it is the die, not the air).

Wiring

Arduino NanoOnly the pins used are shown · 5 V logicMPU6050 (GY-521)A4A55VGNDVCCGNDSCLSDAXDA (not connected)XCL (not connected)AD0 (not connected)INT (not connected)
Every connection
Arduino NanoMPU6050 (GY-521)WireNotes
5VVCCredGY-521 has its own 3.3 V regulator.
GNDGNDblack
A5SCLyellow
A4SDAblue

3.3–5 V (on-board 3.3 V regulator) part, 5 V board. The GY-521 has a 3.3 V regulator and pulls SDA/SCL up to 3.3 V, so it works on both 3.3 V boards and a 5 V Uno without a level shifter.

Board quirks

  • Leave AD0 unconnected (or to GND) for address 0x68. Tie it to 5V for 0x69 when you need two sensors.
  • XDA/XCL are for an external magnetometer — leave them unconnected.
  • The GY-521 pulls SDA/SCL up to 3.3 V. The Nano reads that fine; the AVR Wire library also turns on weak internal pull-ups to 5 V, which the module tolerates in practice.
  • Pitch and roll from the accelerometer alone wobble when the board moves. For a balancing robot, add a complementary filter with the gyro.

Code

mpu6050-nano.inoArduino C++Open in PlaygroundOpen in PlaygroundFlash
// MPU6050 (GY-521) accelerometer + gyro on an Arduino Nano, with tilt angles in degrees.
// VCC → 5V (the module has a 3.3 V regulator), GND → GND, SCL → A5, SDA → A4. AD0 open = 0x68.
#include <Wire.h>
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>

Adafruit_MPU6050 mpu;

void setup() {
  Serial.begin(115200);
  if (!mpu.begin()) {
    Serial.println(F("MPU6050 not found - check A4/A5 wiring and address 0x68"));
    for (;;) {}
  }
  mpu.setAccelerometerRange(MPU6050_RANGE_4_G);
  mpu.setGyroRange(MPU6050_RANGE_500_DEG);
  mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);
  Serial.println(F("MPU6050 ready"));
}

void loop() {
  sensors_event_t a, g, temp;
  mpu.getEvent(&a, &g, &temp);
  float ax = a.acceleration.x, ay = a.acceleration.y, az = a.acceleration.z;
  float pitch = atan2(ax, sqrt(ay * ay + az * az)) * 57.2958;
  float roll = atan2(ay, az) * 57.2958;
  Serial.print(F("Pitch: "));
  Serial.print(pitch, 1);
  Serial.print(F("  Roll: "));
  Serial.print(roll, 1);
  Serial.print(F("  Gyro Z: "));
  Serial.print(g.gyro.z, 2);
  Serial.print(F(" rad/s  Chip temp: "));
  Serial.print(temp.temperature, 1);
  Serial.println(F(" C"));
  delay(250);
}

Library: Adafruit MPU6050 (Adafruit (also install Adafruit Unified Sensor and Adafruit BusIO)) — compiled with Adafruit MPU6050 2.2.9.

Expected serial output

Serial Monitor · 115200Output
MPU6050 ready
Pitch: 1.8  Roll: -0.6  Gyro Z: 0.01 rad/s  Chip temp: 31.2 C
Pitch: 24.5  Roll: -3.1  Gyro Z: -0.42 rad/s  Chip temp: 31.2 C

Common errors

MPU6050 not found

SDA/SCL swapped, AD0 floating at the wrong level, or a fake chip with a different WHO_AM_I. Full fix.

Sketch uses too much memory

The Adafruit stack uses about 14 KB of flash on a Nano — fine alone, but tight with an OLED too. Drop serial strings or switch to a lighter library.

↑↓ to move · Enter to open