Skip to Content

How To Use A Capacitive Soil Moisture Sensor With Arduino

How To Use A Capacitive Soil Moisture Sensor With Arduino

In this tutorial you will learn how to use a Capacitive Soil Moisture Sensor with an Arduino to monitor the watering needs of your plants.

Overwatering can lead to root rot, nutrient leaching, and reduced oxygen levels in the soil, which can suffocate the roots. While underwatering can cause wilting, stunted growth, and nutrient deficiencies in plants.

A Capacitive Soil Moisture Sensor measures the volumetric water content in the soil, giving a more precise indication of when to water the plants. This helps in avoiding water stress or root rot, which can occur if the soil moisture levels are not optimal. By monitoring soil moisture, you can adjust your watering schedule based on the actual needs of the plants, leading to healthier and more productive growth.

Let’s get started with the required parts.

Required Parts

Apart from the Sensor you will need an Arduino or other microcontroller. I used an Arduino Uno but any other Arduino, ESP32 or ESP8266 will work as well, since the sensor operates on 3.3V or 5V.

Capacitive Soil Moisture Sensor

Arduino

Arduino Uno

Dupont wire set

Dupont Wire Set

Half_breadboard56a

Breadboard

USB Data Sync cable Arduino

USB Cable for Arduino UNO

Makerguides.com is a participant in the Amazon Services LLC Associates Program, an affiliate advertising program designed to provide a means for sites to earn advertising fees by advertising and linking to products on Amazon.com. As an Amazon Associate we earn from qualifying purchases.

Function of a Capacitive Moisture Sensor

A Capacitive Soil Moisture Sensor measures soil moisture by utilizing the principle of capacitance. The sensor probe consists of two electrodes – a positive and a negative electrode. When inserted into the soil, the moisture content in the soil acts as a dielectric material between the electrodes, forming a capacitor. If you look closely you can actually see the two electrodes of the sensor. In the following picture they are highlighted in yellow:

Electrodes of Capacitive Moisture Sensor
Electrodes of Capacitive Moisture Sensor

An NE555 (or TL555C) timer chip is used in the sensor electronics to generate a square wave signal. This signal is applied to one of the electrodes, creating an electric field between the electrodes. The moisture in the soil affects the capacitance of the sensor, which in turn affects the charging time of the capacitor.

When the soil is dry, the capacitor has a smaller capacitance and therefore charges more quickly. When the soil is wet, the capacitor has a larger capacitance and charges more slowly.

These charging cycles are rectified by a diode and integrated by another capacitor to produce a analog voltage at the output pin AOUT. The voltage is proportional to the moisture of the soil and can be read by an analog input of an Arduino to create a soil moisture reading.

The picture below shows the schematics of a Capacitive Soil Moisture Sensor. You can see the frequency generator circuit with the timer IC, the RC circuit representing the probe that acts as a low pass filter and the smoothing circuit, which create the analog output voltage.

Schematics of a  Capacitive Soil Moisture Sensor
Schematics of a Capacitive Soil Moisture Sensor

The voltage regulator (LDO) ensures a constant voltage for the circuit, independent of the supply voltage. For more details about the function of this circuit, have a look at the excellent tutorial: Interfacing Capacitive Soil Moisture Sensor with Arduino by LastMinuteEngineers.

Pinout

The Capacitive Moisture Sensor comes with 3-pin JST PH2.0 type connector and a cable that ends in a Dupont 3-pin female connector. The 3 pins of the connector are for the supply voltage (VCC), ground (GND) and the analog output (AOUT).

Pinout of Capacitive Moisture Sensor
Pinout of Capacitive Moisture Sensor

The supply voltage can range between 3.3V and 5.5V with an operating current < 5mA.

The output pin AOUT produces an analog voltage that is proportional to the amount of moisture in the soil. Nominally that voltage is between 1.5V and 3V. I measured 1.26V in water and 2.24V in air for a 5V supply voltage.

Note that these simple sensors are not calibrated and we will need to convert the raw sensor signal into a percentage moisture level ourselves.

Tips & Tricks using Capacitive Moisture Sensors

In this section I give you some tips & tricks on what to watch out when buying and using these sensors.

Models

There are many different versions or models of this Capacitive Soil Moisture Sensor with some of them not operating properly or according to specification. There are three common issues:

  • Missing voltage regulator
  • NE555 instead of TL555C
  • Disconnected resistor

