In-Depth: How Soil Moisture Sensor Works and Interface it with Arduino

How Soil Moisture Sensor Works and Interface it with Arduino

When you hear the term “smart garden,” one of the first things that comes to mind is a system that monitors the moisture level of the soil and automatically supplies the necessary amount of water to the plants.

With this system, plants can be watered only when required, avoiding over- or under-watering.

If you want to build such a system, you will undoubtedly require a Soil Moisture Sensor.

How Does a Soil Moisture Sensor Work?

The soil moisture sensor operates in a straightforward manner.

The fork-shaped probe with two exposed conductors acts as a variable resistor (similar to a potentiometer) whose resistance varies with the soil’s moisture content.

soil moisture sensor working.gif

This resistance varies inversely with soil moisture:

  • The more water in the soil, the better the conductivity and the lower the resistance.
  • The less water in the soil, the lower the conductivity and thus the higher the resistance.

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

Hardware Overview

A typical soil moisture sensor consists of two parts.

The Probe

The sensor includes a fork-shaped probe with two exposed conductors that is inserted into the soil or wherever the moisture content is to be measured.

As previously stated, it acts as a variable resistor, with resistance varying according to soil moisture.

soil moisture sensor probe

The Module

In addition, the sensor includes an electronic module that connects the probe to the Arduino.

The module generates an output voltage based on the resistance of the probe, which is available at an Analog Output (AO) pin.

The same signal is fed to an LM393 High Precision Comparator, which digitizes it and makes it available at a Digital Output (DO) pin.

soil moisture sensor sensitivity adjustment

The module includes a potentiometer for adjusting the sensitivity of the digital output (DO).

You can use it to set a threshold, so that when the soil moisture level exceeds the threshold, the module outputs LOW otherwise HIGH.

This setup is very useful for triggering an action when a certain threshold is reached. For example, if the moisture level in the soil exceeds a certain threshold, you can activate a relay to start watering the plant.

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

soil moisture sensor power and status leds

The module also includes two LEDs. The Power LED illuminates when the module is turned on, and the Status LED illuminates when the soil moisture level exceeds the threshold value.

Soil Moisture Sensor Pinout

The soil moisture sensor is extremely simple to use and only requires four pins to connect.

soil moisture sensor pinout

AO (Analog Output) generates analog output voltage proportional to the soil moisture level, so a higher level results in a higher voltage and a lower level results in a lower voltage.

DO (Digital Output) indicates whether the soil moisture level is within the limit. D0 becomes LOW when the moisture level exceeds the threshold value (as set by the potentiometer), and HIGH otherwise.

VCC supplies power to the sensor. It is recommended that the sensor be powered from 3.3V to 5V. Please keep in mind that the analog output will vary depending on the voltage supplied to the sensor.

GND is the ground pin.

Experiment 1 – Measuring Soil Moisture using Analog Output (A0)

In our first experiment, we will read the analog output to estimate the level of soil moisture.

Wiring

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

Let’s begin by powering up the sensor. For this, you can connect the VCC pin of the module to Arduino’s 5V pin.

However, one well-known issue with these sensors is that they have a shorter lifespan because they are constantly exposed to moisture. Moreover, constantly applying power to the sensor while buried in soil significantly accelerates the rate of corrosion.

To avoid this, it is recommended that the sensor be turned on only when taking readings.

One easy way to do this is to connect the sensor’s power pin to a digital pin on an Arduino and set it to HIGH or LOW as needed. Also, the total power drawn by the module (with both LEDs lit) is about 8 mA, so powering the module from a digital pin is fine. So, we’ll connect the VCC pin to the Arduino’s digital pin #7.

Finally, connect the A0 pin to the Arduino’s A0 ADC pin.

The wiring is shown in the image below.

wiring soil moisture sensor with arduino for reading analog output

Finding the threshold values

To estimate the soil moisture level, record the values of your sensor output when the soil is as dry as possible and when it is completely saturated.

Keep in mind that your sensor may be more or less sensitive depending on the type of soil you use. Also, minerals dissolved in water from fertilizers and other sources can affect the sensor output.

Simply run the sketch below and take your readings.

// 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 should see readings similar to the ones below:

  • When the soil is dry (around 850)
  • When the soil is completely saturated (around 400)
calibrating soil moisture sensor

This test may require some trial and error. Once you have the readings, you can use them as a threshold to trigger an action.

Arduino Code

The sketch below estimates the level of soil moisture using the following threshold values:

  • < 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 something similar on the serial monitor.

soil moisture sensor analog output

Experiment 2 – Measuring Soil Moisture using Digital Output (D0)

In our second experiment, we will use digital output to determine whether the soil moisture level is within acceptable limits.

Wiring

We’ll reuse the previous experiment’s circuit. Simply disconnect the connection to the ADC pin and connect the D0 pin on the module to the Arduino’s digital pin #8.

The following image shows the wiring.

wiring soil moisture sensor with arduino for reading digital output

Setting the threshold

The module has a built-in potentiometer for setting the moisture level threshold above which the module outputs LOW and the status LED lights up.

digital output of soil moisture sensor

Now, to set the threshold, stick the probe into the soil when your plant needs watering and turn the pot clockwise until the Status LED is on. Then, turn the pot back counterclockwise just until the LED goes off.

That’s all there is to it; your module is now ready to use.

Arduino Code

Now, upload the sketch below 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
}

You should see similar output on the serial monitor.

soil moisture sensor digital output