Air-quality station (SEN55 + OLED)
A desk-ready monitor: the ESP32 polls a Sensirion SEN55 over I2C and renders live PM2.5, humidity, and temperature to the OLED once a second. Press Run, then ▶ Run script in the serial monitor, and the display updates like the real appliance.

How it works
A Sensirion SEN55 read over I²C with its real command set: the script starts measurement by writing 0x0021 to address 0x69, then polls command 0x03C4 and unpacks the 24-byte reply into PM2.5 (scaled ÷10), humidity (÷100), and temperature (÷200), exactly like production firmware. The SEN55 sits on the 5 V rail because its fan is a real load; its data pins share the C3's I²C bus (SDA=G8, SCL=G9) with the SSD1306 that renders the station readout once a second.
What's on the bench
- Battery
- ESP32-C3
- OLED 128×64
- SEN55
How it's wired
- hole a10→hole B-5
- hole a11→hole B+5
- hole a30→hole B+9
- hole a31→hole B-9
- hole a32→hole a20
- hole a33→hole f11
- hole a34→hole B-9
- hole a40→hole B-9
- hole a41→hole f10
- hole a42→hole g11
- hole a43→hole b20
The code
This MicroPython script runs on the emulated board every boot; edit it in the Code tab.
from machine import I2C, Pin import framebuf, time i = I2C(0, scl=Pin(9), sda=Pin(8)) buf = bytearray(1024) fb = framebuf.FrameBuffer(buf, 128, 64, framebuf.MONO_VLSB) for c in b'\xae\xd5\x80\xa8\x3f\xd3\x00\x40\x8d\x14\x20\x00\xa1\xc8\xda\x12\x81\xcf\xd9\xf1\xdb\x40\xa4\xa6\xaf': i.writeto(0x3c, bytes([0, c])) def show(): i.writeto(0x3c, b'\x00\x21\x00\x7f\x22\x00\x07') i.writeto(0x3c, b'\x40' + buf) # SEN55: start measurement, then poll (Sensirion I2C command set) i.writeto(0x69, b'\x00\x21') time.sleep(0.2) for n in range(60): i.writeto(0x69, b'\x03\xc4') d = i.readfrom(0x69, 24) w = [(d[k*3] << 8) | d[k*3+1] for k in range(8)] fb.fill(0) fb.text('AIR QUALITY', 20, 2) fb.text('PM2.5 %.1f ug' % (w[1]/10), 0, 20) fb.text('RH %.1f %%' % (w[4]/100), 0, 34) fb.text('TEMP %.1f C' % (w[5]/200), 0, 48) show() print('PM2.5', w[1]/10, 'RH', w[4]/100, 'T', w[5]/200) time.sleep(1)
Try this
- Select the SEN55 and drag its PM2.5 slider: the OLED and the serial line follow.
- Two devices, one bus: run I2C(0, scl=Pin(9), sda=Pin(8)).scan() at the REPL and find 0x3c and 0x69.
- Compare with the fume-extractor build, which turns these same readings into fan control.
- Hover the SEN55 supply pin: 5 V, not 3V3 — the fan needs it.