The picture below shows you where in the schematics these issues are located

Schematics of a  Capacitive Soil Moisture Sensor with Issues
Schematics of a Capacitive Soil Moisture Sensor with Issues

Missing voltage regulator

Some models replace the voltage regulator (LDO) by a resistor. This causes the output voltage AOUT to be dependent on the supply voltage (VCC). Also any fluctuations in the supply voltage will cause fluctuations in AOUT. You can identify these models by the resistor that replaces the voltage regulator.

Capacitive Soil Moisture Sensor with missing Voltage Regulator
Capacitive Soil Moisture Sensor with missing Voltage Regulator

You can see the three pads for the voltage regulator. Two of them are bridged by a resistor (diagonal element), instead of being connected to the three pins of a voltage regulator.

NE555 instead of TL555C

Some boards use an NE555 timer chip that has a specified minimum supply voltage of 4.5V. With a 3.3V voltage regulator on the board the timer chip receives only 3.3V. Luckily, in many cases the chip still works even with the lower voltage. I have several of the Capacitive Soil Moisture Sensors with the NE555 and they work fine with 5V or 3.3V power supply. The following picture shows a board with the NE555 chip:

Capacitive Soil Moisture Sensor with NE555
Capacitive Soil Moisture Sensor with NE555

However, the better option is the TL555C timer IC, which is designed for 3.3V and will operate more reliably. Definitely favour Capacitive Soil Moisture Sensors with the TL555C chip, since the ones with the NE555 may not work at all.

Disconnected resistor

Finally, some board are wired incorrectly and the 1MOhms discharge resistor in the output path is not connected. This causes the sensor to react very slowly to changes in moisture.

You can recognize these board by a through hole between capacitor C4 and resistor R4 as shown below.

Capacitive Soil Moisture Sensor with disconnected Resistor

These are sensor boards you should avoid buying. While they sort-of work and the slow reaction time is not a a major problem when monitoring plants, it is still annoying.

Electromagnetic Interference

Since the Capacitive Soil Moisture Sensors measure the capacitance of their surroundings and since their electrodes work similar to an antenna, they are not impacted by moisture only. Metallic objects or electromagnetic fields emitted from power supplies, wireless chargers and more will affect the sensor reading as well.

Most importantly, Capacitive Soil Moisture Sensors will interact with each other when close to each other. If you place two or more sensors in the same plant pot, for instance to measure soil moisture at different depths or locations, make sure not too place the sensors right next to each other.

Finally, the ambient temperature, the salinity of the water, the granularity and density of the soil surrounding the probe are other factors that will affect the sensor readings. For more details have read of the excellent tutorial Hacking a Capacitive Soil Moisture Sensor (v1.2) for Frequency Output.

Positioning

The most important parameter when placing (and calibrating) the sensor is, how deep the sensor sits in the soil. You can easily test this with a glass of water. Immerse the sensor more or less in the water and the sensor output will change!

For this reason, and to protect the electronics, most sensors have a marking (a white line) that shows the maximum depth. See the picture below.

Max. depth marking on Capacitive Moisture Sensor
Max. depth marking on Capacitive Moisture Sensor

For consistent readings between sensors or of the same sensor you must make sure the insertion depth is always the same. Otherwise readings will vary wildly and are not a good indicator for moisture levels anymore. Obviously, never push the sensor completely into the soil beyond the maximum depth marking.

Water Proofing

The electronics of these cheap Capacitive Soil Moisture Sensors is completely exposed. While this is perfectly save due to the low voltage involved, the electronics will corrode and fail fairly quickly in a moist and dirty environment such as a plant pot.

Furthermore, the sensor circuit is printed on a PCB with exposed edges. The PCB will absorb water, which will cause the board to swell and deform. More importantly, water within the PCB will obviously interfere with the readings of the soil moisture.

The simplest solution to water-proof your sensors is to place them in a plastic bag. Though you probably still have a problem with condensation and it is not very elegant.

Capacitive Moisture Sensor in plastic bag
Capacitive Moisture Sensor in plastic bag

I sprayed my sensors with a clear coat of paint and they are still working fine but I haven’t done any long term testing yet. Before, spraying or any other coating, I suggest you sand the edges, since they are very rough, which will make it difficult to seal them properly.

Whatever you use for sealing (super glue, nail polish,  PlastiDip, …), the edges of the PCB need to be sealed perfectly, since the probe will sit in wet soil for months.

