Capacitive Soil Moisture Sensor

Good day All,

This is my first time posting to this forum and kind off my last resort as I would've liked to figure it out myself. I am trying to create a soil moisture probe which can be used on farms to determine soil moisture at different depths. The project consists of a Arduino Nano, a DIY capacitive moisture reading setup (schematic attached- My setup is the same except for the LED moisture indicator)) and an LCD screen to display the required value.

My initial setup was a Arduino Nano (328P Old Bootloader) with a resistive soil moisture sensor. However, these sensors (as they are resistive) do not give reliable readings when measuring at different spots in a field. I believe it is largely influenced by pH, salt content etc.

My next approach was to build a DIY capacitive soil moisture sensor. After searching the web I came across a setup on hackster.io ( https://www.hackster.io/Pedro52/arduino-capacitive-soil-moisture-sensor-diy-with-esp32-d7ad72 ) where a signal is sent via a ESP 32 microcontroller to a probe in the soil and a signal is returned. I implemented the same setup with the same components however I only used optimization of the timers on the Nano to generate the PWM wave (Once again this code was also obtained from another website and I am still a bit confused on how the code works).

I seem to get a reading from the sensor but the zero value seems to very volatile. Even if the wire is only picked up, the output reading changes. Is there a way to get around this and can someone please help me to get my system working optimally.

It would be highly appreciated.

//The setup uses a Chinese Arduino Nano, a 10M ohm, a 10k ohm, a 1N4007 diode and a 1 microfarrad capacitor as shown in the schematic. 
//The LED moisture indicator in the schematic can be ignored

//#include <LiquidCrystal_I2C.h>
//#include <LcdBarGraphRobojax.h>
#include <Wire.h>

//LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 16, 2);
//LcdBarGraphRobojax lbg(&lcd, 16, 0, 0);


float Moistlevel = 0;
float Moistpin = A1;
float Moisture = 0;
float RESET;
float factor;
const byte CLOCKOUT = 9;


void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);

  TCCR1A = bit (COM1A0);                  //Code which I obtained to initiate the onboard timer 1 to give a signal through D9
  TCCR1B = bit (WGM12) | bit (CS10);
  OCR1A =  0;                             // Apparently this should be changed for prescaling. Is it necessary?


  RESET = analogRead(Moistpin);           // Take a initial reading to zero the setup

  for (int j = 1; j < 5 ; j++)            // Take another 5 readings of which the average will be determined
  {
    RESET = RESET + analogRead(Moistpin);
    delay(200);
  };

  RESET = RESET / 6;

  Serial.print(RESET);
  Serial.println();


  Serial.print("Moistlevel");
  Serial.print("\t");
  Serial.print("\t");
  Serial.print("Moisture");
  Serial.println();
}

void loop() {

  Moistlevel = analogRead(Moistpin);                  //Take an average reading every second

  for (int i = 1; i < 5 ; i++)
  {
    Moistlevel = Moistlevel + analogRead(Moistpin);
    delay(200);
  };

  Moistlevel = Moistlevel / 6;
  Moisture = (RESET - Moistlevel) / (RESET / 100);    //Conversion to go from a voltage reading to a percentage reading

  if (Moisture < 0)                                   //Moves the initial if a negative moisture is obtained.         
  {
    RESET = Moistlevel;
  };

  Moisture = (RESET - Moistlevel) / (RESET / 100);    //Obtains the new moisture value and prints it.

  Serial.println(Moistlevel);
  Serial.print("\t");
  Serial.print("\t");
  Serial.print("\t");
  Serial.print(Moisture);
  Serial.println();
  delay (500);
}

Thanks in advance!!!!

DIY soil Moisture.jpg

DIY soil Moisture.jpg

Please, no, can you please put that aside ?

  • Never call a Fritzing drawing a schematic, that drives some of us nuts :wink:
  • The circuit is not a capacitive soil moisture sensor. It is mainly a resistive soil sensor with a DC part and a part radio wave. Because it is not AC, the probes will oxidize.
  • I doubt if you use Timer1 correctly.
  • I don't understand the calculation in your sketch.
  • One wire of the probe is connected to the GND of the Arduino. That can cause issues when it is not powered by batteries or when more probes are used.

I'm sorry, but that is not the way. I'm afraid it will never work :frowning:

For the Arduino Nano you can use the tone() function to generate a frequency. I forgot the maximum frequency it can do.
Sometimes I use the toneAC, I think it can go up to 1MHz.
There are other good libraries as well.
If you use capacitive soil moisture sensors with analog output, then you don't need a high frequency signal.

You can buy capacitive soil sensors with analog output which are waterproof, or buy normal capacitive soil sensors and use heatshrink with glue to make them waterproof. Don't buy the cheapest capacitive soil moisture sensors, they have issues.
This is an example of such a sensor: https://www.tindie.com/products/pinotech/soilwatch-10-soil-moisture-sensor/.

