denied.systems

field guide

MPU-6050: MEMS IMU

The MPU-6050 MEMS IMU: a 3-axis accelerometer and gyroscope on one die, the six raw measurements a complementary or Kalman filter fuses into attitude.

updated 2026-06-14 sensing imu i2c

Sensor architecture

Two sensors on one die:

Together, six raw measurements that feed into a complementary or Kalman filter to recover attitude (roll, pitch, yaw).

MEMS working principle

Microelectromechanical structures etched into silicon — no spinning mass, no lasers. Just silicon springs, comb fingers, and capacitance.

Accelerometer: a tiny proof mass suspended on silicon springs. Acceleration deflects the mass relative to fixed electrodes. The deflection changes the capacitance between interleaved comb fingers. Change in capacitance \propto acceleration. Measured continuously by on-chip analog front-end.

Gyroscope: a proof mass driven to vibrate at its resonant frequency (roughly 4–8 kHz for typical MEMS) by electrostatic forcing. When the chip rotates, the vibrating mass experiences a Coriolis force perpendicular to both its vibration direction and the rotation axis: 𝐅c=2m(𝛀×𝐯) \mathbf{F}_c = -2m\,(\boldsymbol\Omega \times \mathbf{v}) This Coriolis force deflects the mass in a second axis, changing capacitance in a perpendicular sense-comb. The in-phase vibration drive frequency is known, so synchronous demodulation extracts the tiny rotation signal from noise. This is the same physics as the Coriolis flow meter or the Foucault pendulum — scaled to microns.

The vibrating mass never stops moving while powered on. That’s the oscillator you hear as a faint whine from the chip (typically above human hearing).

ADC chain

The analog capacitance measurements are converted to 16-bit signed integers by the on-chip ADC. Those integers are what you read over I2C from the data registers.

Accelerometer full-scale ranges (configurable): ±2g, ±4g, ±8g, ±16g. Gyroscope full-scale ranges: ±250, ±500, ±1000, ±2000 °/s. At ±2g accel range: 16384LSB/g16384\,\text{LSB/g}. At ±250 °/s gyro range: 131LSB/(°/s)131\,\text{LSB}/(\text{°/s}).

Default on power-up: ±2g accel, ±250 °/s gyro.

Register map

Flat 128-byte address space. Some registers are configuration (write to set up the sensor), some are data (read for measurements).

Address Name Purpose
0x68 – 0x6F factory calibration, leave alone
0x75 WHO_AM_I read-only, always 0x68. Exists purely for identification — confirm you’re talking to the right chip.
0x6B PWR_MGMT_1 power state, clock source. High bit = SLEEP.
0x3B – 0x3C ACCEL_XOUT_H/L accelerometer X, high byte then low byte
0x3D – 0x3E ACCEL_YOUT_H/L accelerometer Y
0x3F – 0x40 ACCEL_ZOUT_H/L accelerometer Z
0x41 – 0x42 TEMP_OUT_H/L temperature sensor (not precision — good for relative tracking)
0x43 – 0x44 GYRO_XOUT_H/L gyroscope X
0x45 – 0x46 GYRO_YOUT_H/L gyroscope Y
0x47 – 0x48 GYRO_ZOUT_H/L gyroscope Z

The 14 bytes at 0x3B–0x48 are the live sensor dump. Read them all in one I2C burst (7 registers × 2 bytes) to get a consistent snapshot — reading one register at a time risks mixing samples from different measurement cycles. See i2c-protocol for how multi-byte reads work.

Sleep mode

The chip boots in sleep mode to save power. The oscillator is off, no measurements are happening, data registers contain stale zeros. Before any sensor read, write 0x00 to PWR_MGMT_1 (0x6B) to clear the SLEEP bit and start the internal clock.

The PWR_MGMT_1 register also selects the clock source: - 0x00 (default after waking): internal 8 MHz oscillator. Works fine for bringup. Drifts with temperature. - 0x01: gyroscope X-axis PLL. Better temperature stability because the gyro’s resonant drive is inherently stable. Worth switching to after bringup.

For initial bringup, 0x00 is sufficient.