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 ESP32 — accelerometer and gyroscope over I2C

Connect a GY-521 MPU6050 module to an ESP32 DevKit V1 (I2C on GPIO21/22, 3.3 V) and read acceleration, rotation and chip temperature in Arduino C++.

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

Community draft — report a mistake

The MPU6050 combines a 3-axis accelerometer and a 3-axis gyroscope; the GY-521 breakout adds a regulator and pull-ups, so it drops straight onto the ESP32’s I2C pins.

Power it from 3V3 and wire SDA/SCL to GPIO21/GPIO22. The sketch sets a ±4 g and ±500 °/s range with a 21 Hz filter — a good default for tilt sensing, robots and gesture projects — and prints all six axes twice a second.

Wiring

ESP32 DevKit V1Only the pins used are shown · 3.3 V logicMPU6050 (GY-521)GNDD22D213V3VCCGNDSCLSDAXDA (not connected)XCL (not connected)AD0 (not connected)INT (not connected)
Every connection
ESP32 DevKit V1MPU6050 (GY-521)WireNotes
3V3VCCredThe GY-521 has its own 3.3 V regulator; from 3V3 it still works and its I2C pull-ups stay at 3.3 V.
GNDGNDblack
D22SCLyellow
D21SDAblue

3.3–5 V (on-board 3.3 V regulator) part, 3.3 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

  • GPIO21 (SDA) and GPIO22 (SCL) are the ESP32’s default I2C pins — Wire.begin(21, 22) just makes that explicit.
  • AD0 is left unconnected, so the address is 0x68. Tie AD0 to 3V3 for 0x69 if you need two MPU6050s.
  • XDA, XCL and INT are not needed for basic readings.

Code

mpu6050-esp32.inoArduino C++Open in PlaygroundOpen in PlaygroundFlash
// MPU6050 (GY-521) accelerometer + gyroscope on an ESP32 DevKit V1.
// VCC → 3V3, GND → GND, SDA → D21, SCL → D22. Address 0x68 (AD0 low).
#include <Wire.h>
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>

Adafruit_MPU6050 mpu;

void setup() {
  Serial.begin(115200);
  Wire.begin(21, 22);  // SDA, SCL
  if (!mpu.begin(0x68, &Wire)) {
    Serial.println("MPU6050 not found at 0x68 — check wiring, or try 0x69 if AD0 is high");
    while (true) delay(1000);
  }
  mpu.setAccelerometerRange(MPU6050_RANGE_4_G);
  mpu.setGyroRange(MPU6050_RANGE_500_DEG);
  mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);
  Serial.println("MPU6050 ready");
}

void loop() {
  sensors_event_t a, g, t;
  mpu.getEvent(&a, &g, &t);
  Serial.printf("Accel X %.2f Y %.2f Z %.2f m/s²  Gyro X %.2f Y %.2f Z %.2f rad/s  Chip %.1f °C\n",
                a.acceleration.x, a.acceleration.y, a.acceleration.z,
                g.gyro.x, g.gyro.y, g.gyro.z, t.temperature);
  delay(500);
}

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
Accel X 0.21 Y -0.34 Z 9.71 m/s²  Gyro X -0.02 Y 0.01 Z 0.00 rad/s  Chip 29.4 °C
Accel X 0.19 Y -0.36 Z 9.73 m/s²  Gyro X -0.03 Y 0.01 Z 0.01 rad/s  Chip 29.4 °C

Common errors

“MPU6050 not found at 0x68”

Check SDA/SCL are not swapped, then run the I2C scanner. Some clones answer at 0x69 or carry a different chip ID.

Readings drift when the board is still

Normal gyro bias. Average a few hundred readings at rest and subtract that offset, or use the accelerometer for tilt.

↑↓ to move · Enter to open