Example project · Sensors
Pico 2 + BME280 over I2C
A real RP2350 Hazard3 core boots the pinned official RISC-V MicroPython v1.29.0 image, scans a BME280 on I2C0 (GP4/GP5), then reads and compensates its registers directly. Disconnect SDA to see the honest OSError path.

What's on the bench
- 2× Resistor
- Battery
- BME280
- Pi Pico 2
How it's wired
- Battery · pos→Pi Pico 2 · vsys
- Battery · neg→Pi Pico 2 · gnd
- Pi Pico 2 · 3v3→BME280 · vcc
- Pi Pico 2 · gnd→BME280 · gnd
- Pi Pico 2 · gp4→BME280 · sda
- Pi Pico 2 · gp5→BME280 · scl
- Pi Pico 2 · 3v3→Resistor · a
- Resistor · b→BME280 · sda
- Pi Pico 2 · 3v3→Resistor · a
- Resistor · b→BME280 · scl
The code
This MicroPython script runs on the emulated board every boot; edit it in the Code tab.
from machine import I2C, Pin i2c = I2C(0, sda=Pin(4), scl=Pin(5), freq=400000) def u16(b, n): return b[n] | (b[n + 1] << 8) def s16(v): return v - 65536 if v & 0x8000 else v try: scan = i2c.scan() chip = i2c.readfrom_mem(0x76, 0xD0, 1)[0] i2c.writeto_mem(0x76, 0xF4, b'\x27') ctrl = i2c.readfrom_mem(0x76, 0xF4, 1)[0] cal = i2c.readfrom_mem(0x76, 0x88, 6) raw = i2c.readfrom_mem(0x76, 0xFA, 3) t1, t2, t3 = u16(cal, 0), s16(u16(cal, 2)), s16(u16(cal, 4)) adc = (raw[0] << 12) | (raw[1] << 4) | (raw[2] >> 4) v1 = (((adc >> 3) - (t1 << 1)) * t2) >> 11 v2 = (((((adc >> 4) - t1) * ((adc >> 4) - t1)) >> 12) * t3) >> 14 temp = ((v1 + v2) * 5 + 128) >> 8 if scan == [0x76] and chip == 0x60 and ctrl == 0x27: print('P2-I2C-OK scan=%s chip=0x%02x ctrl=0x%02x temp=%d.%02d' % (scan, chip, ctrl, temp // 100, temp % 100)) else: print('P2-I2C-FAIL unexpected response') except OSError: print('P2-I2C-FAIL OSError')