There a several tutorials that describe different methods for water-proofing. Have a look at Waterproofing a Capacitance Soil Moisture Sensor, Tutorial: Waterproofing your Capacitive Moisture Sensors and Protecting Capacitive Soil Moisture Sensors.

Connecting the Capacitive Moisture Sensor to an Arduino

Connecting a Capacitive Moisture Sensor to an Arduino is very simple. Just connect VCC of the Sensor to 5V, GND to GND, and the output AOUT to A0 of the Arduino. The picture below shows the complete wiring.

Connecting Capacitive Moisture Sensor to Arduino
Connecting Capacitive Moisture Sensor to Arduino

In the next section we write the code to read the measured moisture level from the Sensor.

Code to measure with the Capacitive Moisture Sensor

We start with some very simple code to test the sensor. We simply read the raw value we get at the analog input A0 and print it to the Serial Monitor:

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

void loop() {
  int val = analogRead(A0);  
  Serial.println(val);
  delay(1000);
}

If you run this code, open the Serial plotter and then grab and squeeze the Sensor tightly, you should see something like the following curve:

Sensor value when grabbing Capacitive Sensor
Sensor value when grabbing Capacitive Sensor

Since the human body and therefore your hand contain water, the sensor will react similar to moist soil. There is no need to immerse the sensor into water for testing.

As you can see the raw sensor value, when the sensor is in the air is around 438. When I squeeze the sensor tightly it drops down to 225. So, you can actually use a Capacitive Moisture Sensor as a touch or even hand pressure sensor.

Calibrate Capacitive Moisture Sensor

The minimum and maximum raw values will depend on the analog-digital-converter (ADC) of your microcontroller, your sensor model and might even slightly vary between sensors of the same model. Also the raw values are not very intuitive. We preferably want to calibrate our sensor to provide moisture readings in percent, with 100% in water and 0% in dry air.

The following code takes the raw values and maps them to a range from 0% to 100%:

const int valAir = 440;
const int valWater = 200;

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

void loop() {
  int val = analogRead(A0);
  int percent = map(val, valAir, valWater, 0, 100);
  percent = constrain(percent, 0, 100);
  Serial.println(percent);
  delay(1000);
}

For this mapping, we need to know the raw values for the sensor in air and in water. In the code above you can see the raw value for air is stored in the constant valAir and the one for water in the constant valWater. Then we can use the map() function to convert the raw sensor value into a percentage.

However, even after mapping the percentage value may be slightly lower than 0% or higher than 100% due to senor drift, different position of the sensor, or simply none perfect values for the valAir and valWater constants. To ensure the 0…100% range we also call the constraint() function.

To calibrate the sensor, you need to measure the raw value, when the sensor is in air and when the sensor is immersed in water – more about that later. After calibration I get the following output on the Serial Plotter, when squeezing the sensor very tightly with my hand. You can see that the measured percentage varies between 0% (air) and around 90% (in hand). If I immerse the sensor in water, the reading shows the full 100%.

Moisture measurement when grabbing Capacitive Sensor
Moisture measurement when grabbing Capacitive Sensor

Insertion depth

Determining the raw value in water is actually quite tricky, since it depends on how deeply you push the sensor into the water. Most of the Capacitive Moisture Sensor have white marking that indicates the maximal insertion depth.

You definitely don’t want to go beyond that mark, since then the electronics will get wet. You can put your own depth marking on the sensor but you have to use it consistently and have to align the water level with the marking when calibrating for 100%.

Calibrating Capacitive Moisture Sensor in Water
Calibrating Capacitive Moisture Sensor in Water

If you place the sensor at a different levels in the plant pot, you will either never be able to reach 100% or you will reach 100% at lower moisture levels.

Improved resolution for the Capacitive Moisture Sensor

The analog-digital-converter (ADC) of an Arduino Uno has a resolution of 10 bits, which means for input voltages between 0 and 5V it will produce raw values between 0 and 2023.

However, if you look at the raw sensor readings we get for the sensor in air or water, they are between 200 and 440. So the resolution is only 240 steps, compared to the 2023 the ADC is capable of. The reason is that the Capacitive Moisture Sensor produces voltages from 1.26V to 2.24V and not from 0..5V. That is what I measured for my sensor. Depending on the sensor model you may see different values.

Using AREF

