A soil moisture monitor that runs on a Raspberry Pi Zero 2 W. It reads moisture from an LM393-based sensor and sends a push notification to your phone when your plant needs watering. Includes a web dashboard accessible from any device on the same network.
- The Pi reads a soil moisture sensor every 2 seconds.
- After 3 consecutive dry readings (~6 seconds), it changes state and sends a notification via ntfy.sh.
- A Phoenix LiveView dashboard at
http://spm.local:4000shows the current status and history — updated in real time.
- Raspberry Pi Zero 2 W (H variant, with pre-soldered GPIO headers)
- MH-Sensor-Series soil moisture module (LM393-based)
- Female-to-female Dupont cables
- MicroSD card + card reader
- Micro USB cable + USB power adapter
| Sensor Pin | Pi Pin | Notes |
|---|---|---|
| VCC | Pin 1 (3.3V) | Not 5V — this is important |
| GND | Pin 6 (GND) | |
| DO | Pin 11 (GPIO17) | Digital output (wet/dry) |
Two projects in a poncho layout:
spm/
├── docs/ ← implementation plan
├── ui/ ← Phoenix LiveView dashboard
└── firmware/ ← Nerves firmware (sensor, notifications)
firmware/ depends on ui/ via a path dependency. mix firmware bundles
both into a single image that runs on the Pi.
- macOS
- Erlang 28.4.1 and Elixir 1.19.5-otp-28 (via asdf)
- Nerves toolchain:
mix archive.install hex nerves_bootstrap - System deps:
brew install fwup squashfs coreutils xz pkg-config
cp firmware/config/secrets.exs.example firmware/config/secrets.exsEdit firmware/config/secrets.exs with your 2.4 GHz Wi-Fi SSID and password.
cd ui && mix assets.deploy
cd ../firmware
export MIX_TARGET=rpi0_2
mix deps.get
mix firmware
mix burn- Insert the MicroSD card into the Pi.
- Wire the sensor (see table above).
- Plug the micro USB cable into the PWR port.
- Wait ~30 seconds, then open
http://spm.local:4000.
- Install the ntfy app on your phone.
- Subscribe to the topic you configured in
firmware/config/secrets.exs. - When the soil dries out, you get a push notification.
Work on the dashboard without the Pi:
cd ui
mix phx.server
# Open http://localhost:4000The UI uses fake sensor data in dev mode. Push to the Pi when ready:
cd ui && mix assets.deploy
cd ../firmware
export MIX_TARGET=rpi0_2
mix firmware
mix upload spm.local # over-the-air, no SD card neededThe sensor module has a small blue potentiometer. Turn it with a screwdriver to adjust the wet/dry threshold for your specific plant.
See docs/plan.md for wiring diagrams, safety checklist, iPhone hotspot instructions for demos, and the optional MCP3008 analog upgrade.
Fully moist:
Dashboard reports that:
Suddenly, it gets dry:
Dashboard reports that:
And you get a notification on your phone:

