Plant133: A DIY Automatic Indoor Plant Watering System

Posted on November 18, 2023 • Last modified on September 19, 2026 • 13 min read • 2,638 words
Project:   Plant133
A closed-loop, ESP32-powered indoor plant watering system with adaptive filtering, Home Assistant telemetry, and a custom PCB.
Plant133: A DIY Automatic Indoor Plant Watering System

Automating indoor plant watering sounds simple until you consider soil hydrology and Murphy’s law. If you naively pump water until a soil sensor detects moisture, diffusion delay will cause you to over-saturate the root zone and drown your plant. Worse, if the soil sensor fails, stops making good contact with the soil, or is removed from the soil for whatever reason, you might pump the reservoir dry, overflow the pot or its base, damage the pump, and even damage your house. Plant133 is an automated indoor watering device powered by an ESP32 and a custom PCB that solves this using a closed-loop pulsed watering cycle, daily watering limits, and adaptive digital signal filtering.

Plant133 automated plant watering device
Plant133: an automated watering system combining a custom ESP32 PCB, 3D-printed reservoir, and Home Assistant telemetry.

The system is designed for unattended operation: keeping soil moisture precisely within a target window, protecting the submersible pump from running dry, and reporting telemetry to a smart home system.

This post covers the initial hardware design, closed-loop watering logic, and physical construction. Later posts expand on lessons learned from years of real-world use:

System Architecture  

Rather than a simple threshold switch, Plant133 is built around a closed-loop control and monitoring pipeline:

  • Pulsed Closed-Loop Control: A state machine runs short pump bursts followed by 15-minute diffusion pauses, giving water time to soak through the soil column before re-evaluating moisture.
  • Adaptive Signal Filtering: Switches between a wide 5-minute smoothing kernel during active watering cycles to reject noise, and a fast tens-of-seconds filter during idle monitoring.
  • Pump Run-Dry Protection: A mechanical float switch paired with a programmable 10-second runout budget allows the system to scavenge the bottom of the reservoir without running the pump dry.
  • Custom KiCad PCB: Integrates a 5V-to-3.3V buck regulator, N-channel MOSFET motor drive with inductive flyback protection, and an I2C OLED diagnostic display.
  • Production IoT Telemetry: Native Home Assistant MQTT auto-discovery, InfluxDB time-series logging, and push notifications when the reservoir needs refilling.

The Closed-Loop Watering Process  

The primary challenge in automated watering is managing the delay between adding water at the surface and sensing that water at the root level. When Plant133 waters my spider plant, it maintains soil moisture between 65% and 75%, where 0% represents dry air and 100% represents immersion in a glass of water.

Graph showing soil moisture percentage increasing as the plant is watered
A plot of soil moisture percentage over time, showing the stair-step absorption during pulsed watering cycles.

When the soil moisture drops below 65%, Plant133 initiates a sequence of watering pulses. The pump runs for a few seconds, followed by a (configurable) 15-minute wait state that lets moisture migrate naturally through the soil. This sequence creates the distinct stair-step pattern shown in the telemetry plot above: the raw sensor signal is plotted in yellow, while the real-time filtered value is shown in green. Watering halts as soon as the smoothed reading crosses the 75% upper limit.

This operational logic is governed by the state machine below:

Eval
Eval
Dose
(pump on)
Dose...
End of Dose
(pump off)
End of Dose...
Wait for next cycle
Wait for next cycle
Disabled
Disabled
Check moisture
Check moisture
Check moisture
Check moisture
Watering enabled via web interface
Watering e...
moisture
< min
moisture...
moisture
 > max
moisture...
moisture
>= min
moisture...
moisture
<= max
moisture...
wait dose msecs
wait dose...
wait 15 minutes
wait 15 minutes
Check reservoir
Check reservo...
is empty
is empty
not empty
not empty
wait 1 minute
wait 1 m...
wait 1 minute
wait 1 m...
moisture reading is outside valid range
moisure reading is...
Text is not SVG - cannot display
State machine diagram for the plant watering logic

There is one additional failsafe: a daily limit for pump cycles. Moisture sensor readings can be unreliable for a number of reasons: sensor failure, a broken wire or poor connector contacts, poor soil contact, or the sensor getting completely knocked out of the soil. In some of these cases, the moisture sensor reading will be detected as invalid and watering will be disabled. In other cases, the moisture reading might appear valid but never reach the desired value no matter how much water is pumped. If the reservoir has enough water, this can lead to all kinds of problems. Thus we limit the total number of watering cycles per day to a safe number, typically 4 or 5, to avoid damage to plant and house, and to detect and report the potential problem.

Hardware  

Plant133 is designed to be made using inexpensive and easily obtainable hardware. This includes a pump, sensors, microcontroller, 3D-printed components, and a custom-designed circuit board. All printed components were designed using the OpenSCAD1 CAD package.

