Capacitive Soil Moisture Sensor

How to measure soil moisture with a capacitive sensor and ESP32

The capacitive soil moisture sensor (commonly sold as "v1.2") measures moisture levels without exposing any metal electrodes to the soil. Unlike the older resistive-type sensors that have two exposed metal prongs, the capacitive version has a sealed PCB surface. This means it does not corrode over time, giving you much longer sensor life in wet soil.

The sensor outputs an analog voltage that varies with soil moisture. Drier soil produces a higher voltage; wetter soil produces a lower voltage. You read this value with the ESP32's ADC and convert it into a moisture percentage.

🔗Key Specs

ParameterValue
Operating voltage3.3V -- 5V
OutputAnalog (voltage)
Output range~1.2V (wet) -- ~2.8V (dry) at 3.3V supply
Sensing methodCapacitive (no exposed electrodes)
Corrosion resistanceHigh (sealed PCB)
InterfaceSingle analog pin

🔗Capacitive vs. Resistive Soil Moisture Sensors

FeatureCapacitive (recommended)Resistive
ElectrodesSealed inside PCBExposed metal prongs
CorrosionMinimalCorrodes quickly in wet soil
LifespanMonths to yearsDays to weeks
OutputAnalog voltageAnalog voltage
CostSlightly higherVery cheap
AccuracyModerateModerate (degrades as it corrodes)

If your sensor has two exposed metal prongs, you have a resistive sensor, not a capacitive one. Resistive sensors work fine for quick experiments but will degrade rapidly in continuously moist soil.

🔗What You'll Need

ComponentQtyNotesBuy
ESP32 dev board1AliExpress | Amazon.de .co.uk .com
Capacitive soil moisture sensor v1.21Capacitive type recommendedAliExpress | Amazon.de .co.uk .com
Breadboard1AliExpress | Amazon.de .co.uk .com
Jumper wires3AliExpress | Amazon.de .co.uk .com

Links marked Amazon/AliExpress are affiliate links. We may earn a small commission at no extra cost to you.

🔗Wiring

Sensor PinESP32 PinNotes
VCC3.3VPowers the sensor
GNDGNDCommon ground
AOUTGPIO 34Analog output to ADC1

Board variation note: Pin labels, GPIO numbers, and ADC channels vary between ESP32 boards. Always check your specific board's pinout diagram. The recommended starter board is the ESP32-WROOM-32 DevKit.

ADC pin selection matters. Use a GPIO on ADC1 (GPIOs 32--39) for reliable analog readings. ADC2 (GPIOs 0, 2, 4, 12--15, 25--27) conflicts with WiFi -- if you plan to use WiFi in your project (e.g., to send moisture data to a server), ADC2 pins will give incorrect readings while WiFi is active. GPIOs 34--39 are input-only, which is perfectly fine for reading a sensor.

🔗Required Libraries

None -- you only need the built-in analogRead() function.

🔗Code Example

This sketch reads the raw sensor value, calibrates it against known dry and wet values, and outputs a moisture percentage.

#define SOIL_PIN 34

// Calibration values -- measure these for YOUR sensor (see How It Works)
const int DRY_VALUE  = 2800;  // ADC reading in dry air
const int WET_VALUE  = 1200;  // ADC reading fully submerged in water

void setup() {
    Serial.begin(115200);
    Serial.println("Capacitive soil moisture sensor ready.");
}

void loop() {
    int rawValue = analogRead(SOIL_PIN);

    // Map raw ADC value to percentage (note: lower value = wetter)
    int moisturePercent = map(rawValue, DRY_VALUE, WET_VALUE, 0, 100);
    moisturePercent = constrain(moisturePercent, 0, 100);

    Serial.print("Raw: ");
    Serial.print(rawValue);
    Serial.print("  |  Moisture: ");
    Serial.print(moisturePercent);
    Serial.println("%");

    // Simple threshold-based detection
    if (moisturePercent < 20) {
        Serial.println("  >> Soil is very dry - water needed!");
    } else if (moisturePercent < 50) {
        Serial.println("  >> Soil moisture is moderate.");
    } else {
        Serial.println("  >> Soil is well-watered.");
    }

    delay(2000);
}

🔗How It Works

  1. Capacitive sensing -- The sensor works like a capacitor. The PCB traces form two plates, and the soil between and around them acts as the dielectric material. Water has a much higher dielectric constant (~80) than dry soil (~3--5), so when the soil is wet, the capacitance increases. The sensor circuit converts this capacitance change into an analog voltage.

  2. Calibration -- Every sensor unit is slightly different, so you need to calibrate yours. The process is simple:

    • Dry reading: Hold the sensor in dry air and note the ADC value. This is your DRY_VALUE.
    • Wet reading: Submerge the sensor up to the line marked on the PCB (do not submerge the electronics at the top) in a glass of water and note the ADC value. This is your WET_VALUE.
    • Use these two values to map() any reading to a 0--100% range.
  3. ADC conversion -- The ESP32's ADC reads values from 0 to 4095 (12-bit resolution). The sensor output voltage translates into this range. Note that the ESP32's ADC is not perfectly linear, especially near the extremes (close to 0V and 3.3V), but it is accurate enough for soil moisture monitoring.

  4. Why lower voltage = wetter -- As moisture increases, the sensor's capacitance rises, which lowers the output voltage. This feels counterintuitive, which is why the map() function in the code reverses the direction (DRY_VALUE maps to 0% and WET_VALUE maps to 100%).

Tip: The ESP32's ADC can be noisy. For more stable readings, take multiple samples and average them:

int readSmoothed(int pin, int samples) {
    long total = 0;
    for (int i = 0; i < samples; i++) {
        total += analogRead(pin);
        delay(10);
    }
    return total / samples;
}

🔗Troubleshooting

ProblemPossible CauseSolution
Readings do not change when inserting into soilSensor not inserted deep enoughPush the sensor in up to the marked line on the PCB
Readings do not changeWrong GPIO pin or broken sensorVerify wiring; try a different ADC1 pin
Readings fluctuate wildlyNoisy ADC or loose connectionsAverage multiple samples; secure wiring connections
Readings are always 0 or 4095Power not connected, or pin not on ADCCheck VCC and GND connections; verify GPIO is an ADC-capable pin
Sensor corrodes in soilYou have a resistive sensor, not capacitiveCapacitive sensors have no exposed metal contacts; replace with a true capacitive version
Readings incorrect when WiFi is onUsing an ADC2 pinSwitch to an ADC1 pin (GPIOs 32--39)
Dry and wet readings are very close togetherSensor is faulty or wrong supply voltageEnsure VCC is 3.3V; try a different sensor unit

🔗Next Steps

  • Build an automatic plant watering system: when moisture drops below a threshold, trigger a pump via a relay.
  • Log moisture data over WiFi to track how quickly your soil dries out between waterings.
  • Add a BME280 sensor to correlate soil moisture with temperature and humidity.
  • Create a multi-zone garden monitor with several sensors, each on a different ADC1 pin.
  • Display current moisture level on an OLED screen mounted near your plants.