Learn

Reading Acceleration, Rotation & Temperature from an MPU6050 (GY-521) on a Raspberry Pi 4B

Wire a GY-521 MPU6050 breakout to a Raspberry Pi 4B over I2C and read live 3-axis acceleration, 3-axis rotation, and temperature in Python — including how AD0 lets two sensors share one bus.

Note: the MPU6050 Accelerometer/Gyroscope is a VIP-tier component in the simulator — you’ll need a VIP plan to use it there.

Try this directly in the free Raspberry Pi 4B simulator — no hardware or signup required. New to the GPIO header? Start with the interactive pinout guide.

What you’ll need

  • Raspberry Pi 4B
  • MPU6050 Accelerometer/Gyroscope (GY-521 breakout)

Step by step

  1. Drag Raspberry Pi 4B onto the Canvas.
  2. Drag the MPU6050 Accelerometer/Gyroscope onto the Canvas — a real 8-pin breakout, plugs directly into a breadboard.
  3. Hover over its pins to confirm the labels, left to right: VCC, GND, SCL, SDA, XDA, XCL, AD0, INT.
  4. Wire it up: VCC → Pi's 3.3V pin. GND → Pi's GND pin. SCL → Pi's SCL pin. SDA → Pi's SDA pin. Only these four are required for basic accelerometer/gyroscope/temperature reads.

XDA and XCL are the chip's own auxiliary I2C bus, used on real hardware to daisy-chain a second sensor (like an external magnetometer) behind the MPU6050 — they're present and wireable here, but don't carry any behavior in this simulator. AD0 and INT are optional too: leave AD0 unwired (or wire it to GND) to use the default address 0x68; wire it to a 3.3V pin instead to use 0x69 — useful the moment you place a second MPU6050 on the same bus.

  1. Go to the Code tab and write a script using the real, widely-used mpu6050 Python library:
import asyncio
from mpu6050 import mpu6050
 
sensor = mpu6050(x68) # use 0x69 instead if you wired AD0 HIGH
 
while True:
accel = sensor.get_accel_data(g=True) # in g's
gyro = sensor.get_gyro_data() # in degrees/second
temp = sensor.get_temp() # in Celsius
 
print(f"Accel: x={accel['x']:.2f}g y={accel['y']:.2f}g z={accel['z']:.2f}g")
print(f"Gyro: x={gyro['x']:.1f}dps y={gyro['y']:.1f}dps z={gyro['z']:.1f}dps")
print(f"Temp: {temp:.1f}C")
 
await asyncio.sleep(1)
  1. Click the MPU6050's own icon-pill to select it, then adjust its settings panel's 7 fields (Accel X/Y/Z in g, Gyro X/Y/Z in °/s, Temperature in °C) to whatever values you want the sensor to report — a stationary, level sensor defaults to accelZ=1 (gravity) and everything else at 0.
  2. Click Start.

What “working correctly” looks like

  • The Console keeps printing Accel/Gyro/Temp lines once a second, matching whatever values you set in the component's own settings panel.
  • Editing a settings-panel value while the simulation is running is blocked (stop first) — after stopping, changing a value and restarting shows the new number on the very next read.
  • Wiring a second MPU6050 with its AD0 wired the opposite way from the first (one floating/LOW, one wired HIGH) lets both report independently at their own real addresses, 0x68 and 0x69.

If something’s wrong

  • Nothing prints, or an import error → confirm VCC and GND are both wired — an unpowered sensor never provides real register data.
  • Two placed MPU6050 sensors both go quiet, or only one ever seems to update → check the Console for a warning naming a shared I2C address — this means both sensors' AD0 pins resolved to the same address (both floating/LOW, or both wired HIGH). Wire one sensor's AD0 to a 3.3V pin to move it to address 0x69.
  • The readings never change over time even though you're printing in a loop → this is expected — a sensor's values are fixed at whatever you set in its own settings panel, not computed from any simulated physical motion. Adjust the panel's own fields (while stopped) and restart to see a different reading.