Soil moisture sensors are one of the first things people connect to an Arduino, and one of the first to disappoint. The reading drifts, the probe is green after a month, or the number means nothing. Almost all of this comes from two choices: which type of sensor you buy, and whether you calibrate it.

Resistive and capacitive sensors

There are two common kinds, and they look similar on a product page.

Resistive

Two exposed metal prongs. The sensor passes a small current between them through the soil, and wetter soil conducts better. It is cheap and simple, and it does not last. Current flowing through wet soil makes the metal corrode, the prongs get coated, and readings drift within weeks. Powering the probe only while you take a reading slows the damage but does not stop it.

Capacitive

A flat board with the metal sealed under a coating. The sensor measures how the soil changes an electric field, and nothing touches the soil directly, so there is nothing to corrode. This is the type to buy. It costs about the same as a resistive probe and can last for years.

Two cautions with capacitive boards. The edges of the board are usually not sealed, and soil water creeping into them shortens the sensor's life. Coating the edges with nail varnish or a bit of clear sealant helps. And do not bury the electronics part of the board, only the probe section below the marked line.

Wiring

A capacitive probe has three pins: power, ground and signal. Connect them like this.

Probe pinConnects to
VCC3.3 V on an ESP32, 5 V or 3.3 V on an Uno depending on your probe
GNDGND
AOUT or signalAn analog input pin

Check the printing on your own board, because versions differ. With an ESP32, never feed more than 3.3 V into an analog pin.

The ESP32 analog pin trap

The ESP32 has two analog converters, ADC1 and ADC2. ADC2 cannot be used while Wi-Fi is switched on, and the pins that belong to it return errors or zeros. If your sensor works in a test sketch and fails once you add Wi-Fi, this is the usual reason. Use an ADC1 pin: 32, 33, 34, 35, 36 or 39.

Reading raw values

Start by printing the raw number so you can see what your probe does.

const int SENSOR_PIN = 34;

void setup() {
  Serial.begin(115200);
}

void loop() {
  Serial.println(analogRead(SENSOR_PIN));
  delay(1000);
}

On an Uno the numbers run from 0 to 1023. On an ESP32 they run from 0 to 4095. With most capacitive probes, a drier sensor gives a higher number and a wetter one gives a lower number. That feels backwards the first time, and it is normal.

Calibrate in two minutes

  1. Hold the probe in the air, away from your hand, and note the steady number. This is your dry value.
  2. Stand the probe in a glass of water up to the marked line and note the number. This is your wet value.
  3. Put both numbers into the sketch and convert to a percentage.
const int DRY_VALUE = 2900;   // your number from step 1
const int WET_VALUE = 1300;   // your number from step 2

int moisturePercent(int raw) {
  return constrain(map(raw, DRY_VALUE, WET_VALUE, 0, 100), 0, 100);
}

The result is the position between your two points. It is a good measure of change, which is what you need for watering decisions. It is not a lab measurement of the water in the soil, and sand and clay will both read differently at the same real wetness.

Smooth the readings

Analog readings are noisy. Averaging a handful of samples removes most of it.

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

Test it in real soil too

Water is a useful extreme, but real soil rarely reads 100 percent. Push the probe into a freshly watered pot and note the number. Then let the pot dry for a few days and note it again. Those two soil readings are the ones you will use to decide when to water, and they are often a more useful pair than the water and air numbers.

Getting it online

Once the number makes sense on the serial monitor, send it to a dashboard so you can see it without a cable. The next guide has a complete sketch: send ESP32 or Arduino sensor data to a website. If you want the gardening side, such as where to put the probe and how to read the chart, see how to monitor soil moisture remotely.