Soil Moisture Monitoring with ESP32 and MQTT
A basic IoT soil moisture monitor needs an ESP32, a capacitive soil moisture sensor and a way to report readings, such as MQTT. The hardest part is not the code but wiring the sensor correctly and calibrating it for your soil.
What you need
- ESP32 development board
- Capacitive soil moisture sensor (analog output, 3.3 V compatible)
- Jumper wires, breadboard, USB power
- Wi-Fi network and an MQTT broker (a local Mosquitto instance is fine)
Why capacitive, not resistive?
Resistive probes pass current through the soil, which accelerates corrosion and makes readings drift. Capacitive sensors measure a change in capacitance without exposed metal electrodes in contact with the soil and last much longer, so they are the better choice for anything that stays in the ground.
Wiring
| Sensor pin | ESP32 pin | Note |
|---|---|---|
| VCC | 3V3 | Use 3.3 V so the output never exceeds the ADC range |
| GND | GND | |
| AOUT | GPIO34 | An ADC1 input; ADC2 pins cannot be used while Wi-Fi is on |
Calibration
Raw ADC values differ between sensors and soils. Print the raw reading with the sensor in dry air, then in a glass of water (up to the line marked on the sensor), and use those numbers as your dry and wet limits. Then check in actual soil, because air and water are only the extremes.
Code
#include <WiFi.h>
#include <PubSubClient.h>
const char* WIFI_SSID = "YOUR_WIFI";
const char* WIFI_PASS = "YOUR_PASSWORD";
const char* MQTT_HOST = "broker.local";
const int SENSOR_PIN = 34; // ADC1
const int DRY_RAW = 3000; // replace after calibration
const int WET_RAW = 1300; // replace after calibration
WiFiClient net;
PubSubClient mqtt(net);
int readMoisturePercent() {
long sum = 0;
for (int i = 0; i < 16; i++) { sum += analogRead(SENSOR_PIN); delay(5); }
int raw = sum / 16; // average to reduce noise
int pct = map(raw, DRY_RAW, WET_RAW, 0, 100);
return constrain(pct, 0, 100);
}
void ensureConnections() {
if (WiFi.status() != WL_CONNECTED) {
WiFi.begin(WIFI_SSID, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED) delay(500);
}
while (!mqtt.connected()) {
if (!mqtt.connect("soil-node-01")) delay(2000);
}
}
void setup() {
Serial.begin(115200);
analogReadResolution(12);
mqtt.setServer(MQTT_HOST, 1883);
}
void loop() {
ensureConnections();
mqtt.loop();
static unsigned long last = 0;
if (millis() - last > 30000) {
last = millis();
char msg[8];
snprintf(msg, sizeof(msg), "%d", readMoisturePercent());
mqtt.publish("farm/field1/soil/moisture", msg, true);
}
}
Common mistakes
- Using an ADC2 pin and getting erratic values once Wi-Fi starts.
- Powering from 5 V and driving the signal above 3.3 V.
- Skipping calibration and trusting a percentage that is only a guess.
- Controlling a pump from a single noisy reading: add averaging and hysteresis.
- Leaving the sensor’s electronics exposed to water; seal the top edge.
Next steps
Add a relay for irrigation with hysteresis, move to deep sleep for battery operation and display the data in Node-RED. These are covered in the Smart Agriculture IoT course and the ESP32 course. Background on the protocol is in MQTT explained.
References
- Espressif, ESP32 Series Datasheet (ADC and pin information): espressif.com
- PubSubClient library: github.com/knolleary/pubsubclient
Related reading
IoT Projects
IoT Project Ideas for Students by Skill Level
Fifteen practical IoT project ideas for students, grouped by skill level, with the hardware, difficulty and what makes each project strong.
IoT Fundamentals
IoT Learning Roadmap for Engineering Students: What to Learn and When
A semester-by-semester IoT roadmap for engineering and diploma students, from electronics basics to a documented project.
IoT Communication and Cloud
MQTT Explained with Examples
MQTT is the lightweight publish/subscribe protocol behind much of IoT messaging. Learn brokers, topics, QoS, retained messages and last will with examples.
Arduino and ESP32
Arduino Uno vs ESP32 for IoT Projects
Which board should you use for an IoT project? A practical comparison of Arduino Uno and ESP32 on connectivity, power, I/O and learning curve.
Learning from your city?
City guides show how online IoT training works from where you are, with project themes for your area.