Blog

GY-521 MPU-6050 3-Axis Gyroscope & Accelerometer Module – Complete Guide

6-Axis IMU

GY-521 MPU-6050 3-Axis Gyroscope & Accelerometer Module

6-DOF Motion Tracking with I2C Interface

The MPU-6050 packs two separate MEMS (micro-electro-mechanical system) sensors into one chip. The accelerometer works by measuring the tiny deflection of a microscopic proof mass suspended on springs etched directly into silicon - as the chip tilts or accelerates, that mass shifts fractions of a micrometer, and the change in capacitance between it and fixed electrodes around it is converted into a digital acceleration value on each of the three axes. The gyroscope uses a related MEMS structure that exploits the Coriolis effect: a mass is kept vibrating at a fixed rate, and when the chip rotates, that rotation deflects the vibrating mass sideways in proportion to the rotation rate, which is again read out capacitively. Both raw signals are digitized by 16-bit ADCs and, crucially, fed into an onboard Digital Motion Processor that can fuse the drift-prone gyro data with the noise-prone accelerometer data into a stable orientation estimate in hardware - work that would otherwise have to run as a Kalman or complementary filter on your own microcontroller. It has been the go-to inertial measurement unit for hobbyist robotics and flight controllers for years thanks to its low cost, solid documentation, and mature library support; the GY-521 breakout adds a voltage regulator and I2C pull-ups so it can be wired directly to 5V boards like an Arduino Uno.

6 (3-axis Gyro + 3-axis Accel)
Axes
I2C (up to 400 kHz)
Interface
16-bit
ADC Resolution

Key features

Onboard Digital Motion Processor

A built-in DMP can perform sensor fusion in hardware, offloading complex motion-tracking math from your microcontroller.

Selectable Gyro Range

Programmable full-scale range of ±250/500/1000/2000°/s to trade off sensitivity against maximum measurable rotation speed.

Selectable Accelerometer Range

Programmable full-scale range of ±2/4/8/16g for anything from gentle tilt sensing to high-impact motion capture.

Auxiliary I2C Bus

A secondary I2C port can host an external magnetometer for a full 9-axis solution without extra microcontroller pins.

Built-In Temperature Sensor

An onboard die temperature reading is available alongside the motion data at no extra cost.

5V-Tolerant Breakout

The GY-521 module's onboard regulator and level shifting let it connect directly to 5V logic boards.

Technical specifications

Supply Voltage (breakout) 3V – 5V DC
Interface I2C, up to 400 kHz
I2C Address 0x68 (0x69 with AD0 pulled high)
Gyro Full-Scale Range ±250 / 500 / 1000 / 2000 °/s
Accelerometer Full-Scale Range ±2 / 4 / 8 / 16 g
ADC Resolution 16-bit per axis
Gyro Sensitivity (±250° range) 131 LSB / °/s
Operating Temperature -40°C to +85°C
Breakout Dimensions ~20 × 16 mm

Pinout

PinFunction
VCC Power supply, 3V-5V on the breakout board
GND Ground
SCL I2C clock line
SDA I2C data line
INT Interrupt output - signals when new data is ready
AD0 I2C address select - LOW=0x68 (default), HIGH=0x69

Applications

Drone and quadcopter flight stabilization Self-balancing robots Gesture-controlled interfaces Gimbal and camera stabilization VR and motion-tracking peripherals Pedometers and activity tracking

What's in the box

1x GY-521 MPU-6050 breakout board
Header pins (may require soldering)

Downloads

