How Soil Moisture Sensor Works and Interface it with Arduino

When you hear the term ‘smart garden’, one of the things that comes to your mind is a system that measures soil moisture and irrigates your plants automatically.

With this type of system, you can water your plants only when needed and avoid over-watering or under-watering.

If you want to build such a system then you will definitely need a Soil Moisture Sensor.

How Soil Moisture Sensor works?

The working of the soil moisture sensor is pretty straightforward.

The fork-shaped probe with two exposed conductors, acts as a variable resistor (just like a potentiometer) whose resistance varies according to the water content in the soil.

soil moisture sensor working.gif

This resistance is inversely proportional to the soil moisture:

  • The more water in the soil means better conductivity and will result in a lower resistance.
  • The less water in the soil means poor conductivity and will result in a higher resistance.

The sensor produces an output voltage according to the resistance, which by measuring we can determine the moisture level.

Hardware Overview

A typical soil moisture sensor has two components.

The Probe

The sensor contains a fork-shaped probe with two exposed conductors that goes into the soil or anywhere else where the water content is to be measured.

Like said before, it acts as a variable resistor whose resistance varies according to the soil moisture.

soil moisture sensor probe

The Module

The sensor also contains an electronic module that connects the probe to the Arduino.

The module produces an output voltage according to the resistance of the probe and is made available at an Analog Output (AO) pin.

The same signal is fed to a LM393 High Precision Comparator to digitize it and is made available at an Digital Output (DO) pin.

soil moisture sensor sensitivity adjustment

The module has a built-in potentiometer for sensitivity adjustment of the digital output (DO).

You can set a threshold by using a potentiometer; So that when the moisture level exceeds the threshold value, the module will output LOW otherwise HIGH.

This setup is very useful when you want to trigger an action when certain threshold is reached. For example, when the moisture level in the soil crosses a threshold, you can activate a relay to start pumping water. You got the idea!

Tip: Rotate the knob clockwise to increase sensitivity and counterclockwise to decrease it.

soil moisture sensor power and status leds

Apart from this, the module has two LEDs. The Power LED will light up when the module is powered. The Status LED will light up when the digital output goes LOW.

Soil Moisture Sensor Pinout

The soil moisture sensor is super easy to use and only has 4 pins to connect.

soil moisture sensor pinout

AO (Analog Output) pin gives us an analog signal between the supply value to 0V and will be connected to one of the analog inputs on your Arduino.

DO (Digital Output) pin gives Digital output of internal comparator circuit. You can connect it to any digital pin on an Arduino or directly to a 5V relay or similar device.

VCC pin supplies power for the sensor. It is recommended to power the sensor with between 3.3V – 5V. Please note that the analog output will vary depending on what voltage is provided for the sensor.

GND is a ground connection.

Sensing Soil Moisture using Analog Output

As you know that the module provides both analog and digital output, so for our first experiment we will measure the soil moisture by reading the analog output.

Wiring

Let’s hook the soil moisture sensor up to the Arduino.

First you need to supply power to the sensor. For that you may connect the VCC pin on the module to 5V on the Arduino.

However, one commonly known issue with these sensors is their short lifespan when exposed to a moist environment. Having power applied to the probe constantly speeds the rate of corrosion significantly.

To overcome this, we recommend that you do not power the sensor constantly, but power it only when you take the readings.

An easy way to accomplish this is to connect the VCC pin to a digital pin of an Arduino and set it to HIGH or LOW as per your requirement.

Also the total power drawn by the module (with both LEDs lit) is about 8 mA, so it is okay to power the module off a digital pin on an Arduino.

So, let’s connect the VCC pin on the module to the digital pin #7 of an Arduino and GND pin to ground.

Finally, connect the AO pin on the module to the A0 ADC pin on your Arduino.

The following illustration shows the wiring.

wiring soil moisture sensor with arduino for reading analog output

Calibration

To get accurate readings out of your soil moisture sensor, it is recommended that you first calibrate it for the particular type of soil that you plan to monitor.

Different types of soil can affect the sensor, so your sensor may be more or less sensitive depending on the type of soil you use.

Before you start storing data or triggering events, you should see what readings you are actually getting from your sensor.

Use the below sketch to note what values your sensor outputs when the soil is as dry as possible -vs- when it is completely saturated with moisture.

// Sensor pins
#define sensorPower 7
#define sensorPin A0

void setup() {
	pinMode(sensorPower, OUTPUT);
	
	// Initially keep the sensor OFF
	digitalWrite(sensorPower, LOW);
	
	Serial.begin(9600);
}

