PyRaspBeta

MPU-6050 motion sensor

The MPU-6050 (on the ubiquitous GY-521 breakout) packs a three-axis accelerometer and a three-axis gyroscope into one chip for $6. It talks I²C at 0x68 — 0x69 when AD0 is high — reports tilt through gravity and rotation through angular rate, and also has a temperature sensor on board. There is no humidity or magnetometer here; XDA/XCL exist so an external magnetometer can be chained to it, and INT can signal events to a GPIO.

MPU-6050 motion sensor

Pins

PinWhat it isType
VCCSupply 3.3–5 V (on-board regulator)power
GNDGroundground
SCLI²C clockio
SDAI²C dataio
XDAAuxiliary I²C data (for a magnetometer)io
XCLAuxiliary I²C clockio
AD0Address select: low 0x68, high 0x69io
INTInterrupt outputio

In circuit.py:

For most builds you need only VCC, GND, SDA, SCL and a decision about AD0. XDA, XCL and INT can be left unconnected.

Wiring it in circuit.py

circuit.py
from wiring import *

pi = Pi()

imu = MPU6050()

pi.V3_3 >> imu.vcc
imu.gnd >> pi.GND
pi.SDA >> imu.sda
pi.SCL >> imu.scl
imu.ad0 >> pi.GND                       # address 0x68

The breakout has its own 3.3 V regulator, so it tolerates 5 V, but powering it from 3V3 keeps its I²C levels at 3.3 V too. The on-board I²C pull-ups are present on GY-521 boards. Grounding AD0 picks 0x68; wiring it to V3_3 moves the chip to 0x69.

Driving it in main.py

The simulator does not ship an Adafruit driver for the MPU-6050, but smbus2 is available and the registers are simple. Wake the chip first — out of reset it sleeps and every value reads zero:

main.py
from smbus2 import SMBus
from time import sleep

bus = SMBus(1)
bus.write_byte_data(0x68, 0x6B, 0)      # PWR_MGMT_1 = 0: leave sleep mode

def word(register):                      # 16-bit registers are big-endian
    raw = bus.read_i2c_block_data(0x68, register, 2)
    return ((raw[0] << 8) | raw[1]) - (65536 if raw[0] & 0x80 else 0)

while True:
    ax, ay, az = (word(0x3B + axis * 2) / 16384 for axis in range(3))  # ±2 g
    print(f"accel {ax:+.2f} {ay:+.2f} {az:+.2f} g")
    sleep(0.5)

The acceleration registers start at 0x3B (X, Y, Z), temperature at 0x41 and gyro at 0x43. At the default ±2 g range, 16384 counts is one g; each axis is signed two's-complement, hence the word() helper. Real units are never perfectly still: average a few hundred samples while stationary and subtract them to calibrate.

Electrical notes

  • Supply is 3–5.5 V (the GY-521 has a 3.3 V regulator and level shifting); the chip itself draws about 3.9 mA.
  • AD0 low gives address 0x68, high gives 0x69. INT is a push-pull/active-high interrupt, configurable through the register map.
  • Sensitivity: accelerometer ±2/±4/±8/±16 g (16384/8192/4096/2048 LSB per g); gyroscope ±250/±500/±1000/±2000 °/s (131/65.5/32.8/16.4 LSB per °/s). Temperature is raw / 340 + 36.53 °C.
  • Typical zero offsets: about 0.05 g on the accelerometer and 2 °/s on the gyroscope, plus noise. The datasheet's registers let you trim them, or calibrate in software.
  • It resets asleep (PWR_MGMT_1 bit 6 set). Writing 0 to 0x6B wakes it; writing 0x80 resets it.

Simulator vs real hardware

  • Orientation comes from datafeed fields: pitchDeg and rollDeg set the gravity vector the accelerometer sees; yawRateDps and the rate of change of pitch and roll feed the gyroscope. In the Lab you can drive them by hand, with a wave, or with this computer's tilt.
  • vibrationG adds shake to every axis with Gaussian noise, and each unit draws fixed zero offsets unless the feed's offsets knob is set to none — which is handy when checking calibration code.
  • Registers are sampled at the instant you read them; while the chip sleeps they hold all zeros, matching the wake-first requirement above.
  • There is no FIFO, DMP, interrupt routing or magnetometer emulation: INT, XDA and XCL are wired but inert. No self-test, no temperature drift beyond the modelled noise.

Going deeper

Further reading