Sensors  

Capacitive soil moisture sensor with analog output
Capacitive soil moisture sensor with analog output

Plant133 has three sensors. Because this is a system for watering plants, the most important is the soil moisture sensor. This capacitive moisture sensor2 is reliable for a long time, especially if you seal its edges , is non-toxic, and works acceptably for this kind of application. See the YouTube video on the subject by Andreas Spiess.3 The sensor is powered by 5V, and has an analog output that can be read with the microcontroller used for this project.

For reading temperature and humidity, the system uses a SHTC34 sensor. This sensor performs well and is simple to interface with the microcontroller.

SHTC3 digital temperature and humidity sensor module
SHTC3 digital temperature and humidity sensor module

For detecting when the reservoir level is getting low, it uses a simple float sensor.5

Mechanical float switch for water level detection
Mechanical float switch for water level detection

Actuator  

The system uses an aquarium pump6 to move water from the reservoir to the plant. The vertical pump configuration has the intake hole on the bottom, which allows use of almost all the water in the reservoir. Water below the level of the intake cannot be used.

Small 5V vertical aquarium pump used for plant watering
Small 5V vertical aquarium pump used for plant watering

A printed spike inserted into the soil spreads the pumped water. The spike is printed in two pieces, then connected together with the epoxy coating which also makes the part waterproof.

3D printed watering spike for distributing water into the soil
3D printed watering spike for distributing water into the soil

Water reservoir  

3D printed lid for the plant watering water reservoir
3D printed lid for the plant watering water reservoir
The reservoir is mainly a vessel for holding water for watering the plant. It is covered by a lid which serves as a platform for holding the EBox. The EBox contains the electronic components. The reservoir lid also has a hinged flap which can be opened for refilling the reservoir.

3D printed insert holding the pump and float sensor inside the reservoir
3D printed insert holding the pump and float sensor inside the reservoir
The pump shouldn’t be run when the reservoir is dry, and the reservoir must be refilled when near empty, so the system needs to sense the water level. A simple float-based level sensor detects when the reservoir is near empty. The lid has a cut-out to make room for an insert which holds the float sensor, the pump, and the water tube from the pump to the soil. There is still a usable amount of water in the reservoir when the float falls to its bottom position. The microprocessor thus allows a programmable amount of total pumping time after the float indicates that the water level is low. By default, this is 10 seconds of pump operation.

The reservoir, lid, and insert are printed with PETG filament, and coated with epoxy to make them waterproof.

Circuit board  

Inside the EBox is the main circuit board.

Assembled Plant133 PCB with ESP32 module and connectors
Assembled Plant133 PCB with ESP32 module and connectors
This uses a ESP32 microcontroller module. The ESP32 module has:

  • Analog inputs which can read the moisture sensor,
  • Digital inputs which can read the float sensor,
  • Digital outputs which can control the pump and LED indicator lights,
  • An I2C serial interface which can be used to talk to an OLED display and the temperature/humidity sensor,
  • A serial interface which can be used to talk to a developer computer using a separate USB to serial board,
  • Onboard flash storage which can be used for storing software and configuration settings, and
  • A Wifi interface for talking to a web browser, and optionally to a MQTT broker for data-logging and control.

The ESP32 module is relatively inexpensive, and can be used with a large number of open source Arduino libraries for things like sensor interfaces, flash storage, web clients, and MQTT clients.

Wifi is important because it provides a way for users to set the watering parameters such as minimum and maximum soil moisture levels and the length of time the pump runs during a watering cycle. It also makes possible some methods to notify users to refill the reservoir.

The circuit board provides connections from the microprocessor to connectors for the pump, moisture sensor, float sensor, and an OLED screen. It also has a USB micro jack for power, and an edge connector which can be used to attach an external USB serial adapter for reprogramming the CPU. The board has a MOSFET and fly-back diode for powering the pump motor, and a 3.3V voltage converter for powering the microprocessor. There is also the temperature/humidity sensor mounted near the connectors where it can be exposed to the air. LED indicator lights indicate the state of the reservoir sensor, pump power, and the watering state machine.

3D printed enclosure for the Plant133 electronics
3D printed enclosure (EBox) for the Plant133 electronics
The circuit board is housed by a 3D-printed box which contains the board, while exposing the connectors, the OLED screen, and the USB jack.

The circuit board was designed using the open source KiCAD7 package, and printed by JLCPCB.8

KiCad PCB layout design for the Plant133 project
KiCad PCB layout design for the Plant133 project

Software  

Framework  

The software for Plant133 is written in C++. I used the Arduino framework for developing software for the ESP32 because of the ease of finding documentation, examples, and libraries online. I used the PlatformIO9 development system because I wanted a command-line interface for building code and the ability to create libraries and projects with a number of source files.

Web interface  

