DIY Smart Garden: Build a Soil-Moisture Sensor with ESP32 and Home Assistant

DIY Smart Garden: Build a Soil-Moisture Sensor with ESP32 and Home Assistant

In This Article

    DIY Smart Garden: 7 Ways to Build a Soil-Moisture Sensor with ESP32 and Home Assistant

    You know the feeling. You go on vacation for a week, come back, and your prized monstera looks like it survived a drought in the Sahara. Or worse—you overwater out of guilt, and the roots rot. The problem isn't your gardening skills; it's that you're guessing. Plants don't send text messages when they're thirsty.

    But they don't have to anymore.

    The global smart agriculture market hit $13.8 billion in 2023 and is climbing at 12.6% annually. However, you don't need a commercial greenhouse setup to benefit from this technology. For under $20, you can build a soil-moisture sensor system that monitors your plants in real-time and waters them automatically—all through Home Assistant, the open-source platform with over 1 million active installations.

    Here are 7 ways to build and enhance your own DIY smart garden system using an ESP32 microcontroller and Home Assistant.


    1. Choose the Right Soil Moisture Sensor: Capacitive vs. Resistive

    Before you buy anything, understand the two main sensor types. This decision determines how often you'll be replacing parts.

    Resistive sensors work by passing a small current between two metal probes and measuring the electrical resistance. Wet soil conducts better, so lower resistance means more moisture. They cost $2–$5, which is attractive. But there's a catch: the probes corrode. The constant electrolysis eats away at the metal, and within 1–2 years, your readings drift or fail entirely.

    Capacitive sensors, on the other hand, measure changes in capacitance—the soil's ability to store an electrical charge—using an oscillator circuit and a copper trace coated in a corrosion-resistant finish. They don't expose bare metal to the soil, so they last 3–5 years. They also give more stable readings because they don't depend on ion concentration in the soil, which changes with fertilizer application.

    The cost difference is minor: $5–$15 for a capacitive sensor. The lifespan difference isn't.

    Key Takeaway: Buy a capacitive sensor. The extra $5–$10 upfront saves you from replacing corroded resistive probes every year. DFRobot's SEN0193 is a solid, well-documented option.


    2. Connect the Sensor to Your ESP32: Wiring and Power Considerations

    The ESP32 is a $5–$15 microcontroller with built-in Wi-Fi and Bluetooth, making it the perfect brain for this project. Wiring is straightforward, but there are a few gotchas to watch out for.

    Components you'll need: - ESP32 development board (any variant works; the DevKit V1 is most common) - Capacitive soil moisture sensor - Jumper wires - Breadboard (optional but helpful for prototyping)

    The basic wiring: - Sensor VCC → ESP32 3.3V pin - Sensor GND → ESP32 GND - Sensor AOUT (analog output) → ESP32 GPIO34 (or any ADC-capable pin)

    That's it. Three wires.

    The gotcha: Some sensors are designed for 5V operation. If you power them with 5V, the analog output can exceed 3.3V, which will damage the ESP32's ADC pins. Double-check your sensor's datasheet. If it's 5V-only, use a voltage divider (two resistors, e.g., 10kΩ and 20kΩ) to step down the output voltage before it hits the ESP32.

    Additionally, power the sensor from the ESP32's 3.3V rail, not from a separate 5V supply. The sensor's readings will fluctuate if the voltage isn't stable, and the ESP32's onboard regulator provides clean, consistent power.

    Key Takeaway: Wire VCC to 3.3V, GND to GND, and AOUT to GPIO34. Never feed 5V into the ESP32's pins without a voltage divider.


    3. Calibrate Your Sensor for Accurate Readings

    Raw ADC values are meaningless until you map them to actual soil moisture percentages. The ESP32's ADC is notoriously non-linear, so calibration is non-negotiable.

    Step 1: Dry calibration (0%) - Place the sensor in dry air (or completely dry soil) and record the raw ADC value. Let's say it reads 2800.

    Step 2: Wet calibration (100%) - Submerge the sensor in a glass of water (just up to the marked line, not the electronics) and record the raw value. Let's say it reads 1200.

    Step 3: Map the range The relationship isn't perfectly linear, but for most practical purposes, a linear mapping works:

    moisture_percent = (dry_value - current_value) / (dry_value - wet_value) * 100
    

    So if your sensor reads 2000:

    (2800 - 2000) / (2800 - 1200) * 100 = 50%
    

    The catch: Different soil types have different dielectric properties. Sandy soil holds less water than clay, so the same moisture percentage produces different readings. If you change your potting mix, recalibrate.

    Key Takeaway: Calibrate in air (0%) and water (100%), then use the linear formula above. Recalibrate whenever you change soil types.


    4. Flash ESPHome Firmware for Seamless Home Assistant Integration

    You could write raw Arduino code and send MQTT messages to Home Assistant. But there's a much better path: ESPHome.

    ESPHome lets you define your device in a YAML file, and it generates the firmware automatically. It handles Wi-Fi connectivity, sensor polling, and Home Assistant discovery out of the box. No manual MQTT setup, no custom JSON parsing.

    Here's a minimal configuration:

    esphome:
      name: soil-sensor
      platform: ESP32
      board: esp32dev
    
    wifi:
      ssid: "YourWiFi"
      password: "YourPassword"
    
    api:
      encryption:
        key: "your_encryption_key"
    
    sensor:
      - platform: adc
        pin: GPIO34
        name: "Soil Moisture Raw"
        update_interval: 60s
        filters:
          - calibrate_linear:
              - 1200 -> 100.0  # wet
              - 2800 -> 0.0    # dry
          - lambda: return id(soil_moisture).state;
    

    Wait—the calibrate_linear filter does the heavy lifting. It maps raw ADC values to percentages directly. No manual math in your automations.

    Flashing the firmware: 1. Install ESPHome (via Home Assistant add-on or standalone). 2. Plug the ESP32 into your computer via USB. 3. Run esphome run soil-sensor.yaml — it compiles, flashes, and installs. 4. Once connected, Home Assistant automatically discovers the device. No IP address hunting, no manual integration.

    The update_interval: 60s means the sensor reports every minute. You can adjust this based on your needs.

    Key Takeaway: ESPHome eliminates the hardest parts of firmware development. The calibrate_linear filter converts raw ADC values to percentages in the device itself.


    5. Set Up Automations to Water Your Plants Automatically

    Now for the fun part: making the system act on the data. You'll need a relay module connected to a GPIO pin, which controls a water pump or solenoid valve.

    Relay wiring: - Relay IN pin → ESP32 GPIO26 - Relay VCC → ESP32 3.3V (or 5V if your relay requires it, with a separate supply) - Relay GND → ESP32 GND - Pump/valve power → through relay's COM and NO terminals

    The automation in Home Assistant:

    automation:
      - alias: "Water Plants When Dry"
        trigger:
          - platform: numeric_state
            entity_id: sensor.soil_moisture
            below: 30
        condition:
          - condition: time
            after: "06:00:00"
            before: "20:00:00"
        action:
          - service: switch.turn_on
            entity_id: switch.water_pump
          - delay: "00:00:10"  # run for 10 seconds
          - service: switch.turn_off
            entity_id: switch.water_pump
          - service: notify.mobile_app_phone
            data:
              message: "Plants watered. Soil moisture was {{ states('sensor.soil_moisture') }}%."
    

    This automation triggers when moisture drops below 30%, only runs during daylight hours, waters for 10 seconds, then notifies your phone.

    Pro tip: Add a for: condition to the trigger to prevent watering when the soil is only briefly dry (e.g., right after evaporation on a hot day). Use for: "00:05:00" to require the moisture to stay below threshold for 5 minutes.

    Key Takeaway: A simple numeric_state trigger plus a relay-controlled pump gives you fully automated watering. Always add time-of-day conditions to avoid watering at night, which promotes fungal growth.


    6. Monitor Soil Moisture Trends and Optimize Watering Schedules

    The real value of a smart garden isn't the instant notification—it's the data accumulated over weeks and months.

    Home Assistant's History panel shows you moisture patterns over time. The Long-Term Statistics feature (enabled by default for sensors) gives you hourly, daily, and monthly averages. Use these to answer questions like:

    • How quickly does my soil dry out after watering? (This tells you if your potting mix retains water well.)
    • Does my plant need more water in summer than winter? (Obviously yes, but by how much?)
    • Is my current threshold too aggressive? (If you're watering every day, raise the threshold from 30% to 40%.)

    Multiple sensors for different zones: One ESP32 has multiple ADC-capable pins (GPIO34, 35, 36, 39). You can connect up to 4 sensors to a single board, each monitoring a different plant or garden bed. Define each as a separate sensor in ESPHome:

    sensor:
      - platform: adc
        pin: GPIO34
        name: "Monstera Moisture"
        ...
      - platform: adc
        pin: GPIO35
        name: "Basil Moisture"
        ...
    

    Then create zone-specific automations with different thresholds—basil likes consistent moisture, while succulents prefer to dry out completely between waterings.

    The numbers back this up: smart irrigation systems reduce water usage by 30–50% compared to manual watering, according to the World Bank. That's not just saving water—it's saving money on your utility bill.

    Key Takeaway: Use Home Assistant's history and long-term statistics to fine-tune your thresholds. Connect multiple sensors to one ESP32 to monitor different zones with different needs.


    7. Extend Battery Life with Deep Sleep Mode for Wireless Operation

    The ESP32's biggest weakness is power consumption. In active mode with Wi-Fi connected, it draws 100–240mA. Run it 24/7 and you'll be changing batteries every few days.

    Deep sleep changes the equation. In deep sleep mode, the ESP32 draws only 10–150µA—a 99.9% reduction. The trick is to wake it periodically, take a reading, transmit it, and go back to sleep.

    ESPHome configuration:

    deep_sleep:
      run_duration: 30s
      sleep_duration: 30min
    
    sensor:
      - platform: adc
        pin: GPIO34
        name: "Soil Moisture"
        update_interval: 30s  # only matters while awake
    

    This wakes the ESP32 every 30 minutes, connects to Wi-Fi, reads the sensor, sends data to Home Assistant, then sleeps again. A 2000mAh battery (about $8) will last 3–6 months with this setup.

    Solar-powered option: Pair the ESP32 with a small 6V solar panel and a TP4056 charging module wired to a Li-ion battery. During the day, the panel charges the battery; the ESP32 wakes periodically, sends data, and sleeps. You get an off-grid sensor that never needs manual charging.

    A maker on Hackster.io built exactly this—a solar-powered ESP32 soil sensor sending data to Home Assistant via MQTT. The total hardware cost was around $25, and the sensor has been running for over a year without maintenance.

    One caveat: Deep sleep works best for monitoring, not automation. If you're controlling a water pump, you need the ESP32 awake to trigger the relay. In that case, keep it powered via USB and skip deep sleep.

    Key Takeaway: Deep sleep mode cuts power usage by 99.9%. Combine it with a solar panel and battery for a truly wireless, maintenance-free garden sensor.


    FAQ

    What is the best soil moisture sensor for an ESP32 project? A capacitive sensor, like the DFRobot SEN0193 or the generic capacitive v1.2 boards sold on Amazon. They last longer and give more stable readings than resistive sensors.

    How do I connect a soil moisture sensor to an ESP32? Wire VCC to 3.3V, GND to GND, and AOUT to any ADC-capable GPIO pin (GPIO34–39 are safe choices). Verify your sensor's voltage requirements first.

    How do I calibrate the soil moisture sensor? Read the raw ADC value in dry air (0%) and submerged in water (100%). Use ESPHome's calibrate_linear filter to map these values to percentages.

    Can I use the ESP32 to automate watering? Yes. Connect a relay module to a GPIO pin, control a water pump or solenoid valve, and create a Home Assistant automation that triggers based on soil moisture thresholds.

    How do I integrate the ESP32 sensor with Home Assistant? Use ESPHome. Flash the firmware to your ESP32, and it automatically appears in Home Assistant via the ESPHome API. No manual MQTT configuration needed.

    What is the power consumption of an ESP32 with a soil moisture sensor? Active mode with Wi-Fi: 100–240mA. Deep sleep: 10–150µA. With a 30-minute deep sleep cycle, a 2000mAh battery lasts 3–6 months.

    How many soil moisture sensors can I connect to one ESP32? Up to 4 analog sensors using GPIO34, 35, 36, and 39. Beyond that, you'd need an external multiplexer (like a CD4051).

    Do I need a voltage level shifter for the sensor? Only if your sensor is designed for 5V operation. Most capacitive sensors work fine at 3.3V. Check the datasheet.

    Can I monitor soil moisture remotely? Yes. Home Assistant has a mobile app with push notifications, and you can access your dashboard remotely via the Home Assistant Cloud service or a secure remote connection.

    What is the typical accuracy of a soil moisture sensor? Capacitive sensors typically have ±3–5% accuracy after calibration. They're not laboratory instruments, but they're more than accurate enough for plant care.


    Conclusion

    Building a smart garden with an ESP32 and Home Assistant isn't just a weekend project—it's a practical solution to a real problem. Overwatering kills more houseplants than neglect, and a $15 sensor tells you exactly when your plants need water, eliminating the guesswork.

    Here's the recap:

    1. Choose a capacitive sensor for longevity and accuracy
    2. Wire it correctly to avoid frying your ESP32
    3. Calibrate properly for meaningful percentage readings
    4. Use ESPHome to skip the firmware headaches
    5. Automate watering with a relay and a simple YAML automation
    6. Analyze trends to fine-tune your watering schedule
    7. Add deep sleep for battery-powered, off-grid operation

    Start simple: one sensor, one ESP32, and the basic ESPHome config. Get it working, watch the data for a week, then expand. Add a relay for automated watering. Add a second sensor for a different plant. Add solar power so you never think about batteries again.

    With over 70% of global freshwater going to agriculture and smart irrigation cutting usage by up to 50%, the environmental impact is real. But on a personal level, the benefit is simpler: you stop killing your plants.


    Ready to build your own smart garden? Start with a capacitive sensor and an ESP32 board, and follow the steps in this guide to create a fully automated watering system. Share your project in the comments below or on social media with #DIYSmartGarden!

    R
    Rex Hardwick
    Master Maker & Fabricator
    Former aerospace machinist turned full-time maker. Runs a 3,000 sq ft workshop. Believes the best tool is the one you know how to fix. Based in Portland, OR.

    📬 Get new articles by email

    No spam. Just new articles from Maker Forge.