Preview build — page text is a draft awaiting human review. Code badges come from real compiles. The flasher is real but not yet hardware-tested; the Playground is still a preview.

Rain sensor with Raspberry Pi Pico W — MicroPython rain detector

Detect rain with an FC-37 / YL-83 raindrop sensor on a Pico W: AO on ADC2 (GP28) for intensity, DO on GP21 for a yes/no, powered from 3V3.

MicroPythonVerified — micropython (mpy-cross v1.29.0), 3 Nov 2026Compile-only

Community draft — report a mistake

The raindrop sensor is a PCB plate of interleaved tracks plus a small LM393 comparator board. Water bridging the tracks lowers the resistance, which the Pico W reads two ways: AO on GP28 (ADC2) for how wet, and DO on GP21 for a simple yes/no.

Power it from 3V3 so neither output can exceed the Pico’s limit. The script prints the wetness every two seconds and lights the on-board LED when it rains.

Wiring

Raspberry Pi Pico WOnly the pins used are shown · 3.3 V logicRain sensor (FC-37 / YL-83)GND3V3GP28GP21VCCGNDDOAO
Every connection
Raspberry Pi Pico WRain sensor (FC-37 / YL-83)WireNotes
3V3VCCred3V3 is pin 36. Both outputs then stay at or below 3.3 V.
GNDGNDblack
GP28AOgreenGP28 = ADC2, physical pin 34.
GP21DOyellowGP21 is physical pin 27.

3.3–5 V part, 3.3 V board. AO and DO swing up to VCC. Power the module from 3.3 V on ESP32/Pico so AO stays within the ADC range.

Board quirks

  • AO falls as more of the plate is wet; the script turns it into a 0–100 % “wet” figure and a rough dry / drizzle / rain / heavy label.
  • DO goes LOW when water crosses the pot setting — the on-board LED follows it. Useful to close a window actuator or pull in a clothes line.
  • The exposed tracks corrode in a few monsoon weeks if powered all the time. Mount the plate at an angle so water runs off, and only the plate goes outside — keep the comparator board and Pico dry.
  • GP28 is the ADC pin next to AGND and ADC_VREF on the right header; GP26–GP28 are the only analog pins.

Code

main.pyMicroPython
# Rain / raindrop sensor (FC-37 / YL-83 plate + LM393 board) on a Raspberry Pi Pico W (MicroPython).
# Wiring: VCC -> 3V3 (pin 36), GND -> GND, AO -> GP28 / ADC2 (pin 34), DO -> GP21 (pin 27).
# Powered from 3.3 V, AO and DO can never exceed the Pico's limit.
from machine import ADC, Pin
import time

ao = ADC(28)
do = Pin(21, Pin.IN)
led = Pin("LED", Pin.OUT)


def wetness():
    raw = sum(ao.read_u16() for _ in range(8)) // 8
    return 100 - raw * 100 // 65535, raw  # AO falls as the plate gets wetter


print("Rain sensor: AO on GP28, DO on GP21")
while True:
    pct, raw = wetness()
    raining = do.value() == 0  # DO goes LOW when water crosses the pot threshold
    led.value(raining)
    if pct < 10:
        state = "dry"
    elif pct < 40:
        state = "drizzle"
    elif pct < 70:
        state = "rain"
    else:
        state = "heavy rain"
    print("Wet {:3d} %  (raw {:5d})  DO={}  {}".format(pct, raw, do.value(), state))
    time.sleep(2)

Expected serial output

REPL / Thonny shellOutput
Rain sensor: AO on GP28, DO on GP21
Wet   3 %  (raw 63520)  DO=1  dry
Wet  47 %  (raw 34612)  DO=0  rain

Common errors

Reads wet long after the rain stops

The plate stays wet or dirty. Angle it, wipe it, and expect a delay of several minutes as it dries.

DO never changes

Turn the pot on the small board until its DO LED switches when you drip water on the plate.

↑↓ to move · Enter to open