Go Down

Topic: How to: soil moisture measurement? (Read 43 times) previous topic - next topic

madepablo

#5
Oct 18, 2009, 01:35 pm Last Edit: Oct 18, 2009, 01:46 pm by madepablo Reason: 1
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: [Select]

/*  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);
}

Grumpy_Mike

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.

Mike Rice

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.


madepablo

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!

Mike Rice

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.

Go Up