Pages: [1] 2   Go Down
Author Topic: How to: soil moisture measurement?  (Read 39546 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Sr. Member
****
Karma: 0
Posts: 471
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I saw two different circuits to measure soil moisture with arduino, bot of the low-cost based n the measurement of the reistance of the soil throught two nails.
These circuits are those:
The simple: http://www.make-digital.com/make/vol18/?pg=94
The complex: http://spaces.kisd.de/makethings/2008/05/12/how-to-build-a-soil-moisture-sensor/

I have three questions about it.
1) what are the practical difference between them? I mean is one of them more accurate than the other? or something like that?
2) is there a "standard" distance between the nails to measure the distance in a precise way (as precise as arduino made possible, of course)?
3) I suppose that a simple calibration process consist on measure the output from analogue pin when the nails are in the air (maximum resistance, humidity=0) and inside a glass of water (minimum resistance, Humidity= 100%)

Thanks.
Logged

Florida
Offline Offline
Full Member
***
Karma: 0
Posts: 112
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

A simple circuit can be just as accurate as a more complex one. The more complex circuit is more sensitive though.

As for calibration, you're correct in how to get the zero and 100% points.

The simple 'two nails' probe works OK as an experiment, but accuracy degrades, slowly in some cases, rather quickly in others, depending a lot on soil chemistry. The nails corrode, and the use of a DC current aggravates the problem due to electro-migration.

A more practical probe will use an AC measuring current, and use corrosion resistant probes.

The AC measurement technique can be easily done with an Arduino, but it will cost you a two digital pins.
Your 'probe' (the two nails) are in series with a resistor, forming a voltage divider. The center of the divider is connected to an analog input. The voltage divider is connected between two digital outputs.

The following code fragment gives an example.

Quote
/*
Connect two nails and a resistor as shown

digital 2---*
                  |
                  \
                  /
                  \ R1
                  /
                  |
                  |
analog 0----*
                  |
                  |
                  *----> nail 1
                  
                  *----> nail 2
                  |
                  |
                  |
digital 3---*
*/

#define moisture_input 0
#define divider_top 2
#define divider_bottom 3

int SoilMoisture(){
  int reading;
  // set driver pins to outputs
  pinMode(divider_top,OUTPUT);
  pinMode(divider_bottom,OUTPUT);

  // drive a current through the divider in one direction
  digitalWrite(divider_top,HIGH);
  digitalWrite(divider_bottom,LOW);

  // wait a moment for capacitance effects to settle
  delay(1000);

  // take a reading
  reading=analogRead(moisture_input);

  // reverse the current
  digitalWrite(divider_top,LOW);
  digitalWrite(divider_bottom,HIGH);

  // give as much time in 'revers'e as in 'forward'
  delay(1000);

  // stop the current
  digitalWrite(divider_bottom,LOW);

  return reading;

}

Logged

Offline Offline
Sr. Member
****
Karma: 0
Posts: 471
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Mike!

Thanks! This is a third possible circuit. I will try your circuitand code next weekend.
I know that the nails (also galvanized ones) are not the best sensors for accurate measurement, but i readed other post in this forum about a similar topic, and the main problem is that the commercial sensors are pretty expensive compared to other sensors that we could buy in our favorite electronic's store.

I will inform about my advances soon...
Cheers,

Logged

Florida
Offline Offline
Full Member
***
Karma: 0
Posts: 112
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Actually you can make a high quality sensor for less than $5!

What we are going to do here is re-purpose a Leaf Wetness sensor, which is available from hobby-boards dot com.
This sensor is gold-plated, so it will not tarnish or corrode except in quite extreme and very unlikely, circumstances.
And it only costs a couple of dollars.

Coat the board with Plaster of Paris, then wrap a layer of burlap (feel free to substitute) around it.
Let it dry, then apply another coat of plaster.
Ta Da! A $50 sensor for less than 5 bucks!

Plaster of Paris will absorb moisture from the soil around it, protect the board from mechanical damage, and removes
soil chemistry from the equation.

Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 57
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I tested a sensor which was basically two nails encased in Plaster of Paris. My only complaint was that once the sensor got wet it seemed to take much longer for the plaster to dry out than the soil around it. Using something like the Leaf Wetness sensor and a thin coat of plaster might improve the response.

