Yes, I know that there are capacitive soil moisture sensors shipped from China for some bucks. But buying does not make me understand how things work. So I decided to build my own sensor.

My requirements are simple:

  • The sensor shall work with Arduino and ESP32, i.e. it shall support 3.3V as well as 5V supply voltage
  • It shall be cheap

Browsing the web I found three different solutions. All three do have the same base technology: They require some kind of oscillator, i.e. something that generates cyclic pulses – or to be more precise: a square wave signal.

I grabbed the chance and made this my first timer 555 project. Yeah.

So here are my three approaches:

  1. Measure the soil moisture as a varying frequency as output
  2. Measure the soil moisture as a varying analog voltage as output
    • Alternative 1: With a LM331 IC
    • Alternative 2: With the help of a diode and a capacitor

For all the sensors I used an arrow like perfboard and sticked a copper foil on it. I devided the foil into two pieces with the same area. Both areas form the plates of a capacitor. I went for the arrowish design because I thought it is easiest this way to stick it into the soil.

Basic design of the soil moisture sensors. The copper foil is the main element.

Timer 555

Just a short word on the timer 555 I use. Well, I do not think that the timer 555 needs any explanation on how it works. If you do not know this famose IC, just google it.

I used not the original NE555 as it was not deliverable during the Covid-19 shut down Germany. I instead picked the TLC555. It does have the identical pin out, but is based on CMOS technology. It operates at frequencies up to 2 MHz, which is ideal for my project.

Output: Varying Frequency

In fact this is the simplest circuit of all three. All you need is:

1 x timer 555

1 x resistor 300 Ohm

1 x resistor 1 kOhm

1 x capacitor 100 nF


All you have to do is connect pins 4 and 8 to supply voltage, connect pin 1 to ground. Pin 5 is also connected to ground, but the capacitor is put in between.

Pins 2 and 6 are connected between the 1 kOhm resistor and the positive plate off the big capacitor.

Pin 7 is connected between the 1 kOhm resistor and the 300 Ohm resistor. The latter is connected to Vcc.

The resulting frequency of 555’s rectangle signal mainly depends on your capacitor. I achieved 1.32 MHz if the sensor was dry, dropping down to 171 kHz when put into water at 5V. And 1.77 MHz (dry) to 365 kHz (in water) at 3.3V.
This means I would have more then 1 million steps to measure. More than enough precision for measuring soil moisture.


2 x resistors EUR 0.1

1 x capacitor EUR 0.06

1 x TLC 555 EUR 0.75

1 x perfboard EUR 0.78

1 x copper foil EUR 0.07

Total costs: EUR 1,76

I will write an extra article on measuring frequencies with an ESP32 in the future. It is best to use the pulse counter of ESP32 in addition with a esp_timer.

In the Arduino IDE you should use the FrequencyCounter Library.

Output: Varying Analog Voltage with LM331

The LM331 IC is mainly designed to output a frequency signal based on an analog voltage input signal. But it can also be used in the opposite direction: Output an analog voltage based on a frequency signal.

The datasheet of LM331 depicts two implementations of a frequency to voltage coverter:

The left circuit is a high precision frequency to voltage converter, which is able to handle frequencies up to 100 kHz. The circuit on the rights shows a less precise converter which is only able the handle frequencies up to 10 kHz.

I wanted to keep my project simple therefore I went for the less precise circuit as it requires less components. Next I had to adapt my timer 555 circuit so that the output frequency was less than 10 kHz. All I had to do was change R6 to 1 kOhm.


9 x resistors EUR 0.45

4 x capacitor EUR 0.24

1 x TLC 555 EUR 0.75

1 x LM331 EUR 2,75

1 x perfboard EUR 0.78

1 x copper foil EUR 0.07

Total costs: EUR 5,04

This is the most expensive version of a soil moisture sensor. Another disadvantage is that the LM331 only works in a voltage range from 4V to 40V. That means it is not compatible with an ESP32. In my tests I found it works best at 12V to 15V supply voltage.

Output: Varying Analog Voltage with Diode and Capacitor

The output frequency of the 555 timer can also be used to charge and discharge a capacitor. With the help of a fast switching diode this is the same mechanism as with the LM331. But much cheaper.


4 x resistors EUR 0.20

5 x capacitor EUR 0.30

1 x TLC 555 EUR 0.75

1 x perfboard EUR 0.78

1 x copper foil EUR 0.07

Total costs: EUR 2,10

This version is not as cheap as the frequency version, but it works very good at 3.3V and 5V. It is easy to build and the biggest advantage is: you do not need advanced programming skills. In the Arduino IDE you can read the output voltage with a simple analogRead-statement.