We can get a better resolution by telling the ADC that the maximum input voltage is not 5V but something lower. This is done by providing that maximum voltage at the AREF pin, which the ADC internally uses for scaling.

You could use a potentiometer to build a voltage divider, which would allow you to adjust the AREF voltage at 2.24V or whatever your maximum voltage is. But this is a bit of an overkill. We usually don’t need that much accuracy. A simple solution is to connect AREF to the 3.3V pin of the Arduino, as shown in the image below:

AREF for higher resolution of Capacitive Moisture Sensor
AREF for higher resolution of Capacitive Moisture Sensor

That is an easy way to get a higher resolution, albeit not the full resolution. With AREF = 3.3V and after calibrating the sensor again in air and water, I get the following, new constants:

const int valAir = 690;  
const int valWater = 380;

That is a 22% increase in resolution (1- (440-200)/(690-380))). However, we have also have to change the code slightly. To tell the ADC to use AREF you have to call analogReference(EXTERNAL) in the setup() function:

// Using AREF = 3.3V
const int valAir = 690;  
const int valWater = 380;

int toPercent(int val) {
  int percent = map(val, valAir, valWater, 0, 100);
  return constrain(percent, 0, 100);
}

void setup() {
  Serial.begin(9600);
  analogReference(EXTERNAL); // Using AREF!
}

void loop() {
  int val = analogRead(A0);
  Serial.println(toPercent(val));
  delay(1000);
}

To make the code a bit more readable, I also moved the conversion of a raw value into a percentage to a new function called toPercent().

Note, however, that for most practical application a high resolution is actually not needed. We just need to know when the moisture level drops below some threshold and even a 10 step resolution would be sufficient for that.

In the next section, we build a simple Plant Watering Reminder System that blinks an LED when the soil gets to dry.

Plant Watering Reminder System

The following picture shows our Plant Watering Reminder System.

Plant Watering Reminder System
Plant Watering Reminder System

It uses the same wiring as before, just with an additional LED connected to pin 12 of the Arduino.

Wiring for Plant Watering Reminder System
Wiring for Plant Watering Reminder System

It works by continuously measuring the soil moisture using the Capacitive Sensor and if the moisture drops below a defined threshold the red LED starts blinking. Here is the complete code:

const int valAir = 440;
const int valWater = 240;
const int ledPin = 12;
const int minMoisture = 30;

int toPercent(int val) {
  int percent = map(val, valAir, valWater, 0, 100);
  return constrain(percent, 0, 100);
}

void setup() {
  Serial.begin(9600);  
  pinMode(ledPin, OUTPUT);
}

void loop() {
  static bool toggle = false;
  int val = analogRead(A0);
  int percent = toPercent(val);
  bool alarm = percent < minMoisture;
  Serial.println(percent);
  digitalWrite(ledPin, (alarm && toggle) ? HIGH : LOW);    
  delay(1000);
  toggle = !toggle;
}

The only really new bit is happing in the loop() function. We are measuring the moisture level in percent. If that level drops below minMoisture, the alarm variable becomes true. If the alarm variable is true, we blink the LED.

The blinking effect is achieved by toggling the toggle variable in each iteration, and since we have a delay of 1 second, the LED blinks every second. If you want a faster or slower blinking, just change the delay. The short video clip below shows the system in action.

Plant Watering Reminder System Demo
Plant Watering Reminder System Demo

And that’s it! With that you should have a good starting point to build your own Plant Watering Reminder System.

Conclusions

In this tutorial you learned how to use a Capacitive Sensor with an Arduino to measure moisture levels. A typical application of this specific type of sensor is the monitoring of soil moisture to avoid over- or underwatering of plants.

We built a simple Plant Watering Reminder System that warns if the the soil moisture drops below a certain threshold. It would be easy to extend this system to also warn if the water levels are too high.

Similarly, adding more sensors to the system is easy as well. An Arduino Uno has six analog inputs you can use. Since the current consumption of the sensors is low, you could power all six sensors from the Arduino.

A more advanced system could use WiFi (e.g. ESP32) to send an email message should the soil moisture deviate too much from a set target value, or even control a little pump to water the plants fully automatically. See our tutorial Automatic plant watering system with Arduino IoT Cloud for more details.

When buying Capacitive Soil Moisture Sensors make sure you get the good ones. Look for the voltage regulator, a TL555C timer chip and correct wiring as described above.

