Introduction: Capacitive Soil Moisture Measuring (with I2C)

About: I am a physician by trade. After a career in the pharmeceutical world I decided to take it a bit slower and do things I like. Other than my hobbies that involves grassroots medicine in S.E.&P Asia. I have buil…

A lot has been written about how to measure soil moisture and especially on what sensor to use.

With the simple resistance measuring the biggest issue is the corrosion of the sensor, not just because it is in contact with the soil but also because there is a DC current flowing which causes electrolysis of the sensors.

There are solutions for this, like feeding the sensor with an AC current, but in practice this is at best a pulsating DC. Some people encase their sensors in plaster, but I found that a bit of a drag and you get a slow reacting sensor as the moisture content of the plaster will always be behind that of the soil.

So, like many others, i have been entertaining the idea of capacitive soil measuring.
Capacitive measuring has some advantages, not only is it possible to avoid corrosion of the probe, capacitive measuring also gives a better reading of the moisture content of the soil as opposed to resistance measuring. In the latter one doesnt really measure moisture (as water is a bad conductor of current), but in fact one measures the ions that are dissolved in the moisture. Adding fertilizer for instance will decrease the resistance of the soil, eventhough no water is added.

Capacitive measuring basically measures the dielectrum that is formed by the soil and the water is the most important factor that forms that dielectrum.

As said, various people have already been tackling this issue and came up with capacitive probes. Usually these are made of double sided PCB to form the 'capacitor', sometimes even single sided PCB in which basically two tracks are etched. These have the advantage that they can contain some hardware as well and basically have a "stick in and forget" practicality. Just one thing you put in the ground and be done with it.

These are also a bit pricey if you buy them around 10-13 dollars, but ofcourse making it yourself is possible and in this case probably cheaper as well.

Essential with these 'probes' is that you electrically insulate them from the soil, otherwise you might as well measure resistance again and keep it simple. This insulation is usually done with some kind of weatherproof lacquer or paint.

I wanted to see if i could use a bit of a simpler contraption, like 2 pieces of pcb as my capacitor plates.

Step 1: Capacitive Soil Moisture Measuring: Testing

Although one can use the arduino to measure capacity directly, I find it a bit tedious and it will also cost you an extra pin or 2. Also it is a bit impractical as it needs the capacitor to be close to the arduino as not to measure stray capacity of the wires.
Therefore I wanted to use an RC oscillator in which the 'C' i.e. the soil moisture content defined the frequency of the osicllator. A frequency value can be transported easier over a long wire than a capacity value.


  • 74HCT14
  • 2M2 resistor (In the ready model I ended up using a 100k resistor)
  • Glass jar (pickles or something like that)
  • 2 pieces of alu foil, each large enough to cover a bit less than half the jar
  • Ducttape
  • wires
  • small breadboard
  • Arduino

There are several simple circuits that form an RC oscillator but I have chosen the one with the inverter/schmitt-trigger 74HCT14. The frequency of that is 1/T=1/(0.67 xRC). If you happen to use a 74HC14 the frequency is 1/T=1/(0.8xRC).

However, the actual frequency is not really important as we are looking for differences in frequency that relate to dry or moist soil. If you happen to have some NANDs rather than the 74HC14 that can be used too and most people will likely have a 555 that can be used.

As it is winter and cold outside I like to do my testing inside so I also made a quick sort of modified "Leyden jar" (Leidse Fles) that consisted of a glass jar with two pieces of alufoil attached to the outside (at opposite sides) with each a wire ducttaped to it.

