Documentation

Capacitive Soil Moisture Sensor V1.2 | ShillehTek Product Manual
Documentation / Capacitive Soil Moisture Sensor V1.2 | ShillehTek Product Manual

Capacitive Soil Moisture Sensor V1.2 | ShillehTek Product Manual

manualshillehtek

Overview

The Capacitive Soil Moisture Sensor V1.2 is a low-cost, hobby-friendly probe that measures how wet or dry your soil is. Unlike older resistive moisture sensors that use two exposed metal prongs, this one uses capacitive sensing, so there is no direct electrical contact between the probe and the soil. That single design change solves the biggest headache of resistive sensors: corrosion. Resistive probes literally electrolyze themselves into oblivion after a few weeks in damp soil, while capacitive probes can sit in a planter for months and keep reading.

Electrically the sensor is dead simple. It outputs an analog voltage on the AOUT pin. In dry air the output sits near ~2.5V, and when the probe is submerged in water it drops to around ~1.0V. The drier the soil, the higher the voltage; the wetter the soil, the lower the voltage. You read that voltage with any microcontroller ADC and either use the raw value or map it to a 0-100% scale after calibrating in air and water.

This makes it perfect for plant-watering reminders, automated irrigation projects, greenhouse data loggers, ESP32-based smart pots that ping your phone when the basil is thirsty, or just classroom electronics experiments. Power it from 3.3V or 5V, plug AOUT into an analog input, and you have a working soil sensor in under five minutes.

At a Glance

Sensing Type
Capacitive (no corrosion)
Output
Analog voltage (AOUT)
Supply Voltage
3.3V - 5.5V DC
Interface
3-pin: VCC, GND, AOUT
Dry vs Wet
~2.5V dry, ~1.0V wet
Best For
Plants, irrigation, IoT

Specifications

Parameter Value
Operating Voltage 3.3V - 5.5V DC
Operating Current ~5 mA
Output Type Analog voltage
Output Range (Dry) ~2.5V (in open air)
Output Range (Wet) ~1.0V (fully submerged)
Onboard Regulator Yes (stabilizes 3.3V-5V input)
Connector 3-pin JST / dupont header (VCC, GND, AOUT)
Probe Material Corrosion-resistant PCB substrate
Operating Temp 0°C to 60°C
PCB Length ~98 mm
PCB Width ~23 mm
Weight ~15 g

Pinout Diagram

Capacitive Soil Moisture Sensor V1.2 pinout showing GND, VCC, AOUT analog output pins and warning line indicating max insertion depth.
Important: Do not insert the sensor past the white warning line printed on the board. Only the bare PCB area below the line is meant to be in soil. The chip and connector at the top should never get wet, or you will short out the sensor.

Wiring Guide

Arduino Wiring

Arduino Uno/Nano/Mega have a 10-bit ADC built in, so wiring is as simple as it gets — three wires and you're reading soil moisture.

Sensor Pin Arduino Pin
VCC 5V
GND GND
AOUT A0
Tip: Power the sensor from 5V on Arduino Uno boards — you'll get the cleanest ~2.5V dry / ~1.0V wet swing on a 10-bit ADC.

ESP32 Wiring

ESP32 has multiple ADC-capable pins. GPIO34 is input-only and a great pick for analog sensors because there's no risk of accidentally driving it as an output.

Sensor Pin ESP32 Pin
VCC 3.3V
GND GND
AOUT GPIO34 (ADC1_CH6)
Tip: Stay on ADC1 pins (GPIO32-39) if you also use Wi-Fi. ADC2 pins are unreliable while the radio is active.

Raspberry Pi Wiring

The Raspberry Pi has no built-in ADC, so you need an external analog-to-digital converter like the MCP3008 (SPI) or ADS1115 (I2C). Below is wiring with an MCP3008.

Sensor Pin Connection
VCC Pi 3.3V (pin 1)
GND Pi GND (pin 6)
AOUT MCP3008 CH0

And the MCP3008 to Pi:

MCP3008 Pin Pi Pin
VDD / VREF 3.3V
AGND / DGND GND
CLK GPIO11 (SCLK)
DOUT GPIO9 (MISO)
DIN GPIO10 (MOSI)
CS GPIO8 (CE0)
Tip: Enable SPI with sudo raspi-config before wiring.

Raspberry Pi Pico Wiring

The Pico has three usable ADC channels on GP26, GP27, and GP28. Pick any of them.

Sensor Pin Pico Pin
VCC 3V3 (OUT) — pin 36
GND GND — pin 38
AOUT GP26 / ADC0 — pin 31
Tip: The Pico ADC is 12-bit (0-4095). Adjust your calibration math accordingly.

Code Examples

Arduino

soil_moisture.ino
// Capacitive Soil Moisture Sensor V1.2 - Arduino
// AOUT -> A0, VCC -> 5V, GND -> GND

const int SOIL_PIN = A0;