And now have fun ; )

Frequently Asked Questions

What is a capacitive soil moisture sensor?

A capacitive soil moisture sensor measures the volumetric water content in the soil by detecting changes in capacitance.

How does a capacitive soil moisture sensor work with Arduino?

The sensor is connected to the Arduino board, and the Arduino reads the analog output from the sensor to determine the soil moisture level.

Can I use multiple capacitive soil moisture sensors with one Arduino board?

Yes, you can connect multiple sensors to one Arduino board by using different analog input pins for each sensor.

Do I need to calibrate the sensor before using it?

It is recommended to calibrate the sensor by testing it in dry and wet soil conditions to establish accurate moisture level readings.

How do you calibrate the capacitive soil moisture sensor using Arduino?

  1. Prepare the hardware by connecting the capacitive soil moisture sensor to the Arduino
  2. Prepare an empty and dry beaker
  3. Fill the dry soil inside
  4. Immerse the capacitive sensor inside the soil
  5. Note down the readings. This reading represents the minimum capacitance value
  6. Now, add water into the beaker carefully until the soil is almost saturated
  7. Wait for a minute
  8. Reread the capacitance value. This reading denotes the maximum value
  9. Use these values to map the moisture level read from the actual application between 0 % to 100 %

Can I use the capacitive soil moisture sensor for other applications besides gardening?

Yes, the sensor can be used in various applications such as automatic plant watering systems, soil moisture monitoring in agriculture, and environmental monitoring projects.

How do I power the capacitive soil moisture sensor?

The sensor can be powered using the 5V output from the Arduino board or an external power supply within the recommended voltage range.

What is the ideal placement of the sensor in the soil?

Place the sensor in the root zone of the plant, ensuring good soil contact for accurate moisture readings.

How often should I water my plants based on the sensor readings?

The watering frequency will depend on the plant type, soil type, and environmental conditions. Use the sensor readings as a guide and adjust watering as needed.

What factors affect the accuracy and readings of a capacitive soil moisture sensor?

Several factors can influence the accuracy of a capacitive soil moisture sensor, including soil composition, temperature, sensor calibration, and environmental conditions. Different soil types may have varying electrical properties that affect sensor readings. Temperature fluctuations can also impact sensor accuracy. Additionally, factors such as electrical interference, sensor placement, and moisture distribution in the soil can affect the overall accuracy of the sensor readings.

What is the difference between the NE555 and the TL555C timer IC ?

The NE555 and TL555C are both timer ICs used in capacitive soil moisture sensors. The NE555 is a general-purpose timer IC, while the TL555C is a low-power version of the NE555 with improved specifications.

Which is better resistive or capacitive soil moisture sensor?

Both Resistive and capacitive soil moisture sensors have their own merits. Resistive-based soil moisture sensors are cheaper compared to capacitive soil moisture sensors. 

The capacitive soil moisture sensor is highly immune to environmental elements as the electrodes don’t come in direct contact with the soil moisture. 

The resistive soil moisture sensors suffer from a process called electrolysis which happens due to the salts in the water reacting with the electrode when there is a current flow between the electrodes.

Over a while, the measurements will have huge offsets and errors due to the corrosion of the electrodes. 

If you plan to monitor the soil moisture sensors using the resistive type, you can monitor the values periodically instead of keeping the sensor powered all the time. One idea is to connect the 5 V line of the sensor to an Arduino GPIO. Whenever measurements are needed, you can drive the GPIO pin high. Once you take the readings, you can drive the GPIO low.

If you have to use the sensor measurements frequently, capacitive sensors are a better design choice.

Nick

Friday 7th of June 2024

You did not run this code. This will not execute. Serial.println(soilMoistureValue); You need parentheses around the text to print text. Serial.println("soilMoistureValue");

Not a big thing but it could confuse some novices. Always test before publishing.

Stefan Maetschke

Friday 7th of June 2024

Thank you very much for letting us know! Much appreciated! Code example has been fixed.

Jeff Verive

Monday 27th of February 2023

There's an error in your code. You declare a variable called "MoistureLevel", but use a different (undeclared) variable called "soilMoistureValue" when displaying the raw analog value via the second line in the main loop:

Serial.println(soilMoistureValue);

Because "soilMoistureValue" is not declared elsewhere, the compiler throws an error. If you replace "soilMoistureValue" with "MoistureLevel" the sketch runs as intended.