The standard Raspberry Pi Pico dimensions are exactly 21.0 mm × 51.0 mm × 1.6 mm (0.83" × 2.0" × 0.06"). However, when designing a space-constrained embedded project, the bare PCB footprint is only half the battle. You must account for the 1.8 mm USB Micro-B overhang, the 11.5 mm mounting hole spacing, and the castellated edge pad clearances. If you are dropping a Pico into a tight off-the-shelf enclosure like a Hammond 1593 series or designing a custom PCB shield, misjudging these fractions of a millimeter will result in a board that doesn't fit or USB cables that bend the PCB.
This guide provides the exact mechanical specifications for the Pico family, followed by a complete, space-constrained I2C environmental sensor build. We will cover the physical assembly, the RP2040 C++ code, and how to debug the most common I2C initialization errors specific to the Raspberry Pi Pico Arduino core.
The Exact Raspberry Pi Pico Dimensions (Spec Sheet)
Before cutting enclosure windows or routing PCB traces, reference this data-dense mechanical table. Note that while the Pico 2 (RP2350) shares the exact same physical footprint as the original Pico, the Pico H variants have pre-soldered headers that drastically alter the Z-axis height.
| Board Variant | PCB Footprint (X × Y) | Z-Height (w/o Headers) | USB Overhang | Mounting Hole Spacing | Castellated Edge Pads |
|---|---|---|---|---|---|
| Pico (RP2040) | 21.0 × 51.0 mm | 1.6 mm | 1.8 mm (Micro-B) | 11.4 mm (Width) | Yes (23 per side) |
| Pico W (RP2040) | 21.0 × 51.0 mm | 2.4 mm (Infineon shield) | 1.8 mm (Micro-B) | 11.4 mm (Width) | Yes (23 per side) |
| Pico H (Pre-soldered) | 21.0 × 51.0 mm | 8.5 mm (w/ male headers) | 1.8 mm (Micro-B) | 11.4 mm (Width) | N/A (Headers block edge) |
| Pico 2 (RP2350) | 21.0 × 51.0 mm | 1.6 mm | 1.8 mm (Micro-B) | 11.4 mm (Width) | Yes (23 per side) |
When designing an enclosure cutout for the USB port, your total required Y-axis clearance is 52.8 mm (51.0 mm PCB + 1.8 mm USB overhang). Always add at least 1.0 mm of tolerance for the USB cable's strain relief boot.
Space-Constrained Build: Parts & Pin Mapping
For this build, we are creating a low-profile environmental logging node that fits inside a Hammond 1593V series enclosure. We will use the castellated edges to solder the Pico W directly to a custom carrier board, eliminating the 8.5 mm Z-height penalty of standard male header pins.
Parts List
- Microcontroller: Raspberry Pi Pico W (RP2040, Infineon CYW43439 WiFi)
- Sensor: Adafruit BME280 I2C/SPI Temperature, Humidity, and Pressure Sensor (Product ID: 2652)
- Enclosure: Hammond Manufacturing 1593VBK (ABS, 60 x 37 x 20 mm)
- Power: 3.7V 500mAh LiPo battery with JST-PH 2.0 connector
- Passives: 2x 4.7kΩ 0805 SMD pull-up resistors (for I2C lines)
Pin Mapping Table
The RP2040 features highly flexible GPIO pin muxing, meaning I2C0 and I2C1 can be mapped to almost any pin. For this layout, we use I2C1 on the lower right quadrant to keep traces short.
| Pico W Pin (Physical) | GPIO Number | Function | BME280 Sensor Pin |
|---|---|---|---|
| Pin 6 | GPIO 4 | I2C1 SDA | SDI / SD0 |
| Pin 7 | GPIO 5 | I2C1 SCL | SCK / SCL |
| Pin 8 | GND | Ground | GND |
| Pin 36 | 3V3(OUT) | 3.3V Power | VIN / VCC |
Assembly & Enclosure Fitment Steps
- Prep the Castellated Edges: If soldering the Pico W directly to your carrier PCB, apply a thin layer of tacky flux (e.g., Amtech NC-559-V2-TF) to the castellated half-holes. Do not use standard liquid flux; it will wick under the RF shield.
- Solder the SMD Pull-ups: Solder the 4.7kΩ resistors between the 3V3 trace and the SDA/SCL traces on your carrier board. While the BME280 breakout has internal pull-ups, they are often 10kΩ, which can cause I2C bus capacitance issues at higher clock speeds. External 4.7kΩ resistors guarantee a clean rise time.
- Reflow the Pico W: Use a hot air station set to 350°C with medium airflow. Heat the castellated pads evenly until the solder wets the board. Warning: Keep the hot air nozzle moving to avoid melting the Pico's plastic USB connector housing or damaging the Infineon WiFi module shield.
- Verify USB Clearance: Before securing the board into the Hammond 1593VBK enclosure, insert a low-profile USB Micro-B cable. Ensure the enclosure's side wall cutout is at least 8 mm wide and 4 mm tall to accommodate the cable's molded boot without prying against the PCB.
- Secure the LiPo: Use a 10 mm square of double-sided VHB tape to mount the LiPo cell to the underside of the carrier board. Ensure the battery does not press against the BME280's humidity vent hole, which will skew readings.
Compilable Code: BME280 I2C Sensor Node
#include <Wire.h>
#include <Adafruit_BME280.h>
// Pin definitions for RP2040 I2C1 bus
#define I2C_SDA_PIN 4
#define I2C_SCL_PIN 5
#define SEALEVELPRESSURE_HPA (1013.25)
Adafruit_BME280 bme;
void setup() {
Serial.begin(115200);
// Wait up to 5 seconds for serial monitor to connect
unsigned long startMillis = millis();
while (!Serial && (millis() - startMillis < 5000)) {
delay(10);
}
Serial.println("Initializing BME280 Sensor Node...");
// CRITICAL: RP2040 Arduino core requires setSDA/setSCL BEFORE Wire.begin()
Wire.setSDA(I2C_SDA_PIN);
Wire.setSCL(I2C_SCL_PIN);
Wire.setClock(400000); // Set I2C to 400kHz Fast Mode
Wire.begin();
// Initialize BME280 on I2C address 0x76 (Adafruit breakout default)
if (!bme.begin(0x76)) {
Serial.println("ERROR: BME280 init failed, check wiring or I2C address!");
Serial.println("Halting execution to prevent bus lockup.");
while (1) {
delay(1000);
}
}
Serial.println("BME280 initialized successfully.");
}
void loop() {
float temperature = bme.readTemperature();
float humidity = bme.readHumidity();
float pressure = bme.readPressure() / 100.0F;
float altitude = bme.readAltitude(SEALEVELPRESSURE_HPA);
Serial.printf("Temp: %.2f C | Hum: %.2f %% | Press: %.2f hPa | Alt: %.2f m\n",
temperature, humidity, pressure, altitude);
delay(2000); // 2-second polling interval
}
Debugging: TwoWire::begin Compilation Errors
When migrating from ESP32 or standard AVR Arduino boards to the RP2040, developers frequently hit a specific compiler error regarding I2C initialization. If you attempt to pass pin numbers directly into the Wire.begin() function, the Earle Philhower core will throw the following exact error string:
error: no matching function for call to 'TwoWire::begin(int, int)'
Ranked Causes & Fixes
- Cause: Using ESP32-style I2C syntax. The ESP32 Arduino core allows
Wire.begin(SDA_PIN, SCL_PIN). The RP2040 core does not. The RP2040 uses a pin multiplexer that must be configured before the I2C peripheral is started.
Fix: UseWire.setSDA(pin)andWire.setSCL(pin)on separate lines, followed by a parameter-lessWire.begin(), exactly as shown in the code block above. - Cause: Outdated Arduino-Pico Core. Versions prior to 2.0.0 had inconsistent implementations of the Wire class.
Fix: Open the Boards Manager, search for 'Raspberry Pi Pico/RP2040', and update to the latest stable release (v3.x+). - Cause: Missing Wire.h Include. Rarely, if you are using a custom library that abstracts I2C but forgets to include the base Wire library, the compiler fails to resolve the TwoWire class.
Fix: Ensure#include <Wire.h>is at the very top of your sketch.
The First Three Things to Check When I2C Fails at Runtime
If the code compiles but the serial monitor prints ERROR: BME280 init failed, check these three hardware realities:
- I2C Address Mismatch: The Adafruit BME280 defaults to
0x77if the SDO pin is tied to VIN, but0x76if tied to GND. Run an I2C scanner sketch to verify the actual address on your specific breakout board, and update thebme.begin(0xXX)argument accordingly. - Missing Pull-up Resistors: Measure the voltage on the SDA and SCL lines with a multimeter. If they are not sitting at ~3.2V to 3.3V when idle, your pull-up resistors are missing, broken, or the wrong value. The I2C bus will hang in a 'low' state.
- Pin Remapping Conflict: Ensure GPIO 4 and GPIO 5 are not being used by another library (like an SPI display or SD card) in your sketch. The RP2040 cannot route I2C1 to GPIO 4/5 if those pins are already claimed by the SPI0 peripheral.
Extending and Simplifying the Build
How to Extend the Build
- Add MQTT Telemetry: Since we are using the Pico W, you can add the
PubSubClientlibrary to push temperature and humidity data to a Home Assistant Mosquitto broker. Use the RP2040's light sleep modes between 2-second polling intervals to reduce the LiPo current draw from ~65mA to ~12mA. - External Antenna: If mounting the node inside a metal enclosure or a location with heavy RF interference, cut the trace to the PCB antenna and solder a u.FL to SMA pigtail to utilize the Pico W's secondary antenna pads.
How to Simplify the Build
- Drop the WiFi: If this is a local data logger that writes to an onboard SPI flash chip or an SD card, swap the Pico W for the standard Pico 2 (RP2350). You save roughly $2 per unit, eliminate the Infineon module's quiescent current draw, and gain the RP2350's enhanced security and dual-core Cortex-M33 processing power.
- Use Pre-Soldered Headers: If enclosure Z-height is not a constraint, abandon the castellated edge soldering. Buy the Pico H variant, which comes with male headers pre-installed. You can then use standard 2.54mm female Dupont wires to connect the BME280, cutting assembly time from 20 minutes to 2 minutes.
Understanding the exact Raspberry Pi Pico dimensions and the quirks of the RP2040 Arduino core is the difference between a project that works on the bench and one that survives in the field. Always verify your mechanical clearances for the USB overhang, respect the I2C pin muxing rules, and your embedded builds will fit perfectly every time.