I attached this jar to the input of the oscillator and fed the output to an arduino where i used a simple 'pulseIn' command to measure the period. I first used a resistor of 100k but that really didnt show any results, so i increased it to 2M2.
i then started to fill the jar with water. That gave me the following readouts:

  • Empty jar: 1uS (but that was probably the minimum reading as 'no jar' also gave me that)
  • Half full jar: 50-60uS
  • Full jar: 90-110 uS (that's around 10kHz)

All in all it looked pretty stable and in fact fairly linear as well. The system is fairly sensitive too: I found out that if i stuck my fingers in a full jar, the cycle time dropped a bit: as my fingers contain less water than pure water and they displaced the water, the dielectrum dropped. Obviously this only works with a full jar,because with a half full jar the water between the plates rises, increasing the dielectrum again.

Step 2: Capacitive Soil Moisture Measuring: Field Testing

For the field test we need the following:

  • 2 pieces of PCB ca, 12x7 cm (or other size if you have)
  • 2 Zip bags of >12x>7 cm
  • 2 alligator clamps (or solder a wire)
  • 1x HCT14
  • 1x 2M2 resistor (Eventually in my ready model I used a 100k, but much depends on yr sensor)
  • wires
  • small breadboard
  • Arduino
  • Laptop or LCD

As it was freezing, I had to wait for the ground to thaw, but then I constructed two plates simply by placing a piece of PCB with a wire attached in a ZIP-bag as one plate and a similar construction as the other plate.

I have a raised bed of 1.20x1.20m (4x4 foot 'square foot garden') filled with Mel' s Mix.
I put the plates some 30 cm apart with the copper sides facing. With that I took a rather traditional view on what a capacitor is: a dielecrum BETWEEN 2 plates, whereas the double sided pcb versions more look at the dielectrum AROUND 2 plates. In reality ofcourse the soil at the back of my plates also is part of the dielectrum.

I used the PulseIn command again to measure the pulse-length of the output of the 74HCT14 RC oscillator.

I was pleasantly surprised to see values in the range of what I found with the Leyden jar the reading was about 30uS and would rise fairly rapidly when I started watering, even if this was not directly between the plates.

The reading was more stable than I had expected, but handling the wires definitely had an influence, albeit small. This can be helped by using twisted pair wires, but as there are two plates at 30 cm distance, some length of single strand will be unavoidable. Note, I am talking about the wires from the plates to the oscillator, not the wires from the oscillator to the arduino,


So, basically I now had a fairly cheap and simple capacitive sensor but I was starting to think about the practicality.
Ideally, I would place the plates at opposite ends of the Square foot garden, so 4 feet/1m20 away from eachother.
That did work albeit that the readings were a bit lower. Placing them in a 90degree angle in a corner also worked well.
Now I still had to consider where in the final setup I had to put the oscillator. Clearly this had to be on one of the plates, but then there always would be a wire needed to connect the distal plate.
I was starting to see the advantages of the "one prod, just stick it in the soil" sensor. Time to rethink

Step 3: Capacitive Soil Moisture Measuring: Practical Solutions

As said, I was now having this working, cheap, easy capacitive sensor that would do fine in a steady setup, but I wanted something more moveable, durable.
My goal however was to keep it cheap, otherwise I might as well have bought one. Ofcourse it is possible to have a PCB made and then for say 15 euro's you get 3 PCBś so the cost per PCB is not that bad, but to have a PCB made for something that simple seemed dumb.
So I did some further testing and placed the PCB's back to back with the copper surface away from eachother and I also tried putting them next to eachother. Both setups again gave reasonable results. Maybe the one PCB solution wasnt that bad after all.

With one PCB there are a few options to form the capacitor plates A and B:

  • double sided, each with a full surface A or B
  • double sided, but each side also divided in two surfaces so A & B at both sides
  • single sided with plate A and B on one side

The first solution seemed simplest to me

Step 4: Capacitive Soil Moisture Measuring: the Chirp Has I2C: Can You Do That Too?

Yes, well the original Chirp does not have I2C (but can be hacked as such) but they do have a version with an I2C and that isn't a big problem to do. We are going to need an Attiny85 for that. As we are using the Attiny85 we could consider dropping the HC14 as the attiny can also measure capacity (and uses 3 pins for that), but while we are at it and use I2C, we might as well expand the humidity sensor with a temperature and e.g. light sensor. and keep the HC14.
The Attiny has 5 pins to its disposal (unless we want to mess with pin1), two we need for I2C so we would have 3 left, which would just be enough for a capacity tester. If we keep the HC14, we only need one pin and have two left for other measurements
In order to make the Attiny85 act like an I2C slave we will be using the TinyWireS library.

For the reading of the LDR ant the NTC we need an integer to store the readings as it could go up to 1023, however, unless you nee a lot of accuracy, you could map it into 1 byte.

Do not forget that the I2C lines need a 4k7-10k pull up line. Whether you want to add those to your sensor or add them at yr Arduino is up to you

You will find the code in the next step

Step 5: Capacitive Soil Moisture Measuring: I2C Slave Code

The code to provide the sensor with I2C looks like this:

It is important that the Attiny works on at least 8Mhz.
I cant take all the credit for the code as I just reworked one of the examples in the TinyWireS library.
I have used pulseIn to measure the pulselength. PulseIn is a command that waits. It might not be the best policy, but it works. If anybody has a suggestion on a better code, I am always interested to hear that.
With regard to the NTC, I now read the value on the analog port, map that to 1 byte and present that for further processing. Ofcourse it is also possibe to use the Steinhart-Hart formula to rework it to a temperature in degrees and put that in the register.

If u approximate the temperature with th Steinhart-Hart formula youneed one of these calculations
Rntc = Rseries/((1023/ADC) – 1)); // with a pull up resistor