void loop() {
	//get the reading from the function below and print it
	Serial.print("Analog output: ");
	Serial.println(readSensor());
	
	delay(1000);
}

//  This function returns the analog soil moisture measurement
int readSensor() {
	digitalWrite(sensorPower, HIGH);	// Turn the sensor ON
	delay(10);							// Allow power to settle
	int val = analogRead(sensorPin);	// Read the analog value form sensor
	digitalWrite(sensorPower, LOW);		// Turn the sensor OFF
	return val;							// Return analog moisture value
}

When you run the sketch, you’ll see the close to the following readings in the serial monitor:

  • when the soil was dry (~850)
  • when the soil was completely wet (~400)
calibrating soil moisture sensor

This test may take some trial and error. Once you get a good handle on these readings, you can use them as threshold if you intend to trigger an action.

Final Build

Based on the calibration values, the program below defines the following ranges to determine the status of the soil:

  • < 500 is too wet
  • 500-750 is the target range
  • > 750 is dry enough to be watered
/* Change these values based on your calibration values */
#define soilWet 500   // Define max value we consider soil 'wet'
#define soilDry 750   // Define min value we consider soil 'dry'

// Sensor pins
#define sensorPower 7
#define sensorPin A0

void setup() {
	pinMode(sensorPower, OUTPUT);
	
	// Initially keep the sensor OFF
	digitalWrite(sensorPower, LOW);
	
	Serial.begin(9600);
}

void loop() {
	//get the reading from the function below and print it
	int moisture = readSensor();
	Serial.print("Analog Output: ");
	Serial.println(moisture);

	// Determine status of our soil
	if (moisture < soilWet) {
		Serial.println("Status: Soil is too wet");
	} else if (moisture >= soilWet && moisture < soilDry) {
		Serial.println("Status: Soil moisture is perfect");
	} else {
		Serial.println("Status: Soil is too dry - time to water!");
	}
	
	delay(1000);	// Take a reading every second for testing
					// Normally you should take reading perhaps once or twice a day
	Serial.println();
}

//  This function returns the analog soil moisture measurement
int readSensor() {
	digitalWrite(sensorPower, HIGH);	// Turn the sensor ON
	delay(10);							// Allow power to settle
	int val = analogRead(sensorPin);	// Read the analog value form sensor
	digitalWrite(sensorPower, LOW);		// Turn the sensor OFF
	return val;							// Return analog moisture value
}

If everything is fine, you should see below output on serial monitor.

soil moisture sensor analog output

Sensing Soil Moisture using Digital Output

For our second experiment we will determine the status of the soil by using the digital output.

Wiring

We’ll use the circuit from the previous example. This time we just need to remove the connection to ADC pin and connect DO pin on the module to the digital pin #8 on the Arduino.

Hook up your circuit as pictured below:

wiring soil moisture sensor with arduino for reading digital output

Calibration

The module has a built-in potentiometer for calibrating the digital output (DO).

By turning the knob of the potentiometer, you can set a threshold. So that when the moisture level exceeds the threshold value, the Status LED will light up and the module will output LOW.

digital output of soil moisture sensor

Now to calibrate the sensor, insert the probe into the soil when your plant is ready to be watered and adjust the pot clockwise so that the Status LED is ON and then adjust the pot back counterclockwise just until the LED goes OFF.

That’s it your sensor is now calibrated and ready for use.

Arduino Code

Once the circuit is built, upload the following sketch to your Arduino.

// Sensor pins
#define sensorPower 7
#define sensorPin 8

void setup() {
	pinMode(sensorPower, OUTPUT);

	// Initially keep the sensor OFF
	digitalWrite(sensorPower, LOW);

	Serial.begin(9600);
}

void loop() {
	//get the reading from the function below and print it
	int val = readSensor();
	Serial.print("Digital Output: ");
	Serial.println(val);

	// Determine status of our soil moisture situation
	if (val) {
		Serial.println("Status: Soil is too dry - time to water!");
	} else {
		Serial.println("Status: Soil moisture is perfect");
	}

	delay(1000);	// Take a reading every second for testing
					// Normally you shoul take reading perhaps every 12 hours
	Serial.println();
}

//  This function returns the analog soil moisture measurement
int readSensor() {
	digitalWrite(sensorPower, HIGH);  // Turn the sensor ON
	delay(10);              // Allow power to settle
	int val = digitalRead(sensorPin); // Read the analog value form sensor
	digitalWrite(sensorPower, LOW);   // Turn the sensor OFF
	return val;             // Return analog moisture value
}

If everything is fine, you should see below output on serial monitor.

soil moisture sensor digital output