I ended up using two thin strips of stainless steel held together with nylon screws to keep the spacing constant. I packed this in sand. The sand seems do to a good job of wicking in moisture from the soil and dries out more quickly than the Plaster of Paris.

This thread has a picture of my sensor and information about using a 555 timer to create an AC circuit and measuring the frequency of the timer circuit rather than directly measuring current. It is just another way to approach the problem.

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1241791578/0
Logged

Offline Offline
Sr. Member
****
Karma: 0
Posts: 471
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks to all,

Nice ideas... however, i would like to start first by the easier circuits until to start with more complex ones. But i will think about them to test with my project.

About the simple circuit proposed my Mike, i wrote an small sketch using your code, but is don´t give me results... just only 0 in any case (in the air, in contact, in the soil,...
I suspect that i don´t know to write sketches for arduino...

Could you take a look? The circuit is this one that Mike proposed above. I iused a 10KOhms resistance in R1. (although i also tried with a 4.7KOhms...) I used this one because is the resistance used in other similar projects (links in the first post of this topic).

Thanks!

Here is the complete code:
Code:
/*  Soil Moisture measurement v0.1 20091017
    Simple circuit
    Not calibrated at this moment
    
    Started by Mike Rice, October 14, 2009
    Modified by M.A. de Pablo, October 17, 2009

    Circuit:
    To connect two nails and a 10 KOhms resistor as shown:

           digital 2---*
                 |
                 \
                 /
                 \ R1
                 /
                 |
                 |
         analog 0----*
                 |
                 |
                 *----> nail 1
                
                 *----> nail 2
                 |
                 |
                 |
           digital 3---*
*/


#define moisture_input 0
#define divider_top 2
#define divider_bottom 3

int moisture; // analogical value obtained from the experiment

int SoilMoisture(){
  int reading;
  // set driver pins to outputs
  pinMode(divider_top,OUTPUT);
  pinMode(divider_bottom,OUTPUT);

  // drive a current through the divider in one direction
  digitalWrite(divider_top,HIGH);
  digitalWrite(divider_bottom,LOW);

  // wait a moment for capacitance effects to settle
  delay(1000);

  // take a reading
  reading=analogRead(moisture_input);

  // reverse the current
  digitalWrite(divider_top,LOW);
  digitalWrite(divider_bottom,HIGH);

  // give as much time in 'revers'e as in 'forward'
  delay(1000);

  // stop the current
  digitalWrite(divider_bottom,LOW);

  return reading;
  moisture = reading;
}


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

void loop (void) {
  Serial.print("Soil moisture: ");
  Serial.print(moisture); // print the analogical measurement of the experiment
  // later i will improve here a calculation for derive Soil Moisture in %
  Serial.println();
  delay(1000);
}
« Last Edit: October 18, 2009, 06:46:50 am by madepablo » Logged

Manchester (England England)
Online Online
Brattain Member
*****
Karma: 619
Posts: 33989
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
The nails corrode, and the use of a DC current aggravates the problem due to electro-migration.

This is true but there is an other effect that also reduces the sensitivity of gold probes. As a DC current is applied you get some electrolysis around the probes. That is the water is broken down into hydrogen and oxygen and forms microscopic bubbles on the surface of the electrodes. This reduces the surface area in contact with the soil and hence reduces the resistance measured. The only way round this is to use AC.
Logged

Florida
Offline Offline
Full Member
***
Karma: 0
Posts: 112
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

OK, I found a couple of problems in your code.

In the code I posted, int SoilMoisture() is a function, but you are trying to use it as a subroutine (i.e not using the returned value, but calling it for its 'side effects').

But that doesn't matter because you never invoke the subroutine anyway.

But even if you had called it, it still wouldn't work, because the CPU never gets to the side effect moisture=reading which you added to the very end of the routine, right after return reading.

Kinda looks like you're getting in a hurry   ;D

Try this...

Quote
/*  Soil Moisture measurement v0.1 20091017
 Simple circuit
 Not calibrated at this moment
 
 Started by Mike Rice, October 14, 2009
 Modified by M.A. de Pablo, October 17, 2009
 
 Circuit:
 To connect two nails and a 10 KOhms resistor as shown:
 
        digital 2---*
                  |
                  \
                  /
                  \ R1
                  /
                  |
                  |
        analog 0----*
                  |
                  |
                  *----> nail 1
                 
                  *----> nail 2
                  |
                  |
                  |
        digital 3---*
 */


#define moisture_input 0
#define divider_top 2
#define divider_bottom 3

int moisture; // analogical value obtained from the experiment

int SoilMoisture(){
  int reading;
  // set driver pins to outputs
  pinMode(divider_top,OUTPUT);
  pinMode(divider_bottom,OUTPUT);

  // drive a current through the divider in one direction
  digitalWrite(divider_top,LOW);
  digitalWrite(divider_bottom,HIGH);

  // wait a moment for capacitance effects to settle
  delay(1000);

  // take a reading
  reading=analogRead(moisture_input);

  // reverse the current
  digitalWrite(divider_top,HIGH);
  digitalWrite(divider_bottom,LOW);

  // give as much time in 'reverse' as in 'forward'
  delay(1000);

  // stop the current
  digitalWrite(divider_bottom,LOW);

  return reading;
}


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

}