Datasheet (PDF) Register Map (PDF) Arduino Library (MPU6050)
🔌
Pin Connections
1 Table
Pin Connections Table 1
BoardSensor PinConnection
MPU-6050VCC/GND/SDA/SCL3.3-5V (module has a regulator) / GND / board SDA / board SCL
📟
GY-521 MPU-6050 I2C Module 3-Axis Gyro & Accelerometer for Arduino
7 Examples • C/C++ | Boards: Arduino Uno, Arduino Nano, Arduino Mega, ESP32, ESP8266, STM32, Raspberry Pi Pico
GY-521 MPU-6050 I2C Module 3-Axis Gyro & Accelerometer for Arduino - Arduino Uno
GY-521 MPU-6050 I2C Module 3-Axis Gyro & Accelerometer for Arduino - Arduino Nano
GY-521 MPU-6050 I2C Module 3-Axis Gyro & Accelerometer for Arduino - Arduino Mega
GY-521 MPU-6050 I2C Module 3-Axis Gyro & Accelerometer for Arduino - ESP32
GY-521 MPU-6050 I2C Module 3-Axis Gyro & Accelerometer for Arduino - ESP8266
GY-521 MPU-6050 I2C Module 3-Axis Gyro & Accelerometer for Arduino - STM32
GY-521 MPU-6050 I2C Module 3-Axis Gyro & Accelerometer for Arduino - Raspberry Pi Pico
📄 File: gy-521_mpu-6050_i2c_module_3-axis_gyro_&_accelerometer_for_arduino_-_arduino_uno.inoArduino Uno
1418 characters
1//ekostra.com
2//electronics store in egypt
3//+201008896258
4
5// I2C wiring for Arduino Uno: A4=SDA, A5=SCL. VCC->3.3V or 5V per module label, GND->GND.
6#include <Wire.h>
7#define MPU_ADDR 0x68 // MPU-6050 I2C address (AD0 low)
8
9int16_t ax, ay, az, gx, gy, gz;
10
11void setup() {
12 Serial.begin(115200);
13 Wire.begin(); // uses this board's default SDA/SCL pins
14 Wire.beginTransmission(MPU_ADDR);
15 Wire.write(0x6B); // PWR_MGMT_1 register
16 Wire.write(0); // wake the MPU-6050 up (it starts in sleep mode)
17 Wire.endTransmission(true);
18}
19
20void loop() {
21 Wire.beginTransmission(MPU_ADDR);
22 Wire.write(0x3B); // starting register: ACCEL_XOUT_H
23 Wire.endTransmission(false);
24 Wire.requestFrom(MPU_ADDR, 14, true); // 7 registers x 2 bytes
25
26 ax = Wire.read() << 8 | Wire.read();
27 ay = Wire.read() << 8 | Wire.read();
28 az = Wire.read() << 8 | Wire.read();
29 Wire.read(); Wire.read(); // skip temperature registers
30 gx = Wire.read() << 8 | Wire.read();
31 gy = Wire.read() << 8 | Wire.read();
32 gz = Wire.read() << 8 | Wire.read();
33
34 Serial.print("Accel X="); Serial.print(ax / 16384.0);
35 Serial.print("g Y="); Serial.print(ay / 16384.0);
36 Serial.print("g Z="); Serial.print(az / 16384.0);
37 Serial.print("g Gyro X="); Serial.print(gx / 131.0);
38 Serial.print(" Y="); Serial.print(gy / 131.0);
39 Serial.print(" Z="); Serial.println(gz / 131.0);
40
41 delay(200);
42}
📄 File: gy-521_mpu-6050_i2c_module_3-axis_gyro_&_accelerometer_for_arduino_-_arduino_nano.inoArduino Nano
1419 characters
1//ekostra.com
2//electronics store in egypt
3//+201008896258
4
5// I2C wiring for Arduino Nano: A4=SDA, A5=SCL. VCC->3.3V or 5V per module label, GND->GND.
6#include <Wire.h>
7#define MPU_ADDR 0x68 // MPU-6050 I2C address (AD0 low)
8
9int16_t ax, ay, az, gx, gy, gz;
10
11void setup() {
12 Serial.begin(115200);
13 Wire.begin(); // uses this board's default SDA/SCL pins
14 Wire.beginTransmission(MPU_ADDR);
15 Wire.write(0x6B); // PWR_MGMT_1 register
16 Wire.write(0); // wake the MPU-6050 up (it starts in sleep mode)
17 Wire.endTransmission(true);
18}
19
20void loop() {
21 Wire.beginTransmission(MPU_ADDR);
22 Wire.write(0x3B); // starting register: ACCEL_XOUT_H
23 Wire.endTransmission(false);
24 Wire.requestFrom(MPU_ADDR, 14, true); // 7 registers x 2 bytes
25
26 ax = Wire.read() << 8 | Wire.read();
27 ay = Wire.read() << 8 | Wire.read();
28 az = Wire.read() << 8 | Wire.read();
29 Wire.read(); Wire.read(); // skip temperature registers
30 gx = Wire.read() << 8 | Wire.read();
31 gy = Wire.read() << 8 | Wire.read();
32 gz = Wire.read() << 8 | Wire.read();
33
34 Serial.print("Accel X="); Serial.print(ax / 16384.0);
35 Serial.print("g Y="); Serial.print(ay / 16384.0);
36 Serial.print("g Z="); Serial.print(az / 16384.0);
37 Serial.print("g Gyro X="); Serial.print(gx / 131.0);
38 Serial.print(" Y="); Serial.print(gy / 131.0);
39 Serial.print(" Z="); Serial.println(gz / 131.0);
40
41 delay(200);
42}
📄 File: gy-521_mpu-6050_i2c_module_3-axis_gyro_&_accelerometer_for_arduino_-_arduino_mega.inoArduino Mega
1421 characters
1//ekostra.com
2//electronics store in egypt
3//+201008896258
4
5// I2C wiring for Arduino Mega: D20=SDA, D21=SCL. VCC->3.3V or 5V per module label, GND->GND.
6#include <Wire.h>
7#define MPU_ADDR 0x68 // MPU-6050 I2C address (AD0 low)
8
9int16_t ax, ay, az, gx, gy, gz;
10
11void setup() {
12 Serial.begin(115200);
13 Wire.begin(); // uses this board's default SDA/SCL pins
14 Wire.beginTransmission(MPU_ADDR);
15 Wire.write(0x6B); // PWR_MGMT_1 register
16 Wire.write(0); // wake the MPU-6050 up (it starts in sleep mode)
17 Wire.endTransmission(true);
18}
19
20void loop() {
21 Wire.beginTransmission(MPU_ADDR);
22 Wire.write(0x3B); // starting register: ACCEL_XOUT_H
23 Wire.endTransmission(false);
24 Wire.requestFrom(MPU_ADDR, 14, true); // 7 registers x 2 bytes
25
26 ax = Wire.read() << 8 | Wire.read();
27 ay = Wire.read() << 8 | Wire.read();
28 az = Wire.read() << 8 | Wire.read();
29 Wire.read(); Wire.read(); // skip temperature registers
30 gx = Wire.read() << 8 | Wire.read();
31 gy = Wire.read() << 8 | Wire.read();
32 gz = Wire.read() << 8 | Wire.read();
33
34 Serial.print("Accel X="); Serial.print(ax / 16384.0);
35 Serial.print("g Y="); Serial.print(ay / 16384.0);
36 Serial.print("g Z="); Serial.print(az / 16384.0);
37 Serial.print("g Gyro X="); Serial.print(gx / 131.0);
38 Serial.print(" Y="); Serial.print(gy / 131.0);
39 Serial.print(" Z="); Serial.println(gz / 131.0);
40
41 delay(200);
42}
📄 File: gy-521_mpu-6050_i2c_module_3-axis_gyro_&_accelerometer_for_arduino_-_esp32.inoESP32
1420 characters
1//ekostra.com
2//electronics store in egypt
3//+201008896258
4
5// I2C wiring for ESP32: GPIO21=SDA, GPIO22=SCL. VCC->3.3V or 5V per module label, GND->GND.
6#include <Wire.h>
7#define MPU_ADDR 0x68 // MPU-6050 I2C address (AD0 low)
8
9int16_t ax, ay, az, gx, gy, gz;
10
11void setup() {
12 Serial.begin(115200);
13 Wire.begin(); // uses this board's default SDA/SCL pins
14 Wire.beginTransmission(MPU_ADDR);
15 Wire.write(0x6B); // PWR_MGMT_1 register
16 Wire.write(0); // wake the MPU-6050 up (it starts in sleep mode)
17 Wire.endTransmission(true);
18}
19
20void loop() {
21 Wire.beginTransmission(MPU_ADDR);
22 Wire.write(0x3B); // starting register: ACCEL_XOUT_H
23 Wire.endTransmission(false);
24 Wire.requestFrom(MPU_ADDR, 14, true); // 7 registers x 2 bytes
25
26 ax = Wire.read() << 8 | Wire.read();
27 ay = Wire.read() << 8 | Wire.read();
28 az = Wire.read() << 8 | Wire.read();
29 Wire.read(); Wire.read(); // skip temperature registers
30 gx = Wire.read() << 8 | Wire.read();
31 gy = Wire.read() << 8 | Wire.read();
32 gz = Wire.read() << 8 | Wire.read();
33
34 Serial.print("Accel X="); Serial.print(ax / 16384.0);
35 Serial.print("g Y="); Serial.print(ay / 16384.0);
36 Serial.print("g Z="); Serial.print(az / 16384.0);
37 Serial.print("g Gyro X="); Serial.print(gx / 131.0);
38 Serial.print(" Y="); Serial.print(gy / 131.0);
39 Serial.print(" Z="); Serial.println(gz / 131.0);
40
41 delay(200);
42}
📄 File: gy-521_mpu-6050_i2c_module_3-axis_gyro_&_accelerometer_for_arduino_-_esp8266.inoESP8266
1428 characters
1//ekostra.com
2//electronics store in egypt
3//+201008896258
4
5// I2C wiring for ESP8266: D2(GPIO4)=SDA, D1(GPIO5)=SCL. VCC->3.3V or 5V per module label, GND->GND.
6#include <Wire.h>
7#define MPU_ADDR 0x68 // MPU-6050 I2C address (AD0 low)
8
9int16_t ax, ay, az, gx, gy, gz;
10
11void setup() {
12 Serial.begin(115200);
13 Wire.begin(); // uses this board's default SDA/SCL pins
14 Wire.beginTransmission(MPU_ADDR);
15 Wire.write(0x6B); // PWR_MGMT_1 register
16 Wire.write(0); // wake the MPU-6050 up (it starts in sleep mode)
17 Wire.endTransmission(true);
18}
19
20void loop() {
21 Wire.beginTransmission(MPU_ADDR);
22 Wire.write(0x3B); // starting register: ACCEL_XOUT_H
23 Wire.endTransmission(false);
24 Wire.requestFrom(MPU_ADDR, 14, true); // 7 registers x 2 bytes
25
26 ax = Wire.read() << 8 | Wire.read();
27 ay = Wire.read() << 8 | Wire.read();
28 az = Wire.read() << 8 | Wire.read();
29 Wire.read(); Wire.read(); // skip temperature registers
30 gx = Wire.read() << 8 | Wire.read();
31 gy = Wire.read() << 8 | Wire.read();
32 gz = Wire.read() << 8 | Wire.read();
33
34 Serial.print("Accel X="); Serial.print(ax / 16384.0);
35 Serial.print("g Y="); Serial.print(ay / 16384.0);
36 Serial.print("g Z="); Serial.print(az / 16384.0);
37 Serial.print("g Gyro X="); Serial.print(gx / 131.0);
38 Serial.print(" Y="); Serial.print(gy / 131.0);
39 Serial.print(" Z="); Serial.println(gz / 131.0);
40
41 delay(200);
42}
📄 File: gy-521_mpu-6050_i2c_module_3-axis_gyro_&_accelerometer_for_arduino_-_stm32.inoSTM32
1435 characters
1//ekostra.com
2//electronics store in egypt
3//+201008896258
4
5// I2C wiring for STM32: PB7=SDA, PB6=SCL (Blue Pill / F103C8). VCC->3.3V or 5V per module label, GND->GND.
6#include <Wire.h>
7#define MPU_ADDR 0x68 // MPU-6050 I2C address (AD0 low)
8
9int16_t ax, ay, az, gx, gy, gz;
10
11void setup() {
12 Serial.begin(115200);
13 Wire.begin(); // uses this board's default SDA/SCL pins
14 Wire.beginTransmission(MPU_ADDR);
15 Wire.write(0x6B); // PWR_MGMT_1 register
16 Wire.write(0); // wake the MPU-6050 up (it starts in sleep mode)
17 Wire.endTransmission(true);
18}
19
20void loop() {
21 Wire.beginTransmission(MPU_ADDR);
22 Wire.write(0x3B); // starting register: ACCEL_XOUT_H
23 Wire.endTransmission(false);
24 Wire.requestFrom(MPU_ADDR, 14, true); // 7 registers x 2 bytes
25
26 ax = Wire.read() << 8 | Wire.read();
27 ay = Wire.read() << 8 | Wire.read();
28 az = Wire.read() << 8 | Wire.read();
29 Wire.read(); Wire.read(); // skip temperature registers
30 gx = Wire.read() << 8 | Wire.read();
31 gy = Wire.read() << 8 | Wire.read();
32 gz = Wire.read() << 8 | Wire.read();
33
34 Serial.print("Accel X="); Serial.print(ax / 16384.0);
35 Serial.print("g Y="); Serial.print(ay / 16384.0);
36 Serial.print("g Z="); Serial.print(az / 16384.0);
37 Serial.print("g Gyro X="); Serial.print(gx / 131.0);
38 Serial.print(" Y="); Serial.print(gy / 131.0);
39 Serial.print(" Z="); Serial.println(gz / 131.0);
40
41 delay(200);
42}
📄 File: gy-521_mpu-6050_i2c_module_3-axis_gyro_&_accelerometer_for_arduino_-_raspberry_pi_pico.inoRaspberry Pi Pico
1430 characters
1//ekostra.com
2//electronics store in egypt
3//+201008896258
4
5// I2C wiring for Raspberry Pi Pico: GPIO4=SDA, GPIO5=SCL. VCC->3.3V or 5V per module label, GND->GND.
6#include <Wire.h>
7#define MPU_ADDR 0x68 // MPU-6050 I2C address (AD0 low)
8
9int16_t ax, ay, az, gx, gy, gz;
10
11void setup() {
12 Serial.begin(115200);
13 Wire.begin(); // uses this board's default SDA/SCL pins
14 Wire.beginTransmission(MPU_ADDR);
15 Wire.write(0x6B); // PWR_MGMT_1 register
16 Wire.write(0); // wake the MPU-6050 up (it starts in sleep mode)
17 Wire.endTransmission(true);
18}
19
20void loop() {
21 Wire.beginTransmission(MPU_ADDR);
22 Wire.write(0x3B); // starting register: ACCEL_XOUT_H
23 Wire.endTransmission(false);
24 Wire.requestFrom(MPU_ADDR, 14, true); // 7 registers x 2 bytes
25
26 ax = Wire.read() << 8 | Wire.read();
27 ay = Wire.read() << 8 | Wire.read();
28 az = Wire.read() << 8 | Wire.read();
29 Wire.read(); Wire.read(); // skip temperature registers
30 gx = Wire.read() << 8 | Wire.read();
31 gy = Wire.read() << 8 | Wire.read();
32 gz = Wire.read() << 8 | Wire.read();
33
34 Serial.print("Accel X="); Serial.print(ax / 16384.0);
35 Serial.print("g Y="); Serial.print(ay / 16384.0);
36 Serial.print("g Z="); Serial.print(az / 16384.0);
37 Serial.print("g Gyro X="); Serial.print(gx / 131.0);
38 Serial.print(" Y="); Serial.print(gy / 131.0);
39 Serial.print(" Z="); Serial.println(gz / 131.0);
40
41 delay(200);
42}
6-axis IMU (3-axis accelerometer + 3-axis gyroscope) over I2C. Reads raw accel/gyro registers directly, no external library needed.
Always calibrate the sensor at startup by averaging a few hundred readings while it sits perfectly still - this removes the small gyro and accelerometer bias every individual chip has out of the factory, and that offset is usually large enough to make raw readings visibly drift within seconds if you skip this step. For beginners, a simple complementary filter combining accelerometer and gyro data (roughly: trust the gyro for fast changes, trust the accelerometer to correct long-term drift) is much easier to get working reliably than the onboard DMP firmware, which has a notoriously fiddly closed-source blob in most community libraries. Mount the module rigidly - any flex or vibration in the mounting itself shows up as noise the sensor cannot distinguish from real motion.