Documentation

MPU9250 Authentic GY-9250 Pre-Soldered 9-Axis 9 DOF Accelerometer + Magnetometer
Documentation / MPU9250 Authentic GY-9250 Pre-Soldered 9-Axis 9 DOF Accelerometer + Magnetometer

MPU9250 Authentic GY-9250 Pre-Soldered 9-Axis 9 DOF Accelerometer + Magnetometer

Overview

The MPU9250 is a 9-axis inertial measurement unit (IMU) that combines a 3-axis accelerometer, 3-axis gyroscope, and 3-axis magnetometer into a single chip. That means a full picture of motion and orientation in space: how your device is accelerating, how fast it's rotating, and which way is north — all in one small breakout board. It's the standard choice for drones, robots, stabilized cameras, VR/AR controllers, attitude/heading reference systems, and gesture-controlled projects.

Internally, the MPU9250 is a package with two dies: an MPU6500 (accel + gyro) and an AK8963 (magnetometer). The chip communicates over I2C or SPI and includes an onboard Digital Motion Processor (DMP) for sensor fusion. ShillehTek's authentic GY-9250 module ships pre-soldered with headers attached and exposes all function pins (VCC, GND, SCL, SDA, EDA, ECL, ADO, INT, NCS, FSYNC) for maximum flexibility. The default I2C address is 0x68, selectable to 0x69 via the ADO pin.

This manual covers specifications, the pinout, wiring for Arduino, ESP32, Raspberry Pi, and the Pico, a working "hello world" code example for each platform, and FAQs on calibration, tilt compensation, and interrupts.

At a Glance

Axes
9 (3 Accel / 3 Gyro / 3 Mag)
Voltage
3.3V - 5V
Interface
I2C / SPI
I2C Address
0x68 / 0x69
Accel Range
±2/4/8/16 g
Gyro Range
±250/500/1000/2000 °/s

Specifications

Parameter Value
Sensor IC InvenSense MPU-9250 (MPU6500 + AK8963)
Accelerometer Ranges ±2g, ±4g, ±8g, ±16g (16-bit)
Gyroscope Ranges ±250, ±500, ±1000, ±2000 °/s (16-bit)
Magnetometer Range ±4,800 µT (14-bit or 16-bit)
Communication I2C (up to 400 kHz) or SPI (up to 1 MHz)
I2C Addresses 0x68 (ADO = LOW) / 0x69 (ADO = HIGH)
Magnetometer Address 0x0C (bypass mode)
Operating Voltage 3.3V - 5V (onboard regulator)
Sample Rate Up to 4 kHz (gyro), 1 kHz (accel), 100 Hz (mag)
DMP Onboard Digital Motion Processor
Current Draw ~3.5 mA (typical)
Pin Count 10 (VCC, GND, SCL, SDA, EDA, ECL, ADO, INT, NCS, FSYNC)

Pinout Diagram

MPU9250 GY-9250 Pinout Diagram

Wiring Guide

Arduino Wiring

The onboard regulator allows 5V supply from an Arduino Uno. Only four pins are needed for basic I2C readings.

Module Pin Arduino Pin Details
VCC 5V Power (5V safe via regulator)
GND GND Ground
SCL A5 (SCL) I2C clock
SDA A4 (SDA) I2C data
ADO Not connected / GND Address = 0x68
INT D2 (optional) Data-ready interrupt
Tip: Leave NCS floating or tied HIGH to force I2C mode. Pulling NCS LOW selects SPI.

ESP32 Wiring

The ESP32 is a 3.3V device. Power the module from the 3.3V rail for cleanest readings.

Module Pin ESP32 Pin Details
VCC 3.3V Power
GND GND Ground
SCL GPIO 22 Default I2C SCL
SDA GPIO 21 Default I2C SDA
ADO Not connected / GND Address = 0x68
INT GPIO 4 (optional) Data-ready interrupt

Raspberry Pi Wiring

Use hardware I2C. Enable it with sudo raspi-config and verify the module with i2cdetect -y 1.

Module Pin Raspberry Pi Pin Details
VCC 3.3V (Pin 1) Power
GND GND (Pin 6) Ground
SCL GPIO 3 (Pin 5) I2C1 SCL
SDA GPIO 2 (Pin 3) I2C1 SDA
ADO GND Address = 0x68
INT GPIO 17 (Pin 11, optional) Data-ready interrupt
Info: The magnetometer (AK8963) is at address 0x0C but is only accessible when the MPU9250 is configured in I2C bypass mode.

Raspberry Pi Pico Wiring

Use I2C0 on GP0 and GP1. MicroPython works with the mpu9250 driver package.

Module Pin Pico Pin Details
VCC 3.3V (Pin 36) Power
GND GND (Pin 38) Ground
SCL GP1 (Pin 2) I2C0 SCL
SDA GP0 (Pin 1) I2C0 SDA
ADO GND Address = 0x68
INT Any GP (optional) Data-ready interrupt

Code Examples

Arduino

mpu9250_read.ino
// MPU9250 - Read accel, gyro, and mag (9 axes)
// Requires: MPU9250 library by hideakitai