If you are a beginner, you should start with something that works.

A if-statement and for-statement don't need a ';' after the closing '}'.

Below is the schematic of the Fritzing diagram, so others can rant about it as well.
soil.png

soil.png

1 Like

Oh shucks,
Thanks so much Koepel. Now I have a couple of questions from your answer:
-Is there a way to remake such a capacitive soil moisture sensor and if there is how can it be done?

  • To what should I connect one wire of the probe if it should not be connected to the Ground of the Arduino?

Please assist in anyway that you can. It will be highly appreciated.

Thanks for the advice regarding the ‚Äú;‚ÄĚ.

I think chirp! started with these capacitive sensors. The main chirp! page is here: chirp! - the plant watering alarm.
On that page are links to Tindie to buy them and to Github for the schematics.

There is a lot of thought and trial and error behind the chirp!
The "capacitance" is created by the copper traces. The moisture in the soil makes the path between those copper traces.
The copper traces are covered by pcb lacquer so the electronics do not touch the soil. There is no ground problem.

The capacitance is very low, and the code is not in Arduino code.
I don't know how you can re-create that in a easy way.

There are however good capacitance meters with an Arduino. Perhaps you can find a good sketch. I forgot which was the best one for the picoFarad range.
The one at the bottom seems good: https://www.gammon.com.au/forum/?id=12075.
This one might measure lower capacitance: How to Make an Arduino Capacitance Meter.
I tried both of them some time ago, and they work with capacitors. However, with water the differences were very small, and it was not reliable.
See: Het Nederlandstalig Arduino forum - Bekijk onderwerp - welke sensor kan ik gebruiken.

When you want to make something yourself, you might have to fall back to some kind of resistive testing. I have tried that myself as well by using two output pins, and exchanging the HIGH and LOW and measure the resistance both ways. That worked for some time, but it got more and more unreliable.
My newest effort was to send 250kHz into the soil and measure how much got through to the other wire. That seems to work, but I never finished it. Today I check the weight of the flower pot and make a guess if it needs water or if it can wait another week.

This is not a complete schematic, but this is how the capacitive probes are made:

Basically, the NE555 is operating as an oscillator and the capacitance of the probe changes the analog value out.

Don't be confused by the name - the soil has no capacitance to measure, only conductivity. The capacitance is only a method of isolating the soil from DC currents. The meaning of that is - the measurement is actually a resistance measurement, taken in series with a very low value capacitor. Hence the high frequency, to reduce the impedance of the capacitive component so it doesn't contribute much to the reading. So, in the diagram above, R1/C1 is effectively working as a resistive voltage divider, and that is why the rectified output voltage can indicate soil conductivity. Any circuit that you design has to follow this basic plan. The sensor itself has this kind of model:

terminal1 0-----||-------(soil resistance)-----||------0 terminal2

Cheap soil moisture sensors are a ‚ÄúSolved probelm‚ÄĚ.

Lots of cheap soil moisure sensors.

I’ve used a BUNCH of these for a couple years. Very few issues with them. You need to set wet/dry limits for each one. So make that easy to do.

-jim lee

aarg:
Don't be confused by the name - the soil has no capacitance to measure, only conductivity. The capacitance is only a method of isolating the soil from DC currents. The meaning of that is - the measurement is actually a resistance measurement, taken in series with a very low value capacitor. Hence the high frequency, to reduce the impedance of the capacitive component so it doesn't contribute much to the reading. So, in the diagram above, R1/C1 is effectively working as a resistive voltage divider, and that is why the rectified output voltage can indicate soil conductivity. Any circuit that you design has to follow this basic plan. The sensor itself has this kind of model:

terminal1 0-----||-------(soil resistance)-----||------0 terminal2

The capacitive sensors work by varying the capacitance of the probe. Wet dirt adds less capacitance than dry dirt.

Thanks all for the feedback. I will be trying the 555 oscillator circuit to see of I can recreate a reliable sensor. I know about the commercial capacitive soil moisture sensors, however these are not practical for what I am building as the probe needs to measure moisture at depths up to 1m. Taking into consideration that a housing will have to be built in which the electronics can be protected whilst probing up to a metre deep, makes these types of sensors unpractical. Thus a control PCB will have to be built which relays the data of the 3mm probes that are at the tip of my sensor ‚Äústick‚ÄĚ

There is always some loss in a dielectric medium, wet soil is very lossy. Also if you look at the capacitor "plates" on the ones I'm seeing from a search, they are placed adjacently in the same plane, reducing the capacitive coupling considerably. I think this must at least introduce a significant dependence on the conductivity of the medium in this case. Either way, if the measurement electronics is separated from the sensing elements by a meter, care has to be taken with the cable. It should be shielded, and have low capacitance.

Cheap capacitive soil moisture sensors with the TLC555 chips work pretty well - provided you take the time to waterproof the circuitry before putting them in the ground. Nothing more complicated than analogRead();