The Raspberry Pi Pico schematic is a three-page PDF that separates casual breadboarders from serious embedded designers. While page one covers the RP2040 microcontroller and page three details the flash memory, page two is the goldmine: it maps the RT6152 buck-boost converter, the USB power path, and the exact I/O routing. If you are designing a custom carrier board or debugging a flaky I2C sensor, understanding this schematic is non-negotiable.
This guide breaks down the critical power nets, walks through a custom I2C carrier build for the Raspberry Pi Pico W, and provides bare-metal MicroPython code to verify your wiring before you wire up complex sensor libraries.
Reading the Pi Pico Schematic: VSYS, VBUS, and 3V3(OUT)
The most common mistake when designing a custom PCB for the Pico is misunderstanding the power nets. The official Pi Pico datasheet clearly defines three distinct power domains on page two of the schematic. Confusing them will either brick your board or cause brownouts under load.
| Net Name | Voltage Range | Source / Function | Max Current Draw |
|---|---|---|---|
| VBUS | 5.0V nominal | Raw 5V from the micro-USB connector. Bypassed by a 100nF cap. | Depends on USB host (typically 500mA) |
| VSYS | 1.8V to 5.5V | Main system input. Feeds the RT6152 buck-boost. If powered via USB, VBUS feeds VSYS through an internal diode (MBR120). | ~300mA (limited by RT6152 and USB) |
| 3V3(OUT) | 3.3V regulated | Output of the RT6152. This is the clean logic supply for the RP2040 and your peripherals. | ~250mA (derate at high VSYS) |
3V3(OUT). The schematic shows this net goes directly to the RP2040 core and I/O banks. Injecting 5V here will instantly destroy the silicon. If you have a 5V sensor, power it from VBUS and use a level shifter for the data lines.
Project Build: Custom I2C Carrier Board for the Pico W
We will build a custom I2C carrier that interfaces the Pico W with a Bosch BME280 environmental sensor. This build highlights a critical schematic detail: the RP2040 internal I2C pull-ups are approximately 50kΩ. The RP2040 Hardware Design Guide explicitly states that 50kΩ is too weak for 400kHz Fast-mode I2C. We must add external 4.7kΩ pull-ups to 3V3(OUT).
Parts List
- MCU: Raspberry Pi Pico W (RP2040 + CYW43439) with pre-soldered headers
- Sensor: BME280 Breakout (3.3V logic variant, e.g., Adafruit 2652)
- Resistors: 2x 4.7kΩ 0805 SMD resistors (for I2C pull-ups)
- Capacitor: 1x 100nF 0805 SMD ceramic capacitor (local decoupling)
- Substrate: Custom 2-layer FR4 PCB or 2x3 inch perfboard
Pin Mapping Table
| Pico W Pin | RP2040 Function | BME280 Pin | Notes |
|---|---|---|---|
| Pin 4 (GP4) | I2C0 SDA | SDI | Requires 4.7kΩ pull-up to 3V3 |
| Pin 5 (GP5) | I2C0 SCL | SCK | Requires 4.7kΩ pull-up to 3V3 |
| Pin 36 (3V3 OUT) | Regulated 3.3V | VIN / 3V3 | Add 100nF cap close to sensor |
| Pin 38 (GND) | Ground | GND | Keep return path short |
Assembly Steps
- Route Power: Connect Pico Pin 36 to the BME280 VIN. Place the 100nF decoupling capacitor as physically close to the BME280 VCC/GND pins as possible to suppress high-frequency switching noise.
- Install Pull-ups: Solder the 4.7kΩ resistors between GP4 and 3V3(OUT), and GP5 and 3V3(OUT). If your breakout board already has 4.7kΩ pull-ups (check the board schematic), you can skip this step to avoid dropping the equivalent resistance to 2.35kΩ, which overloads the RP2040 I/O drive strength.
- Wire Data Lines: Connect GP4 to SDI and GP5 to SCK. Keep these traces parallel and under 10cm in length to minimize parasitic capacitance.
- Verify Continuity: Before applying power, use a multimeter in continuity mode. Check for shorts between 3V3(OUT) and GND. Read the resistance between SDA and 3V3; it should read exactly 4.7kΩ.
Firmware: BME280 I2C Reader with Error Handling
Before importing heavy third-party sensor libraries, verify the physical layer. The following MicroPython code targets the Raspberry Pi Pico W and performs a raw I2C read of the BME280 WHO_AM_I register (0xD0). A successful read returns 0x60. This bare-metal approach guarantees the code compiles and runs without needing external mip packages.
from machine import Pin, I2C
import time
# --- Pin Definitions for Raspberry Pi Pico W ---
SDA_PIN = 4 # Physical Pin 6
SCL_PIN = 5 # Physical Pin 7
I2C_FREQ = 400_000 # 400kHz Fast Mode
# Initialize I2C0 bus
i2c = I2C(0, sda=Pin(SDA_PIN), scl=Pin(SCL_PIN), freq=I2C_FREQ)
# BME280 I2C address (0x76 if SDO is tied to GND, 0x77 if tied to VCC)
BME280_ADDR = 0x76
WHO_AM_I_REG = 0xD0
EXPECTED_ID = 0x60
def scan_and_verify():
print("Scanning I2C bus...")
devices = i2c.scan()
if not devices:
print("FATAL: No devices found on I2C bus. Check wiring and pull-ups.")
return False
print(f"Found devices at: {[hex(d) for d in devices]}")
if BME280_ADDR not in devices:
print(f"ERROR: BME280 not found at {hex(BME280_ADDR)}. Try 0x77 if SDO is high.")
return False
try:
# Read 1 byte from the WHO_AM_I register
chip_id = i2c.readfrom_mem(BME280_ADDR, WHO_AM_I_REG, 1)
if chip_id[0] == EXPECTED_ID:
print(f"SUCCESS: BME280 verified. Chip ID: {hex(chip_id[0])}")
return True
else:
print(f"WARNING: Unexpected Chip ID: {hex(chip_id[0])}. Sensor may be counterfeit or misconfigured.")
return False
except OSError as e:
# Catch specific I2C hardware faults
print(f"I2C Transaction Failed: {e}")
return False
if __name__ == "__main__":
if scan_and_verify():
print("Hardware layer verified. Safe to load full BME280 driver.")
else:
print("Halt. Debug physical connections before proceeding.")
Debugging: First Three Things to Check When I2C Fails
When the code above fails, MicroPython will throw specific exceptions. Do not blindly rewrite your code; the error string tells you exactly where the physics are failing.
1. The "Remote I/O Error" (Missing Pull-ups or Wrong Address)
Exact Error String: OSError: [Errno 121] Remote I/O error or OSError: [Errno 19] ENODEV
Root Cause: The RP2040 sent the address byte, but the SDA line never got pulled low by the sensor for the ACK bit. This almost always means your external 4.7kΩ pull-up resistors are missing, or you are polling 0x76 when the breakout board has 0x77 hardcoded.
Fix: Measure the voltage on SDA and SCL with a multimeter. Both should read ~3.28V when idle. If they read 0V or float around 1.5V, your pull-ups are disconnected.
2. The "Timeout Error" (Capacitance Overload)
Exact Error String: OSError: [Errno 110] ETIMEDOUT
Root Cause: The SCL clock edge is taking too long to rise. This happens when the parasitic capacitance on the I2C bus exceeds 400pF, usually because your wires are too long (>30cm) or you have daisy-chained too many modules.
Fix: Drop the I2C_FREQ in the code from 400_000 to 100_000 (Standard Mode). This gives the RC circuit more time to charge.
3. The "Bus Lockup" (SDA Stuck Low)
Exact Error String: RuntimeError: I2C bus is locked / SDA stuck low (often seen in C++ SDK or custom MicroPython builds).
Root Cause: The Pico was reset mid-transaction while the sensor was pulling SDA low to send a '0' bit. The sensor is now waiting for clock pulses that will never come.
Fix: Toggle the SCL pin manually as a GPIO output 9 times to force the sensor to release the bus, then re-initialize the I2C peripheral.
Pi Pico Schematic FAQ
Where can I download the official Pi Pico schematic PDF?
Raspberry Pi hosts all hardware documentation on their datasheets portal. You can download the Pico Datasheet which includes the schematic on pages 2 and 3. For the W variant (which adds the CYW43439 WiFi/BT chip), refer to the Pico W Datasheet, as the power routing remains identical but the GPIO allocation for the wireless chip differs.
Does the Pi Pico schematic include internal pull-up resistors for I2C?
Yes, the RP2040 silicon features internal pull-ups, but the schematic and hardware design guide note they are nominally 50kΩ to 60kΩ. These are intended for GPIO state retention, not I2C bus termination. At 400kHz, a 50kΩ resistor cannot pull the line high fast enough to meet the I2C specification rise-time requirements. You must add external 2.2kΩ to 4.7kΩ resistors to 3V3(OUT) for reliable communication.
How do I extend this design to add a LiPo battery charging circuit?
To add battery power, do not wire the LiPo directly to 3V3(OUT). Instead, route the LiPo through a dedicated charge controller and boost converter (like the MCP73831 for charging and a TPS61230 for boosting to 5V). Feed the boosted 5V into the VSYS pin. The Pico's onboard RT6152 will handle the buck-boost down to 3.3V. To simplify the build for a one-off prototype, use an Adafruit PowerBoost 1000C module and wire its 5V output directly to the Pico's VSYS pin.