void loop (void) {
  moisture=SoilMoisture(); // assign the result of SoilMoisture() to the global variable 'moisture'
  Serial.print("Soil moisture: ");
  Serial.print(moisture); // print the analogical measurement of the experiment
  // later i will improve here a calculation for derive Soil Moisture in %
  Serial.println();
  delay(1000);
}




In addition to fixing the bugs, I corrected the polarity from my original post (my bad  :-[). My original code came from an irrigation project, and 'reading' was to be a partial indication of how desirable it would be to add water (in combination with some other factors).


Grumpy Mike you are right about the electrolysis. This code basically generates a low frequency, low duty cycle AC excitation signal, and employs a synchronous demodulator to extract the data point.

Since it is AC, the harmful effects of both electrolysis and migration are reduced, and since it is a low duty cycle the effects of any residual DC offsets are further reduced, by an amount equal to the duty cycle. Also reduces power consumption, by the way.

In the original project the uC would suspend for an hour (unless interrupted), take readings and then go back to sleep. The old 6805 was not as quick as an Atmega 328, and the ADC080 was kinda slow too, but still the overall duty cycle was on the order of 1 part in 10 million.

Logged

Offline Offline
Sr. Member
****
Karma: 0
Posts: 471
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks Mike,

More than in a hurry, i am so new in this topic, so i was not sure how to call the subroutine....

I did´t (in really i still don´t) understand why you send a current in one way, take a measurement, and later allow a current in the opposite way... to reduce the electrolysis effect in the soil?.

Thanks for your kind the improvement. I will check as soon as possible.

And about your project, my idea is also to measure ones per hour. So i am thinking different possibilities, such as to use a DS1307 RTC, but i don´t know if this is the better option. What method do you use?

Cheers!
Logged

Florida
Offline Offline
Full Member
***
Karma: 0
Posts: 112
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The idea behind the reversal of current (Alternating Current) here is to minimize both electro-migration and electrolysis.
Both can occur with AC as well as DC in some circumstances, though the effect is much less with AC.
By using AC and a low duty cycle we can minimize problems from these effects.


Electrolysis is the breakdown of a compound caused by an electric current. For example, passing current through water (chemical bond of Hydrogen with Oxygen) will break water molecules up into Hydrogen and Oxygen gasses.

Obviously, passing current through a moisture sensor would cause electrolysis.  

This would not cause any permanent damage (unless the gasses were allowed to accumulate!), but the bubbles could affect the sensitivity and calibration of the sensor.





Electro-migration is basically the movement of atoms and molecules under the influence of an electric current.
Metal plating of objects is done with electro-migration, for example the bronzed baby shoes so popular with parents.
This could cause permanent damage to your sensor... your nice shiny gold plating could migrate away from the board to coat the gypsum particles.

That is why you want to use AC for any practical sensor of this sort. DC works fine for an experiment or a proof of concept... but if you want the product to last any length of time, use AC.




I originally used a RTC chip which is no longer available, a DS1307 would work nicely, they are widely available and inexpsnsive.

My original project used two fine platinum wires, wound around a plastic rod, and coated with Plaster of Paris and burlap as per the post I sent.

It was for a large lawn in a very upscale neighborhood on an island. When I say large, the grounds occupied about four acres. All the homes in the area had huge lawns, and large power bills.

Irrigation was only allowed at certain times of the day, on certain days of the week.

Back then these restrictions were because of the odor (sulfurous well water, Welcome to Florida!).

Nowdays there are water restrictions all over Florida because of water shortages, and a lot of commercial products are available to perform this function.
Logged

Offline Offline
Sr. Member
****
Karma: 0
Posts: 471
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Great explanation, thanks!

Firstly i will learn more about arduino and electronic after to try to program the RTC...

Thanks so much for all the comments!!

UPDATE: I tried the circuit and the improved code. It runs, but it not provide the maximum value when i have the nails inside a glass of water.... the reading is 0 when nails are in the air without contact, and about 700 or so when i have them in water without contact... ??
I will check with different types of nails to see if this in an important factor.
« Last Edit: October 19, 2009, 04:21:31 pm by madepablo » Logged

Florida
Offline Offline
Full Member
***
Karma: 0
Posts: 112
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

What value resistor are you using? Use a higher value resistor to get a higher reading when wet.
Logged

Offline Offline
Sr. Member
****
Karma: 0
Posts: 471
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

a 10KOhms... i will try with other higher and lower to test how they runs for low, medium and high values of soil moisture.

Thanks for the idea!
Logged

Offline Offline
Sr. Member
****
Karma: 0
Posts: 471
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi there,

I was focused on other project, so i didn´tpay so much attention to the soil moisture project.

Today i saw this other circuit on internet, also based on the simple ideas of use nails. I know that this is not the better sensor, but just for fun...

http://www.scribd.com/doc/13069922/arduinomacetas

The text of this link is in spanish, but the circuit is clear. So my question now is if this new circuit is better than the simple connection of the nails with a pull up resistance that we were discussion previously.

I know that the reply could be "it depends".... but may be an expert on electronics could put some light here!

Thanks!

[edit]Here is the original circuit!
http://www.botanicalls.com/archived_kits/twitter/[/edit]

[edit]Here is a similar circuit, but it changes the 10k resistance for a 10k pot resistance...
http://www.faludi.com/2006/11/02/moisture-sensor-circuit/

I suppose than in this case it allow calibration of the probes...[/edit]
« Last Edit: November 24, 2009, 02:35:12 pm by madepablo » Logged

Offline Offline
Sr. Member
****
Karma: 0
Posts: 471
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Still working on testing the circuits, i wired this one from the previous post:
http://www.faludi.com/images/blog/moisture_sensor_s1.html

I adjusted the 10K pot resistance to have 0 in analog pin 0 with this simple code:

Code:
const int sensorpin=0;

int moisture=0;

void setup (){
  Serial.begin(115200);
  Serial.println("Soil moisture circuit 3");
  Serial.println();
}

void loop (){
  moisture=analogRead(sensorpin);
  Serial.println(moisture);
  delay (1000);
}

So, such i said, i obtain 0 when both nails have not contact, and 880 when they are together. I also tried on a plant, and it give me around 300 or 500 depending of how much water. when i put the nails in water, the value changes to 700-770 or so, and quickly changes, what is clearly related to the electrochemical processes in the watter due to the voltage. So it seems that the circuit works.

However, i am worry about the 880 value, what means that the circuit give back about 4.6Volts when the nails are together. So, does it means that the circuit itself consumes about 0.4Volts? Or should i adjust the maximum value to 1023. I mean 880=1023 and 5Vols, and 0=0  and 0volts. (may be something like to use the map() function?)

On the other hand, since soils moisture returns about 770 when the nails are inside the water, should i better assume that 770 means 100% of humidity and 0 value is 0% of humidity? Then, it seems that the circuit is not so adequate for arduino since we lost about a half of the scale, form 1023 to just only 770....

I will appreciate your comments!
Logged

Pages: [1] 2   Go Up
Jump to: