A capacitive soil moisture sensor lets your ESP32 S3 tell you when soil is dry and needs water, without the corrosion problems of the cheap resistive probes you often see bundled with starter kits. This walkthrough covers wiring the sensor, reading raw values over serial, and calibrating a threshold so your code can report WET or DRY instead of just numbers.
The full tutorial, with every detail and the line-by-line code explanation, is on our site: ESP32 S3 - Soil Moisture Sensor
What you need
- ESP32 S3 WROOM N16R8
- ESP32 S3 SuperMini Dev Module
- ESP32 S3 Uno-form Board
- ESP32 S3 Camera Board
- USB Cable Type-A to Type-C (for USB-A PC)
- USB Cable Type-C to Type-C (for USB-C PC)
- Capacitive Soil Moisture Sensor
- Breadboard
- Jumper Wires
- DC Power Jack
- Screw Terminal Expansion Board for ESP32 S3
- Breakout Expansion Board for ESP32 S3
- Power Splitter for ESP32 S3
- DIYables ESP32 S3 Starter Kit (ESP32 S3 included)
- DIYables Sensor Kit (18 sensors/displays)
Wiring
The sensor has three pins: GND, VCC, and AOUT. Connect GND to the ESP32 S3's GND, VCC to the 3.3V pin, and AOUT to GPIO6. The sensor runs happily on 3.3V, so there's no need for a level shifter or any extra components between it and the board.
Keep the circuit board part of the sensor, the bit with the electronics, above the soil or water line at all times. Only the probe itself should go into the soil.
How it works
Capacitive sensors measure moisture by sensing capacitance changes in the soil around the probe, rather than passing current between exposed metal contacts like resistive sensors do. That means nothing touches the soil electrically, so there's no corrosion over time.
The output on AOUT is inversely proportional to moisture: wetter soil gives a lower voltage, drier soil gives a higher voltage. The ESP32 S3 reads that voltage through its ADC, so lower readings mean wet soil and higher readings mean dry soil.
Code
The sketch sets GPIO6 as an analog input, configures the ADC attenuation to handle inputs up to about 3.3V, then reads the pin every 500 milliseconds with analogRead() and prints the value to the Serial Monitor at 115200 baud. Run this version first, before soil, to watch raw numbers and figure out your own thresholds.
Once you've calibrated, you swap in a version that compares the reading against a THRESHOLD constant and prints WET or DRY accordingly.
esp32-s3-soil-moisture-sensor.ino
/*
* This ESP32 S3 code was developed by newbiely.com
*
* This ESP32 S3 code is made available for public use without any restriction
*
* For comprehensive instructions and wiring diagrams, please visit:
* https://newbiely.com/tutorials/esp32-s3/esp32-s3-soil-moisture-sensor
*/
#define AOUT_PIN 6 // The ESP32 S3 pin GPIO6 that connects to AOUT pin of moisture sensor
void setup() {
Serial.begin(115200);
// set the ADC attenuation to 11 dB (up to ~3.3V input)
analogSetAttenuation(ADC_11db);
}
void loop() {
int value = analogRead(AOUT_PIN); // read the analog value from sensor
Serial.print("Moisture value: ");
Serial.println(value);
delay(500);
}
Things that go wrong
If your readings seem inconsistent regardless of sensor version, you may have a low-quality unit; the TLC555I-based capacitive sensor is the one confirmed to behave reliably. If you're testing in liquid rather than soil, use salt water, since pure water barely conducts and won't change the reading.
Thresholds also aren't universal: typical dry readings land around 2200–2500 and wet readings around 1200–1500, but your exact numbers depend on soil type, salinity, and probe depth, so recalibrate for your actual soil rather than reusing someone else's threshold.
Full tutorial
The complete tutorial - wiring diagram, code explanation and troubleshooting - is here: https://newbiely.com/tutorials/esp32-s3/esp32-s3-soil-moisture-sensor

Top comments (0)