Skip to content
Kiln Forged
All projects
ConceptSensors · Wi-Fi · Low power

Plant Moisture Monitor

A battery sensor that sits in a pot, checks soil moisture every hour and sends a reading over Wi-Fi. Runs for months on one charge.

“Make a sensor that sits in a plant pot and tells me when the soil is dry.”
Loading 3D view…
Stage 1

Spec

Spec
Qty 1

Plant Moisture Monitor

A battery-powered soil sensor that reports moisture, temperature and humidity over Wi-Fi every hour.

Power
1000 mAh LiPo, USB-C charging, about 6 months per charge
Size
58 × 38 × 22 mm head with a 10 cm probe
Inputs
Capacitive soil probe, Temperature and humidity sensor, Pair button
Outputs
Status LED, Wi-Fi readings
Connectivity
Wi-Fi 2.4 GHz, USB-C
Budget
Under $20 in parts

Constraints

  • Splash resistant
  • No exposed metal in the soil
  • Why

    Capacitive, not resistive

    Resistive probes corrode in wet soil within weeks. A capacitive probe has no exposed metal and lasts for years.

  • Why

    Hourly readings

    Soil dries over days, so one reading an hour is plenty and keeps the battery going for months.

Stage 2

Circuit board

Top view of the Plant Moisture Monitor board50 mm30 mmU1U2J1J2J3U3U4SW1LED1C1C2
ESP32-C3-MINI-124 components2-layer, 50 × 30 mm≈ $17.37 in parts
  • Why

    Probe power is switched

    The probe only gets power for 50 ms per reading through GPIO1, which saves about 5 mA the rest of the time.

  • Why

    SHT40 for air readings

    It's tiny, accurate to 0.2 °C and draws almost nothing between readings.

Stage 3

Firmware

src/main.cppArduino (PlatformIO)
// Plant Moisture Monitor — wakes every hour, measures soil moisture,
// temperature and humidity, posts them over Wi-Fi, then sleeps again.

#include <Arduino.h>
#include <WiFi.h>
#include <HTTPClient.h>
#include <Wire.h>
#include <Adafruit_SHT4x.h>
#include "pins.h"
#include "secrets.h"   // WIFI_SSID, WIFI_PASS, WEBHOOK_URL

constexpr uint64_t SLEEP_US = 60ULL * 60ULL * 1000000ULL;  // 1 hour
constexpr uint16_t SOIL_DRY = 2900;   // Raw ADC in dry air (calibrate!)
constexpr uint16_t SOIL_WET = 1250;   // Raw ADC in a glass of water

Adafruit_SHT4x sht;

uint8_t readSoilPercent() {
  digitalWrite(PIN_SOIL_PWR, HIGH);     // Power the probe only while reading
  delay(50);
  uint32_t sum = 0;
  for (int i = 0; i < 16; i++) sum += analogRead(PIN_SOIL_ADC);
  digitalWrite(PIN_SOIL_PWR, LOW);
  const int raw = sum / 16;
  return constrain(map(raw, SOIL_DRY, SOIL_WET, 0, 100), 0, 100);
}

bool connectWifi(uint32_t timeoutMs = 8000) {

3 files: src/main.cpp, include/pins.h, platformio.ini

  • Why

    Deep sleep between readings

    The chip is fully asleep for 59 minutes and 58 seconds of every hour, drawing a few microamps.

  • Why

    Calibrate once

    SOIL_DRY and SOIL_WET are set by holding the probe in air and in water. The app will walk you through it.

Stage 4

Enclosure

Outer size
58 × 38 × 22 mm
Material
PETG, 0.2 mm layers
Print time
1 h 40 min, no supports
  • Why

    Drip edge on the lid

    The lid overlaps the base by 2 mm so water from watering runs off instead of in.

Stage 5

Assembly

  1. 1Plug in the battery and probe.
  2. 2Screw the board to the base.
  3. 3Snap on the lid and push the probe into the soil.
  • Why

    Fit check passed

    1.5 mm clearance above the tallest part.

See every stage run, step by step

The workspace shows each engine working, with approval checkpoints in between.

Open in workspace