Welcome to Project 40! Let’s have an honest moment here: keeping houseplants alive is surprisingly stressful. You either forget they exist for three weeks until they turn into crispy husks, or you overcompensate by waterboarding them every morning until they succumb to root rot.
Sure, we built an Automated Plant Waterer back in Project 9, but what if you just want a dashboard you can nervously check from the couch while eating Doritos? What if you want to know exactly how parched your fern is before you commit to getting up?
Enter the ESP32 Smart Plant Monitor. We are going to build a Wi-Fi connected sensor node that hosts its own local web server. No cloud subscriptions, no magic blue smoke, just pure, unadulterated data telling you that your Monstera is thirsty.
If you recall from Lesson 133: Listening to Plants, cheap resistive soil moisture sensors have a fatal flaw: electrolysis. You stick them in wet dirt, pass a current through them, and they literally dissolve into a rusty paste after a few weeks.
For a permanent dashboard setup, we are upgrading to Capacitive Soil Moisture Sensors. They measure moisture using capacitance rather than resistance, meaning their electronics are sealed away from the wet soil, preventing corrosion.
To build this, you’ll need:
The wiring is incredibly straightforward. The capacitive sensor outputs an analog voltage between 0V and 3.3V, which we can easily read with the ESP32’s built-in ADC (Analog-to-Digital Converter).
Note: The ESP32 is a 3.3V logic device. Do not power the sensor from a 5V pin, or the analog output might exceed 3.3V and fry your ADC pin!
We are combining our knowledge from Lesson 153: Setting up a Local Web Server and Lesson 116: Analog Inputs.
The ESP32 will connect to your home Wi-Fi network and spin up an asynchronous web server. When you navigate to the ESP32’s IP address on your phone or computer, it will serve up an HTML page containing a beautiful gauge showing the moisture percentage.
// Snippet: Reading the Capacitive Sensor
const int sensorPin = 36; // VP pin
// You will need to calibrate these values for your specific sensor!
const int airValue = 3500; // Value when sensor is in dry air
const int waterValue = 1500; // Value when sensor is submerged in water
void setup() {
Serial.begin(115200);
}
void loop() {
int sensorValue = analogRead(sensorPin);
// Map the analog value to a percentage (0-100%)
int moisturePercent = map(sensorValue, airValue, waterValue, 0, 100);
// Constrain the percentage between 0 and 100 in case readings drift
moisturePercent = constrain(moisturePercent, 0, 100);
Serial.print("Moisture Level: ");
Serial.print(moisturePercent);
Serial.println("%");
delay(2000);
}
Capacitive sensors are not plug-and-play. Before you put it in the dirt, you must calibrate it.
airValue).waterValue).Now, combine this reading logic with a basic Wi-Fi web server (like we did in Lesson 153), and you’ve got a live dashboard! Let your inner botanist rejoice.