Raspberry Pi Pico MPU6050 Simulator: Wiring, Code and a Live Circuit
This is an MPU6050 accelerometer and gyroscope on a GY-521 board, wired to a Raspberry Pi Pico over I2C and read live: the sketch wakes the chip and prints the three acceleration axes four times a second. In the editor, drag the pitch and roll sliders and watch gravity move between them.
Four wires: 3V3(OUT), GND, SDA to GP4 (physical pin 6) and SCL to GP5 (physical pin 7). The sketch talks to the registers with Wire, so nothing is hidden behind a library.
- 3.3 V logic
- Library: Wire.h only
- I2C address 0x68
- SDA 4, SCL 5
Wiring the MPU6050 to the Raspberry Pi Pico
Every connection in the circuit above, with the board’s own pin names.
| MPU6050 pin | Raspberry Pi Pico pin | Why |
|---|---|---|
| VCC | 3V3(OUT) | The GY-521 board has a 3.3 V regulator, so it takes 3.3 or 5 V. |
| GND | GND | Common ground. |
| SCL | GP5 (physical pin 7) | I2C clock. |
| SDA | GP4 (physical pin 6) | I2C data. |
| AD0 | not connected | Low (the board’s own pull-down): address 0x68. Tie it high for 0x69. |
On the Pico, Wire.begin() puts SDA on GP4 and SCL on GP5, physical pins 6 and 7. Powered from 3V3, the GY-521’s pull-ups hold SDA and SCL at 3.3 V, the Raspberry Pi Pico’s own level. Its regulator still works from 3.3 V, with a little less headroom.
Pins to leave alone on the Raspberry Pi Pico
The numbers in the code are GP numbers, not the physical pin numbers printed beside the header: GP15 is pin 20. GP23 to GP25 are used on the board itself, and GP25 is the LED.
On a real bench
Solder headers on the Pico and press it into the breadboard across the center channel; the MPU6050 goes in beside it. GND pins sit every fifth pin down both sides (pins 3, 8, 13, 18 and so on), so there is always one close. The first upload needs BOOTSEL held while plugging in.
The code
The sketch the circuit above runs. Open it in the editor, change a line and press Run: it compiles in your browser.
#include <Wire.h>
const int MPU = 0x68; // AD0 low
int16_t read16() {
int16_t high = Wire.read();
return (high << 8) | Wire.read();
}
void setup() {
Serial.begin(115200);
Wire.begin(); // SDA GP4 (physical pin 6), SCL GP5 (physical pin 7)
Wire.beginTransmission(MPU);
Wire.write(0x6B); // PWR_MGMT_1
Wire.write(0); // wake up: it starts asleep
Wire.endTransmission();
Serial.println("MPU6050 awake");
}
void loop() {
Wire.beginTransmission(MPU);
Wire.write(0x3B); // ACCEL_XOUT_H, then Y, Z, temperature, gyro
Wire.endTransmission(false);
Wire.requestFrom(MPU, 6);
int16_t ax = read16();
int16_t ay = read16();
int16_t az = read16();
// At the default range, 16384 counts is 1 g.
Serial.print("Accel x: ");
Serial.print(ax);
Serial.print(" y: ");
Serial.print(ay);
Serial.print(" z: ");
Serial.println(az);
delay(250);
}
The MPU6050 powers up asleep, and every reading is zero until register 0x6B is written with 0. That one write in setup() is the step most broken sketches are missing.
Reading starts at register 0x3B and the chip sends the bytes that follow in order: X, Y and Z acceleration, two bytes each, high byte first. endTransmission(false) keeps the bus between the address write and the read, so the three axes come from the same sample.
Lying flat and still, the board reads 0, 0 and 16384: one g straight down on Z. Tilt it with the pitch and roll sliders and the gravity moves between the axes. This sketch uses Wire directly; Adafruit_MPU6050.h and MPU6050.h also compile here, but the raw registers are what those libraries do underneath. Serial.begin(115200) opens the serial monitor. Serial is the USB port at 115200 baud in this sketch; on a real Pico it appears once the board has enumerated.
Common mistakes with the MPU6050 on the Raspberry Pi Pico
Not waking it up
Out of reset the chip is asleep and returns zeros on every axis. Write 0 to register 0x6B first. It is the single most common MPU6050 fault.
Reading the axes in separate transactions
Read X, then start a new transaction for Y, and the chip may have taken a new sample in between, so the axes disagree. Read all six bytes from 0x3B in one requestFrom().
Expecting an angle from the gyro
The gyroscope measures how fast the board turns, in degrees per second, not which way it points. For tilt, use the arctangent of two acceleration axes; for a steady angle while moving, combine both with a complementary filter.
Questions and answers
Can I simulate an MPU6050 with a Raspberry Pi Pico?
Yes. The circuit at the top of this page is a Raspberry Pi Pico with a MPU6050, running in your browser on a simulated RP2040. The pitch and roll sliders tilt the simulated chip, so the acceleration on each axis is what gravity would give at that angle. Press Run it in the editor to change the wiring or the code; it is free and needs no account.
Which pins does the MPU6050 use on the Raspberry Pi Pico?
On the Pico, Wire.begin() puts SDA on GP4 and SCL on GP5, physical pins 6 and 7.
Why are all my readings zero?
The chip is still asleep: write 0 to register 0x6B. If the readings are -1 instead, nothing answered at 0x68, so check the wiring and the AD0 pin.
Can I use the Adafruit MPU6050 library?
Adafruit_MPU6050.h compiles here. This page reads the registers with Wire so the sketch shows what the chip actually does, and so it runs the same on every board.
Build your own MPU6050 project
Open this circuit in the editor, change the wiring or the code, and keep your version in a free account.