Capacitive Soil Moisture v1.2 with an ESP32 DevKit V1
A corrosion-resistant capacitive probe that reports soil moisture as a single analog voltage.

On the ESP32 DevKit V1 the capacitive soil probe runs from 3V3 and its AOUT goes to GPIO33, which is ADC1 channel 5. ADC1 keeps reading while Wi-Fi is connected, which is why the page avoids the ADC2 pins for a sensor you will usually log over the network.
Wiring the Capacitive Soil Moisture v1.2 to the ESP32 DevKit V1
Pin by pin.
| Capacitive Soil Moisture v1.2 | ESP32 DevKit V1 |
|---|---|
| VCC | 3V3 |
| GND | GND |
| AOUT | GPIO33 (D33) |
What to know on the ESP32 DevKit V1
- GPIO33 is ADC1_CH5. ADC2 pins (GPIO0, 2, 4, 12 to 15, 25 to 27) are shared with the Wi-Fi driver and return nothing useful once Wi-Fi starts.Espressif ESP32 Series Datasheet v5.3, p. 14; Espressif ESP32 Series Datasheet v5.3, p. 46; ESP-IDF Programming Guide, ADC Oneshot Mode Driver
- The probe outputs 0 V to 3.0 V, lower when wetter, so it fits the ESP32's input without a divider. The sketch's ESP32 constants, 3723 dry and 1489 wet, are those voltages on the 12-bit 0 to 4095 scale.DFRobot SEN0193 wiki, Specification
- Expect the dry end to read less precisely: at the 11 dB attenuation the ESP32 ADC is less accurate for results above 3000 (about 2450 mV). Calibrate the dry and wet values on your own board rather than trusting the defaults.Espressif ESP32 Series Datasheet v5.3, p. 43
- The probe draws 5 mA. For a battery logger, power it from a GPIO only while reading, or leave it on 3V3 and let the ESP32 deep-sleep between readings.DFRobot SEN0193 wiki, Specification
Capacitive Soil Moisture v1.2 code for the ESP32 DevKit V1
Compiled for esp32:esp32:esp32 on 2026-10-29.
// Capacitive Soil Moisture v1.2 on ESP32 DevKit V1: wiring and a free simulation at https://www.tinkered.ai/components/capacitive-soil-moisture-v12/esp32
// Capacitive soil moisture: analogRead + calibrated percent.
// Calibration constants are auto-selected per board (see the table above).
const int SOIL_PIN = 33; // Arduino: A0-A5 | ESP32: an ADC1 GPIO (e.g. 34)
#if defined(ESP32)
const int DRY_VALUE = 3723; // ~3.0V on a 12-bit ESP32 ADC (sensor in air)
const int WET_VALUE = 1489; // ~1.2V (sensor in water)
#else
const int DRY_VALUE = 614; // ~3.0V on a 10-bit Uno ADC (sensor in air)
const int WET_VALUE = 245; // ~1.2V (sensor in water)
#endif
void setup() {
Serial.begin(9600);
}
void loop() {
int raw = analogRead(SOIL_PIN);
// round() (not map(): map() truncates and reads ~1% low)
int moisture = round((float)(raw - DRY_VALUE) * 100.0 / (WET_VALUE - DRY_VALUE));
moisture = constrain(moisture, 0, 100);
Serial.print("Raw ADC: ");
Serial.print(raw);
Serial.print(" | Moisture: ");
Serial.print(moisture);
Serial.println(" %");
delay(500);
}
Capacitive Soil Moisture v1.2 on the ESP32 DevKit V1: questions
Which ESP32 pin should I use for a soil moisture sensor?
An ADC1 pin: GPIO32 to GPIO39 (ESP32 datasheet, p. 46). The page uses GPIO33. ADC2 pins stop reading while Wi-Fi is on (ESP-IDF ADC documentation).
Why does my soil sensor read 4095 or 0 on the ESP32?
4095 means the input is at or above the ADC's top, 0 means it is at ground: check that AOUT, not VCC, is on GPIO33 and that GND is shared. A reading near 3723 in air and near 1489 in water is normal with the page's constants.
Does the probe need 5 V on the ESP32?
No. It takes 3.3 V to 5.5 V through its own regulator (DFRobot SEN0193 wiki), so 3V3 is enough and keeps its output under 3.0 V.
Keep going
This guide as plain Markdown. /components/capacitive-soil-moisture-v12/esp32.md