Rntc = Rseries*((1023/ADC)-1);// with a pull down resistor as in this circuit

Step 6: Capacitive Soil Moisture Measuring: I2C Master Code

In order to read the the sensor, the Arduino needs the following code:

This is ofcourse only an example code that reads out the LDR, NTC and Humidity registers. The humidity is represented by two bytes that need to be combined in an integer. That can be done with one line of code: value= msbv<<8 | lsvb; For the uninitiated: this code shifts the Highest bit 8 positions (1byte) to the left, basically by adding 8 zeros at the right. It then OR's the lowest byte to that, thus forming the 16 bit (2byte) integer

Step 7: Construction

As I didnt have double sided PCB, I just glued two pieces of single side together (but mind you, one piece of single sided PCB with two plates etched onto it works too). And to make sure it wouldn't detach, I soldered a wire through both plates in the corners. Obviously you should do that an an insulated copper island. Made a round plastic baseplate that the pcb would fit in and that could carry the clear plastic dome. The dome would house the separate PCB I made for the circuit

Now of course this is not the way you have to do it. It is very convenient to etch the PCB for the circuit on one of the capacitor plates, but as my piece of scrap was a bit short I decided against it.

the only reason I made it with a plastic dome is because I have an LDR under it. without that you could just encase the entire circuit in shrink tube and have a nifty sleek design
The NTC I stuck to one of the capacitor plates.
Finally, a 4 wire cable goes into the sensor.

It is essential that the capacitor plates are completely galvanically separated from the soil. One can do that with paint, Plasti-Dip (expensive), or Heatshrink-tube.
I most likely will choose the latter, but for now I will just use a plastic zip bag till I know I am completely happy with the set-up.
Eventually I ended up going back to a 100k resistor in the oscillator

Total cost:

Attiny 45 or 85: 100ct (75 cts in 20SU)

74HC14 10ct

dip foot 10ct

resistors 10 cts
So basically in parts this will cost 1.30 USD.
Some scrap PCB will do and then some wire, a cone and some scrap plastic for a base.
The cover of laquer or shrink tube might be the most expensive part

Step 8: Capacitive Soil Humidity Measuring With I2C: Thoughts

A promising range of chips is the AD7745/46/47 range.
These are integrated capacitive to digital chips that will take two capacitor plates a input and convert it to an I2C signal.
However, at 10-12 USD these are not cheap.

Also, with its current program, the device measures continuously. Obviously that is not really a problem as one always reads-out the most recent stable measurement, but one could decide to send a signal via I²C to start the measurements.

You will find another interesting capacitive moisture measuring projct here.