#include <MPU9250.h>

MPU9250 mpu;

void setup() {
  Serial.begin(115200);
  Wire.begin();
  delay(100);

  if (!mpu.setup(0x68)) {
    Serial.println("MPU9250 not found. Check wiring.");
    while (1);
  }
  Serial.println("MPU9250 ready.");
}

void loop() {
  if (mpu.update()) {
    Serial.print("Ax: "); Serial.print(mpu.getAccX());
    Serial.print(" Ay: "); Serial.print(mpu.getAccY());
    Serial.print(" Az: "); Serial.println(mpu.getAccZ());

    Serial.print("Gx: "); Serial.print(mpu.getGyroX());
    Serial.print(" Gy: "); Serial.print(mpu.getGyroY());
    Serial.print(" Gz: "); Serial.println(mpu.getGyroZ());

    Serial.print("Mx: "); Serial.print(mpu.getMagX());
    Serial.print(" My: "); Serial.print(mpu.getMagY());
    Serial.print(" Mz: "); Serial.println(mpu.getMagZ());
    Serial.println();
  }
  delay(100);
}

ESP32

mpu9250_esp32.ino
// MPU9250 on ESP32 via I2C (GPIO21 SDA, GPIO22 SCL)

#include <MPU9250.h>

MPU9250 mpu;

void setup() {
  Serial.begin(115200);
  Wire.begin(21, 22);
  delay(100);
  if (!mpu.setup(0x68)) {
    Serial.println("MPU9250 not found.");
    while (1);
  }
}

void loop() {
  if (mpu.update()) {
    Serial.printf("Roll=%.2f Pitch=%.2f Yaw=%.2f\n",
                  mpu.getRoll(), mpu.getPitch(), mpu.getYaw());
  }
  delay(20);
}

Raspberry Pi

mpu9250_read.py
# MPU9250 on Raspberry Pi via I2C
# Install: pip install mpu9250-jmdev smbus2
# Enable I2C: sudo raspi-config -> Interface Options -> I2C

import time
from mpu9250_jmdev.registers import AK8963_ADDRESS, GFS_1000, AFS_8G, AK8963_BIT_16, AK8963_MODE_C100HZ
from mpu9250_jmdev.mpu_9250 import MPU9250

mpu = MPU9250(
    address_ak=AK8963_ADDRESS,
    address_mpu_master=0x68,
    address_mpu_slave=None,
    bus=1,
    gfs=GFS_1000,
    afs=AFS_8G,
    mfs=AK8963_BIT_16,
    mode=AK8963_MODE_C100HZ)

mpu.configure()

while True:
    print("Accel:", mpu.readAccelerometerMaster())
    print("Gyro :", mpu.readGyroscopeMaster())
    print("Mag  :", mpu.readMagnetometerMaster())
    print("-" * 40)
    time.sleep(0.5)

Raspberry Pi Pico (MicroPython)

mpu9250_pico.py
# MPU9250 on Pico via I2C0 (GP0 SDA, GP1 SCL)
# Upload mpu9250.py and ak8963.py driver files to the Pico first.

from machine import I2C, Pin
from mpu9250 import MPU9250
import time

i2c = I2C(0, sda=Pin(0), scl=Pin(1), freq=400000)
print("I2C scan:", [hex(d) for d in i2c.scan()])

sensor = MPU9250(i2c)

while True:
    print("Accel:", sensor.acceleration)
    print("Gyro :", sensor.gyro)
    print("Mag  :", sensor.magnetic)
    print("-" * 30)
    time.sleep(0.5)

Frequently Asked Questions

What is the default I2C address of the MPU9250?
The accelerometer/gyroscope is at 0x68 by default, or 0x69 if the ADO pin is tied HIGH. The magnetometer (AK8963) is at 0x0C, but it's only visible when the MPU9250 is in I2C bypass mode.
Do I need to calibrate the MPU9250?
Yes — especially for the magnetometer, which is affected by nearby ferrous metals and magnetic fields. The gyro benefits from a zero-rate calibration at rest, and the accel from a 6-position gravity calibration. Most libraries include calibration helpers.
What's the difference between MPU6050 and MPU9250?
The MPU6050 is 6-axis (accel + gyro only). The MPU9250 adds a 3-axis magnetometer on the same die, giving you full 9-DOF orientation with absolute heading — essential for compass-aware projects like drones and AHRS.
How do I compute tilt-compensated heading?
Use accelerometer readings to determine pitch and roll, then rotate the magnetometer vector by those angles before computing atan2(My, Mx). Libraries like Mahony/Madgwick filters do this for you automatically.
What does the INT pin do?
INT signals data-ready or motion events without polling. Configure the chip to generate interrupts on new samples, free-fall, or motion threshold — then wake or poll your microcontroller only when there's new data, saving power.
Can I use SPI instead of I2C?
Yes — pull NCS LOW to switch to SPI. In SPI mode, use the NCS (chip select), SCL (clock), SDA (MOSI), and ADO (MISO) pins. SPI supports higher sample rates than I2C.

Related Tutorials