Skip to content
Sanderr
All posts

· Technologia · 3 min read

Building a smarter plant

ESP32 soil moisture monitor installed in a plant pot

For about a year, I had an ESP32 and a couple of capacitive soil moisture sensors sitting in a drawer. I had already tried getting one to work once before, but eventually gave up after running into problems I couldn’t figure out.

A few days ago I decided it was time to give it another shot.

Back to the breadboard

ESP32 DevKit board with jumper wires attached, held up by hand

The first thing I discovered was that the sensor I had originally been testing was simply faulty. Luckily, I had another one lying around.

This one looked much more promising. It returned sensible values at first, but after a minute or two every reading slowly drifted back towards zero. My first thought was that I’d connected it to the wrong GPIO pin, so I tried a couple of different analog inputs. The behaviour stayed exactly the same.

Eventually I stumbled upon the actual cause.

The documentation for the sensor suggests powering it from 3.3V, but on my ESP32 it only became stable once I connected it to VIN (5V) instead. As soon as I switched the power supply, the readings stopped drifting and finally became reliable.

Calibrating the sensor

ESP32 wired to a capacitive soil moisture sensor v2.0 and a green LED on a desk

With stable readings, I could finally calibrate the sensor.

The measurements ended up looking roughly like this:

ConditionReading
Air2200–2350
Dry soil1850–2000
Moist soil1400–1500
Freshly watered400–600

Instead of simply showing “wet” or “dry”, I wanted a bit more feedback. I ended up defining four moisture levels:

  • 🟢 Healthy
  • 🟢🔴 Getting dry
  • 🔴 Water needed
  • 🔴 Flashing red — water me now

At first these states only existed in Home Assistant, but I thought it would be nice if the plant itself could tell me how it was doing.

That meant adding two LEDs.

The hardware ended up being surprisingly simple:

Code
ESP32 DevKit

Soil moisture sensor

├── VCC → VIN (5V)

├── GND → GND

└── AO → GPIO34

Green LED

└── GPIO25 → 220Ω resistor → LED → GND

Red LED

└── GPIO26 → 220Ω resistor → LED → GND

My first soldering project

ESP32 soldered onto a perfboard with a capacitive soil moisture sensor, powered over USB-C

Everything started as a pile of jumper wires on my desk. Only after I knew the hardware and software worked reliably did I solder everything together.

This was also my first time soldering.

My first few solder joints definitely weren’t pretty, but once I started using flux everything suddenly became much easier. It’s one of those things that immediately makes you wonder why you didn’t use it from the start.

The final result certainly isn’t perfect, but it’s solid enough to live inside a plant pot.

From Arduino to ESPHome

Home Assistant dashboard showing soil moisture at 73% and the plant status "Well watered"

Originally the LEDs and sensor were driven by a small Arduino sketch. Once everything worked, I migrated the project to ESPHome so I could update the ESP32 over Wi-Fi instead of pulling it out of the planter every time I wanted to tweak a threshold.

There were a couple of moments where I thought I’d broken something. At one point the LEDs kept reporting dry soil, even with the sensor sitting in a glass of water. In the end, nothing was actually wrong — the median filter was simply averaging older measurements, so it took a while before the new reading became visible.

The sensor now reports its moisture level to Home Assistant while the LEDs provide the same status directly on the plant. Even without opening the dashboard, I can immediately see whether it needs watering.

For now, the ESP32 is still sitting loose inside the planter, so I mostly just have to remember not to pour water directly over it.

Designing and 3D printing a proper enclosure will probably be the next step.

Components

  • ESP32 DevKit
  • Capacitive Soil Moisture Sensor
  • 2× 220Ω resistors
  • Green LED
  • Red LED
  • Stripboard
  • Jumper wires

More writing

All posts