KevsRobots Learning Platform
28% Percent Complete
By Kevin McAleer, 8 Minutes
Now that you understand what I2C is, letβs connect a real BME280 sensor to your Raspberry Pi Pico. This lesson covers everything you need to know about physical connections, power requirements, and the mysterious pull-up resistors.
The BME280 is a fantastic sensor that measures:
It communicates via I2C (or SPI), costs just a few dollars, and is perfect for weather stations, environmental monitoring, and learning I2C fundamentals.
Note: BME280 modules come on small breakout boards that handle the complicated stuff (voltage regulation, filtering) so you can focus on learning.
Most BME280 breakout boards have 4 pins:
| Pin | Name | Description |
|---|---|---|
| VCC | Power | 3.3V from Pico |
| GND | Ground | Common ground |
| SCL | Serial Clock | Connect to Pico GP9 |
| SDA | Serial Data | Connect to Pico GP8 |
Important: Some BME280 boards can handle 5V power, but the Pico outputs 3.3V. Always use 3.3V to be safe.
Hereβs something crucial about I2C: the SDA and SCL lines need pull-up resistors. Let me explain why.
I2C uses βopen-drainβ outputs. This means:
Without pull-up resistors, the lines would float randomly when released. The resistors pull them HIGH so devices only need to pull them LOW. Think of it like gravity - the resistor naturally lifts the line up, and devices pull it down when needed.
Most BME280 breakout boards already have pull-up resistors built in! Look at your board carefully:
If your board has these, you donβt need to add external resistors. If it doesnβt, youβll need to add 4.7kΞ© or 10kΞ© resistors between SDA/SCL and 3.3V.
# You don't need to do anything in code for pull-ups
# They're purely hardware components
# Just know they must be present somewhere in the circuit
Hereβs the complete wiring guide:
Raspberry Pi Pico Pinout (relevant pins):
βββββββββββββββββββββββββββ
β USB PORT β
βββββββββββββββββββββββββββ€
β 1 GP0 VBUSβ 40
β 2 GP1 VSYSβ 39
β 3 GND GNDβ 38
β 4 GP2 3V3_EN β 37
β 5 GP3 3.3Vβ 36 β Connect VCC here
β 6 GP4 REFβ 35
β 7 GP5 GP28β 34
β 8 GND GNDβ 33 β Connect GND here
β 9 GP6 GNDβ 32
β10 GP7 GP27β 31
β11 GP8 (SDA) GP26β 30 β Connect SDA here
β12 GP9 (SCL) RUN β 29 β Connect SCL here
βββββββββββββββββββββββββββ
If youβre using jumper wires, consider this color scheme:
This makes troubleshooting easier and keeps your projects organized.
For prototyping, breadboards are perfect:
Breadboard Layout:
ββββββββββββββββββββββββββββββ
β + + + + + + + + + + + + + β β Power rail (connect to 3.3V)
β - - - - - - - - - - - - - β β Ground rail (connect to GND)
β β
β [BME280 Module] β
β VCC GND SCL SDA β
β β β β β β
β βββββΌββββΌββββΌβββββββ β
β βββββΌββββΌβββ β β
β βββββΌβ β β β
β ββ β β β
ββββββββββββββββββΌβΌββΌββββΌβββββ
ββ β β
To Pico Pins
The Raspberry Pi Pico uses 3.3V logic:
Warning: Double-check your sensorβs voltage requirements. Some sensors marked β5Vβ actually mean βcan be powered by 5Vβ but use 3.3V logic. Read the datasheet to be sure.
The BME280 uses very little current:
This means you can power the BME280 directly from the Pico with no issues.
Once everything is connected, letβs verify the wiring with a simple test:
from machine import I2C, Pin
import time
# Initialize I2C
i2c = I2C(0, scl=Pin(9), sda=Pin(8), freq=400000)
print("Testing I2C connection...")
print("If this runs without errors, wiring is likely correct")
# Try to scan for devices (we'll learn more about this in the next lesson)
devices = i2c.scan()
if devices:
print(f"Found {len(devices)} device(s)!")
for device in devices:
print(f" - Device at address: 0x{device:02X}")
else:
print("No devices found - check your wiring")
What you should see:
Testing I2C connection...
If this runs without errors, wiring is likely correct
Found 1 device(s)!
- Device at address: 0x76
or
Found 1 device(s)!
- Device at address: 0x77
Note: BME280 sensors usually appear at address 0x76 or 0x77, depending on the manufacturer and whether theyβve connected the SDO pin to GND or VCC.
Letβs build confidence with your wiring:
# Using alternate pins
i2c = I2C(0, scl=Pin(5), sda=Pin(4), freq=400000)
devices = i2c.scan()
print(f"Devices on alternate pins: {devices}")
Problem: Test code shows βNo devices foundβ
Possible causes:
Solution checklist:
Problem: Error message like βOSError: [Errno 5] EIOβ or βI2C bus errorβ
Possible causes:
Solutions:
Problem: Device found but at unexpected address
This is usually fine! BME280 sensors can appear at either 0x76 or 0x77. Make note of your sensorβs address - youβll need it for the next lesson.
# If your sensor is at 0x76 instead of 0x77, just use that
BME280_ADDRESS = 0x76 # or 0x77
One of I2Cβs superpowers is connecting multiple devices to the same bus. Hereβs how:
All devices share the same SDA and SCL lines:
Pico GP8 (SDA) βββ¬ββ Device 1 SDA
βββ Device 2 SDA
βββ Device 3 SDA
Pico GP9 (SCL) βββ¬ββ Device 1 SCL
βββ Device 2 SCL
βββ Device 3 SCL
Pico 3.3V ββββββββ¬ββ Device 1 VCC
βββ Device 2 VCC
βββ Device 3 VCC
Pico GND βββββββββ¬ββ Device 1 GND
βββ Device 2 GND
βββ Device 3 GND
Each device gets its own power and ground, but they share the communication lines.
Remember: Each device needs a unique address. You canβt have two BME280s at 0x76 on the same bus.
In this lesson, you mastered:
Your BME280 is now physically connected and ready to communicate. Youβve verified it appears on the I2C bus with the test code.
Now that your sensor is wired and responding, letβs learn how to scan the I2C bus systematically, understand device addresses, and why that β0xβ notation keeps appearing. In the next lesson, weβll explore I2C scanning in detail and prepare to read actual sensor data.
You can use the arrows β β on your keyboard to navigate between lessons.
Comments