The code has a web interface for configuring a connection to a WiFi access point. When no Wifi connection is configured, it starts as an access point with ESSID “plant133” and no password. A user can connect to it, and then press the “WiFi Configure” button to tell it how to connect to an access point.

Plant133 web dashboard showing moisture, temperature, and pump status
Plant133 web dashboard showing moisture, temperature, and pump status

Once the device is connected to a WiFi server, it displays its IP address using its OLED screen so one can easily connect to it via a web browser on a computer that is connected to the same network.

The web interface can also be used to connect to a MQTT broker, and to set parameters for the plant watering system.

Configuration  

A number of configuration parameters can be specified. The minimum and maximum soil moisture levels for the plant can be set, as well as the time to run the pump for each increment of watering. A user can also calibrate the moisture sensor by setting the ADC readings when the sensor is in the open air and when submerged in a glass of water.

Web interface for configuring watering thresholds and pump timings
Web interface for configuring watering thresholds and pump timings

The web interface can also enable or disable the watering system, and enable or disable the reservoir water check. If the reservoir level is enabled, then after the water level sensor reads low-water (e.g., the float is at the bottom of its travel), the pump will run a total of a specified number of seconds, usually 10, and then watering is suspended until the water level sensor indicates that there is water in the reservoir again.

MQTT  

For development and monitoring, it is useful for the system to communicate its inner state to the outside world. One useful way to do this for “Internet of Things” (IOT) devices is the MQTT protocol.[^MQTT protocol] The system state is sent periodically to an MQTT broker, where other systems can subscribe to updates. An example of this state information, encoded as a JSON string, is shown below.

{"reservoir":              "ON",
 "soil_moisture_raw":      1919,
 "soil_moisture":          68.60,
 "soil_moisture_filtered": 68.66,
 "temperature":            27,
 "humidity":               30.76,
 "pump":                   "OFF",
 "watering_state":         3,
 "pump_sec_left":          10}

Home Assistant  

I run the Home Assistant[^Home Assistant] home automation system at my house. The Plant133 system sends special MQTT messages to the broker which tells Home Assistant about the available status information and how to use it.

Plant133 status and controls integrated into the Home Assistant dashboard
Plant133 status and controls integrated into the Home Assistant dashboard
This is an example interface displaying some of the information from the system, along with links to the web interfaces for controlling the devices on the home network.

Home Assistant sends a notification to my phone when a reservoir needs refilling.

InfluxDB and Grafana  

At my house, this data also goes to an InfluxDB10 time series database for long-term storage and analysis. The data can be displayed via InfluxDB’s built in graphing systems or using a system like Grafana.11 An example Grafana plot showing the status of the system watering the spider plant is shown here.

Grafana dashboard showing detailed historical graphs of soil moisture and pump activity
Grafana dashboard showing detailed historical graphs of soil moisture and pump activity
A four hour time window of the system is displayed. Each pump cycle is followed by an increase in the soil moisture level. After the second watering cycle, the float sensor measuring the reservoir level starts to read low. The 10 seconds of pump time winds down to zero over the following cycles. By the time the reservoir is completely empty however, the moisture level has risen to the point where watering is finished. I refilled the reservoir around 5:45pm.

Conclusion  

Plant133 has gone through a huge number of iterations. So far, it is working reliably in my house, but earlier versions have not worked well in other households due to reliability and lack of usability when not connected to Home Assistant. When something wasn’t working correctly, it was very difficult to detect and diagnose the problem. If mDNS was not available, it was tricky figuring out the IP address of the device to open its web interface. Improvements in the latest version, adding an OLED screen and various hardware and software updates, have taken it to the point where it is useful for other homes.

Please see my follow-up posts about the project:

All software and hardware designs for the latest version of this projects are available at my GitHub repository under the very permissive MIT license.

References  


  1. OpenSCAD is an open source program implementing a programming language for building 3D models. It is a way to build models using solid modeling primitives. ↩︎

  2. Capacitive moisture sensor ( from Amazon ). ↩︎

  3. Andreas Spiess produces YouTube videos on sensors, radios, microprocessors, and electronics. ↩︎

  4. An SHTC3 module is a temperature and humidity sensor that communicates with a microprocessor using I2C ( AliExpress ) ( Datasheet ). ↩︎

  5. Float sensor ( Amazon ). ↩︎

  6. Aquarium pump ( from AliExpress ). The vertical pump orientation works best. ↩︎

  7. KiCAD is open source circuit board design software. ↩︎

  8. JLCPCB is a company from which I ordered circuit boards designed using KiCAD. ↩︎

  9. PlatformIO is an open source framework for compiling and uploading embedded software, and managing libraries used by this software. ↩︎

  10. InfluxDB is an open source time series database. ↩︎

  11. Grafana is an open source data analysis/graphing system. ↩︎