// Calibrate these for your sensor + soil:
const int DRY_VALUE = 590;  // raw ADC reading in dry air
const int WET_VALUE = 250;  // raw ADC reading fully submerged

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

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

  // Constrain and map to 0-100% (higher = wetter)
  int clamped = constrain(raw, WET_VALUE, DRY_VALUE);
  int percent = map(clamped, DRY_VALUE, WET_VALUE, 0, 100);

  Serial.print("Raw: ");
  Serial.print(raw);
  Serial.print("  Moisture: ");
  Serial.print(percent);
  Serial.println("%");

  delay(1000);
}

ESP32

soil_moisture_esp32.ino
// Capacitive Soil Moisture Sensor V1.2 - ESP32
// AOUT -> GPIO34, VCC -> 3.3V, GND -> GND

const int SOIL_PIN = 34;

// 12-bit ADC: 0-4095. Calibrate these:
const int DRY_VALUE = 3000;
const int WET_VALUE = 1200;

void setup() {
  Serial.begin(115200);
  analogReadResolution(12);
  analogSetAttenuation(ADC_11db); // full 0-3.3V range
}

void loop() {
  int raw = analogRead(SOIL_PIN);
  int clamped = constrain(raw, WET_VALUE, DRY_VALUE);
  int percent = map(clamped, DRY_VALUE, WET_VALUE, 0, 100);

  Serial.printf("Raw: %d  Moisture: %d%%\n", raw, percent);
  delay(1000);
}

Raspberry Pi (Python)

soil_moisture.py
# Capacitive Soil Moisture Sensor V1.2 - Raspberry Pi
# Requires an MCP3008 ADC over SPI.
# pip install adafruit-circuitpython-mcp3xxx

import time
import board
import busio
import digitalio
from adafruit_mcp3xxx.mcp3008 import MCP3008
from adafruit_mcp3xxx.analog_in import AnalogIn

spi = busio.SPI(clock=board.SCK, MISO=board.MISO, MOSI=board.MOSI)
cs = digitalio.DigitalInOut(board.D8)
mcp = MCP3008(spi, cs)
chan = AnalogIn(mcp, 0)  # MCP3008 CH0

# Calibrate (0-65535 scale from adafruit lib)
DRY_VALUE = 48000
WET_VALUE = 20000

while True:
    raw = chan.value
    clamped = max(WET_VALUE, min(DRY_VALUE, raw))
    percent = int((DRY_VALUE - clamped) * 100 / (DRY_VALUE - WET_VALUE))
    print(f"Raw: {raw}  Voltage: {chan.voltage:.2f}V  Moisture: {percent}%")
    time.sleep(1)

Raspberry Pi Pico (MicroPython)

soil_moisture_pico.py
# Capacitive Soil Moisture Sensor V1.2 - Pico (MicroPython)
# AOUT -> GP26 (ADC0), VCC -> 3V3, GND -> GND

from machine import ADC, Pin
import time

soil = ADC(Pin(26))

# 16-bit value on Pico (read_u16). Calibrate:
DRY_VALUE = 50000
WET_VALUE = 22000

while True:
    raw = soil.read_u16()
    clamped = max(WET_VALUE, min(DRY_VALUE, raw))
    percent = int((DRY_VALUE - clamped) * 100 / (DRY_VALUE - WET_VALUE))
    print("Raw:", raw, " Moisture:", percent, "%")
    time.sleep(1)

Frequently Asked Questions

How do I calibrate the sensor?
Run your code with the probe in open, dry air and write down the raw ADC value — that's your DRY_VALUE. Then submerge the probe up to (but not past) the warning line in a glass of water and write down that raw value — that's your WET_VALUE. Plug both into your code. Recalibrate if you move to drastically different soil types.
Why does my reading drift over time?
Capacitive sensors can drift slightly with temperature and supply voltage. Power it from a regulated supply (not directly from a USB port being shared with motors), and consider re-calibrating seasonally if it's outdoors.
Can I leave it in soil 24/7?
Yes — that's the main selling point. Just make sure only the lower PCB (below the warning line) is in soil and the top with the chip and connector stays dry. For outdoor use, seal the top half with hot glue or heat-shrink.
Why does my Raspberry Pi need an extra chip?
The Pi has no analog inputs — only digital GPIO. The MCP3008 (SPI) or ADS1115 (I2C) gives it ADC channels. The Pico, ESP32, and all Arduino boards have built-in ADCs and don't need one.
3.3V or 5V — which should I use?
Both work. Use 5V with Arduino Uno-class boards (their ADC reference is 5V) and 3.3V with ESP32, Pico, and Raspberry Pi to match their logic levels. The onboard regulator handles either.
Higher voltage = wetter or drier?
Higher voltage = drier. The probe outputs ~2.5V in dry air and drops toward ~1.0V as it gets wetter. So in your code, a lower raw ADC reading means wetter soil.
Can I trigger a pump or valve from this?
Absolutely — that's a classic project. Read the moisture percentage, and when it drops below a threshold (say, 30%), turn on a relay/MOSFET driving a small water pump. Just don't drive the pump directly from a GPIO; always use a transistor or relay module.