Leaf Wetness


  • Hero Member

    Leaf wetness is important to know to detect for crops the neet to make some treatments to avoid some diseases (tomatoes, grapes...)...

    With soil humidity and temperature, it is an element important to monitor your crops.

    In order to make it, some parts are needed:

    • a rain sensor whicl looks like to work as the Davis expensive one, this one is double sided and inexpensive.
    • a box enclosure that can work in the outside
    • an arduino with radio (and good software ;-))
    • and a source of energy.

    or that last point, I'm wondering how to make it since I have both 5V and 3.3V arduini, and 2xAAA or 3xAA batteries holders.


  • Hero Member

    From this document here is the caracteristic of the leaf wetness response to events:
    leaf_wetness.png


  • Hero Member

    I'll try to power a 3.3V mini pro with a 3xAA batteries holders, and have it lowered to 3.3V with an AMS1117.

    Sensor resistance seems to lower when there is humidit on the holder as expected. I have 735 as analogRead when it is dry.


  • Hero Member

    First test yesterday, device is well powered, device presentation ok, but afterward nothing was mesured... to be investigated on connexions...


  • Hero Member

    hmmm... difficult to make it work on batteries... AND the gas sensors overloading the radio.... now I have it functional.


  • Hero Member

    @epierre

    What do you mean the gas sensor overloaded the radio?


  • Hero Member

    @ServiceXp just that I have a Mega sketch with 7 sensors reporting too frequently one one side, and on the other the weservice call was too slow, making me think of no transmission, but it was delayed in fact...


  • Hero Member

    Some experiments:

    • I left it on a window border, it varied by one ohm on the night.
    • radio close is ok with the basic antenna.
    • i'll try to see to put it further outside, at the moment there are more than 10ยฐC difference along with wet cars on the morning. I fear the rain drop may not be enough sensible...

    There is an alternative to the expensive davis one: LEAF WETNESS SENSOR

    I'll modify the sketch to report a percentage, as other humidity sensors would do.

    Some interresting discussion:

    • 200 KOmhs = very dry leaf
    • 20 KOmhs = slew fog
    • 5 KOhms = heavy rain

    About oxydation, dfrobot has one ground probe with this explanation:

    Immersion Gold which protects the nickel from oxidation. Electroless nickel immersion gold (ENIG) has several advantages over more conventional (and cheaper) surface platings such as HASL (solder)


  • Hero Member

    some returns:

    • from Sept 11th to 15th, the batteries (3*1.5V) went from 4.5V to 3.2 as mesured today, it stopped emitting on sept 15th
    • the leaf sensor shows heavy signs of oxydation without any rain during the period... this is a real problem with all those copies around... that is not a very viable solution...
      IMG_20140918_205949.jpg

    I've seen another product from Spain at Liebllium that I guess I will test for I haven't found any other item...


  • Mod

    @epierre said:

    heavy signs of oxydation

    You're definitely not the first to report this.... I've read many negative reviews of these cheap sensors.


  • Hero Member

    @Yveaux but finding good one seems to be .... very difficult... I've spoken of immersive gold... will try to see if those are better....


  • Mod

    @epierre any idea why your sensor lasted this short?
    How often did it report its value to the gateway? Was it sleeping in between? Any other sensors connected?


  • Hero Member

    @Yveaux several ideas:

    • it reported every 10000
    • it has no other sensor (this was my first try on batteries...)
    • I had an AMS1117 in entry but I didn't needed it
    • I haven't hacked the 3.3V core with the websites @a-lurker ideas

    I'm waiting for the batteries from my other post because using so fast batteries is not environment friendly...

    Has there been simulation of energy usage for those arduini ? e.g. for a spark core it isadvertized at 500mW


  • Hero Member

    I've finally received from cooking hacks the leaf wetness sensor board that should be better than the one from china...

    It is the one from hobby boards:

    lws1-r2-b__34709_zoom.jpg

    I guess I can recycle the lectronic from the cheap one on this one ?


  • Admin

    It doesn't look much different that the china-ones. Is it gold-plated or something?


  • Hero Member

    yes it is, from the hobby board site it is $2, but it is a quarter the china's size.

    sorry I missed your point, it is gold plated, immersion gold.


  • Hero Member

    Ok, so I made some adjustments from my last try:

    • hobbyboard immersion gold sensor
    • I kept the comparator from the other sensor to facilitate work with the arduino
    • I've added a 18650 LiOn battery (5000mAh) to have an extended life cycle

    Here is the sketch:
    https://github.com/empierre/arduino/blob/master/LeafWetnessSensor.ino

    What I can say, is that it is very sensitive. It is now outside live in the cold.

    This could be used for a leak sensor easily.


  • Hero Member

    so my 5000mAh lasted outside... 4 days... btw I didn't remove all leds from the comparator that could be an improvement and the outside weather is quite cold.

    I had a reading every 30 secs, way to quick surely...

    @hek is there a way to power the radio only when necessary ? I guess the gw.sleep could be a gw.sleep and a gw.wakeup and manage the delay outside ?


  • Admin

    @epierre

    gw.sleep() sleeps the radio as well. What do you mean by power down radio? Like cutting power using digital pin?


  • Hero Member

    @hek said:

    @epierre

    gw.sleep() sleeps the radio as well. What do you mean by power down radio? Like cutting power using digital pin?
    yes, now you combine sleep for the radio and delay, what I mean is to have loop() run without radio, and if a transmission is needed to have a command that power it.

    If you have a long dry period, a device on battery will consume a lot of power having the radion on and off, if it is always off until a sensor finds something, that would save more power, no ?


  • Hero Member

    Wake only on interrupt?


  • Hero Member

    In my idea, a value above 0 would mean sending the info, an interrupt could be generated this way ?



  • Hey,
    I am a newbie (in the forum) and in the arduino/sensors development. I bought the Leaf Wetness from cooking-hacks.com. Can I connected it to my Arduino via Analog input? Is it easy?


  • Hero Member

    @elisavetgrig Welcome to the forum. The answer is yes to both questions. Given that the sensor is a resistive element, you need to build a voltage divider. Google "voltage divider" Arduino and you'll find lots of examples.

    Cheers
    Al


  • Hardware Contributor

    Measuring the current with DC doesn't seem to be the ideal solution:
    thread


  • Hero Member

    @FotoFieber That thread is regarding soil moisture measurements which is different than leaf wetness. For soil, capacitive is the best way to go IMHO.

    Cheers
    Al


  • Hardware Contributor



  • ok...Thank you... I will try the "voltage divider" and I will see what will happen!



  • assembly.jpg



  • Did you mean something like the figure above? Or I only need to connect one resistor to one wire and the other wire to another pin in the Arduino?


  • Hero Member

    @elisavetgrig You're missing the connections to a voltage source and ground. You also only need one resistor as the wetness sensor is the 2nd resistor in the voltage divider circuit. Take a look at this: http://homepage.cs.uri.edu/faculty/hamel/workshops/as220-sept-09/sensors-voltage-dividers.html.

    Cheers
    Al



  • You are right! I thought that I missing something... always there are Data connection, VCC connection and GND.. and I had only one! I made another dummy scheme... Is that better?leaf wetness.jpg


  • Hero Member

    @elisavetgrig Take a look at the second diagram of the link I posted. Right now you show the GND pin connected to the Analog pin and Vcc is also connected to the same spot, so that's not going to work.

    Cheers
    Al



  • I based in the second diagram... i think that I understand it... resistorss-leaf wet.png


  • Hero Member

    @elisavetgrig As I mentioned a few posts ago and how it's shown in the diagram on that link, is that you only need one resistor. The leaf wetness sensor becomes the other resistor in the circuit. In your last diagram, you have both the terminals of the wetness sensor connected to ground. Think of the wetness sensor as a resistor, with each of the terminals representing one leg of a regular resistor.

    Cheers
    Al



  • OK... So I need only one resister... I think that "Scheme 2" is closer to the solution... images ofs.jpg



  • @epierre how is the gold plating holding out on the sensor?
    Is there pitting and would you'd recommend this over the style in the store?
    How is the battery life with this setup?

    Thanks


  • Hero Member

    Hello,

    gold plating is a must have for outdoor.

    I am now regarding to have something more robust in time , I'm waiting for a light with movement with solar pannel to modify it for it.


  • Hero Member

    In the case described there is a constant battery drain when there is "wetness" (moisture) on the sensor. This also implies an electrolytic process which takes care of eroding your sensor. No matter if you use gold plating or not.

    electrolysis.jpg

    To avoid both you can supply the sensor during measurement only -and- reverse te polarity each time.

    An example ketch which takes care of measuring three moisture sensors which relies on this principle.

    (the actual measurement is in the "ReadMoistureValues()" routine)

    /*
     PROJECT: MySensors / Floor moisture sensor - measures moisture
     PROGRAMMER: AWI
     DATE: june 7, 2015/ last update: june 9, 2015
     FILE: AWI_FloorMoisture.ino
     LICENSE: Public domain
    
     Hardware: tbd .- ATmega328p board w/ NRF24l01
    	and MySensors 1.4
    
    	(later: Temp & Humidity - HTU21)
    	
    	
    Special:
    	program with Arduino Pro 3.3V 8Mhz
    	
    SUMMARY:
    	Moisture by analog read a polarity switching voltage divider between (high/ low)
     Remarks:
    	Fixed node-id
    */
    
    #include <SPI.h>
    #include <MySensor.h>
    #include <Wire.h> 								// I2C
    
    #define batteryVoltagePin A0
    #define MoistureHighPin 3
    #define MoistureLowPin 4
    #define Moisture1ReadPin A1
    #define Moisture2ReadPin A2
    #define Moisture3ReadPin A3
    #define BuzzerPin 5
    #define LedPin 6
    
    // MySensors Child ID's
    #define MOISTURE1_CHILD_ID 5					// Moisture 1
    #define MOISTURE2_CHILD_ID 6					// Moisture 2
    #define MOISTURE3_CHILD_ID 7					// Moisture 3
    // #define MOISTURE4_CHILD_ID 8					// Moisture 4
    
    // MySensors messages 
    MyMessage moisturePercentageMsg1(MOISTURE1_CHILD_ID, V_HUM);	// Percentage
    MyMessage moisturePercentageMsg2(MOISTURE2_CHILD_ID, V_HUM);	// Percentage
    MyMessage moisturePercentageMsg3(MOISTURE3_CHILD_ID, V_HUM);	// Percentage
    
    // MySensors instantiate 
    MySensor gw(9,10); 								// board, 3.3v (pin default 9,10)
    
    // Reference values for ADC and Battery measurements
    const float VccMin        = 1.0*3.5;    // Minimum expected Vcc level, in Volts. Example for 1 rechargeable lithium-ion.
    const float VccMax        = 1.0*4.2;    // Maximum expected Vcc level, in Volts. 
    float VccReference = 3.3 ;				// voltage reference for measurement (=vcc)
    unsigned long SLEEP_TIME = 60000;  		//  10 sec sleep time between reads (seconds * 1000 milliseconds)
    
    // **** class for Moisture measurement *****
    // attaches an analog input to a data structure for measurements
    // 			measures % of full scale voltage and scales the range of actual values
    // 			stores current/ min & max values for the sensor
    class MoistureSense
    {
    public:
    	// Create an instance of MoistureSense and initialize (digital & input pin and reference values)
      MoistureSense(uint8_t ReadPin, int LowValue, int HighValue) ; 		// attach to pin and init
      void ReadHigh();								// Read moisture if positive
      void ReadLow();								// Read moisture with polarity inverted
      // average the low/ high readings ang get the moisture percent value
      uint8_t MoisturePercent();
      void ResetMinMax();							// reset min & max values
    
    protected:
      uint8_t _ReadPin ; 							// Hardware Analog Pin number
      int _CurMoisture, _MaxMoisture, _MinMoisture, _Low, _High, _HighValue, _LowValue ;
      uint8_t _curState; 
      };
    
    // to create an instance of MoistureSense and initialize (input pin and reference values)
    MoistureSense::MoistureSense(uint8_t ReadPin, int LowValue, int HighValue) {		// attach to pins and init
    	_ReadPin = ReadPin;
    	_LowValue = LowValue;
    	_HighValue = HighValue;
    	_CurMoisture = _MaxMoisture = _MinMoisture = NULL ;	// min & max in percent
      }
    void MoistureSense::ReadHigh()
     // Read moisture with high polarity (in relation to Gnd)
    {
    	_High = analogRead(_ReadPin);
    }
    void MoistureSense::ReadLow()
     // Read moisture with low polarity (in relation to Vcc)
    {
    	_Low = 1024 - analogRead(_ReadPin);
    }
    void MoistureSense::ResetMinMax()
     // Reset min & max values
    {
    	_MinMoisture = _MaxMoisture = _CurMoisture;
    }
    uint8_t MoistureSense::MoisturePercent()
    // average the low/ high readings ang get the moisture percent value
    {
    	uint8_t reading = constrain(map((_Low + _High)/2, _LowValue, _HighValue, 0, 100),0,100);	// average map to the 0-100% range
    	_MinMoisture = min(reading, _MinMoisture);	// set min and max values
    	_MaxMoisture = max(reading, _MaxMoisture);
    }
    
    // Instantiate moisture sensor objects
    MoistureSense Moisture1(Moisture1ReadPin, 0, 1024); 
    MoistureSense Moisture2(Moisture2ReadPin, 0, 1024); 
    MoistureSense Moisture3(Moisture3ReadPin, 0, 1024); 
    
    void setup(){
      	// MySensors setup (baud 115200)
    	gw.begin(NULL, 21);  // fixed node 21, (final: connected to repeater 3 (living))"
    	// Send the sketch version information to the gateway and Controller
    	gw.sendSketchInfo("AWI FloorMoisture 21", "1.0");
    	gw.present(MOISTURE1_CHILD_ID, S_HUM);			// Present Moisture sensors as humidity
    	gw.present(MOISTURE2_CHILD_ID, S_HUM);			// Present Moisture sensors as humidity
    	gw.present(MOISTURE3_CHILD_ID, S_HUM);			// Present Moisture sensors as humidity
    
    	Serial.print("AWI Moisture Started ");
    	pinMode(BuzzerPin,OUTPUT);						// Setup intermittent buzzer & light
    	pinMode(LedPin,OUTPUT);
    }
    
    void loop(){
    //
    	Serial.println("Moisture Percentages");
    	ReadMoistureValues();
    	gw.send(moisturePercentageMsg1.set(Moisture1.MoisturePercent())); // MySensors Send (V) 
    	gw.send(moisturePercentageMsg2.set(Moisture2.MoisturePercent())); // MySensors Send (V) 
    	gw.send(moisturePercentageMsg3.set(Moisture3.MoisturePercent())); // MySensors Send (V) 
    	gw.sendBatteryLevel(batteryPercentage());
    	// show local alarm if moisture > 20%
    	if ((Moisture1.MoisturePercent()>20) || (Moisture2.MoisturePercent()>20) || 
    		(Moisture3.MoisturePercent()>20) || (batteryPercentage() < 10))
    	{
    		MoistureAlarm();
    	}
    	gw.sleep(SLEEP_TIME);							// low power for sleep time
    }
    
    unsigned ReadMoistureValues()
    // read all moisturevalues
    {
    	pinMode(MoistureLowPin, OUTPUT);				// first set all pins to measurement(non floating) mode
    	pinMode(MoistureHighPin, OUTPUT);
    	digitalWrite(MoistureLowPin, LOW); 				// Set polarity on voltage divider high and read the values
    	digitalWrite(MoistureHighPin, HIGH); delayMicroseconds(100);
    	Moisture1.ReadLow(); delayMicroseconds(100);
    	Moisture2.ReadLow(); delayMicroseconds(100);
    	Moisture3.ReadLow(); delayMicroseconds(100);
    	digitalWrite(MoistureLowPin, HIGH);				// reverse polarity on voltage divider and read values
    	digitalWrite(MoistureHighPin, LOW); delayMicroseconds(100);
    	Moisture1.ReadHigh(); delayMicroseconds(100);
    	Moisture2.ReadHigh(); delayMicroseconds(100);
    	Moisture3.ReadHigh(); delayMicroseconds(100);
    	pinMode(MoistureLowPin, INPUT);					// reset pins to floating, to avoid power leakage
    	pinMode(MoistureHighPin, INPUT);
    	Serial.print("Moist1: ");
    	Serial.print(Moisture1.MoisturePercent());
    	Serial.print(" , Moist2: ");
    	Serial.print(Moisture2.MoisturePercent());
    	Serial.print(" , Moist3: ");
    	Serial.print(Moisture3.MoisturePercent());
    	Serial.println();
     }
    
    unsigned MoistureAlarm()
    // If moisturelevel to high, sound & show local alarm
    {
    	digitalWrite(MoistureLowPin, HIGH);
    	digitalWrite(MoistureHighPin, HIGH); 
    	delay(100);										// sound & light for 100ms, uses a lot of power, so no no need for power down
    	digitalWrite(MoistureLowPin, LOW);	
    	digitalWrite(MoistureHighPin, LOW);
    }
    
    // get Battery Voltage & charge current
    // assumes a balanced voltage divider on Battery and uses the Vcc as reference (3.3V in this case)
    // Parameters:
    // - VccMin = minimum battery voltage
    // - VccMax = maximum battery voltage
    // - VccReference = reference voltage for ADC
    uint8_t batteryPercentage()
    {
    	float batteryVoltage = ((float)analogRead(batteryVoltagePin)* VccReference/1024) * 2;	// actual voltage is double
    	Serial.print("Batt: ");
    	Serial.print(batteryVoltage);
    	Serial.print("V ; ");
    	return(constrain(map(batteryVoltage, VccMin, VccMax, 0, 100),0,100));	// and map to the 0-100% range
    }
    

  • Admin

    This is a great idea to get less erosion!


  • Hero Member

    @AWI your sketch has 3 sensors ? do you use a special wiring or you just get through high and low ?

    The sketch on soil humidity does this but with two pins to make kind of AC current, but it needs also some gypsum to protect the electrodes.

    . Leaf wetness is not immersed by nature hopefully ๐Ÿ˜‰


  • Hero Member

    @epierre It has 3 sensors with copper wiring. It switches the polarity of the voltage divider (1 Mohm in series with the "sensor") and measures the voltage over the sensor. Actualy it is a moisture alarm for a sensitive wooden floor.

    and I learned something today ๐Ÿ˜
    "Gypsum is a soft sulfate mineral composed of calcium sulfate dihydrate, with the chemical formula CaSO4ยท2H2O"


  • Hero Member

    @AWI You can call it also "Plaster of Paris" ๐Ÿ˜‰

    When immersed you need to protect it whatever you do : http://vanderleevineyard.com/1/category/vinduino/1.html


  • Hero Member

    @awi going back to you above sketch, what is your wiring ?

    #define MoistureHighPin 3
    #define MoistureLowPin 4
    #define Moisture1ReadPin A1
    #define Moisture2ReadPin A2
    #define Moisture3ReadPin A3
    

  • Hero Member

    Hello,

    I guess it is the same as Vinduino :

    4533105.jpg

    with their test code:

    // This program tests 3 soil sensor inputs and prints bias caused by galvanic effects
    // Copyright (C) 2015, Reinier van der Lee
    // www.vanderleevineyard.com
    
    
    // This program is free software: you can redistribute it and/or modify
    // it under the terms of the GNU General Public License as published by
    // the Free Software Foundation, either version 3 of the License, or
    // any later version.
    
    // This program is distributed in the hope that it will be useful,
    // but WITHOUT ANY WARRANTY; without even the implied warranty of
    // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    // GNU General Public License for more details.
    
    #include <math.h>       // Conversion equation from resistance to %
    
    
    // Setting up format for reading 3 soil sensors
    #define NUM_READS 10    // Number of sensor reads for filtering
    long buffer[NUM_READS];
    int index;
    
    typedef struct {        // Structure to be used in percentage and resistance values matrix to be filtered (have to be in pairs)
      int moisture;
      long resistance;
    } values;
    
    
    const long knownResistor = 1500;  // Constant value of known resistor in Ohms
    
    int supplyVoltage;                // Measured supply voltage
    int sensorVoltage;                // Measured sensor voltage
    
    values valueOf[NUM_READS];        // Calculated moisture percentages and resistances to be sorted and filtered
    
    
    int i;                            // Simple index variable
    
    
    void setup() {
      // initialize serial communications at 9600 bps:
      Serial.begin(115200); 
        
    
      // initialize the digital pins as an output.
      // Pin 6,7 is for sensor 1
      pinMode(6, OUTPUT);    
      pinMode(7, OUTPUT); 
     
      
    }
    
    void loop() {
      
     
    
    measure(1,6,7,1);
    Serial.print ("\t");
    Serial.println (average());
    long read1 = average();
    
    measure(1,7,6,0);
    Serial.print ("\t");
    Serial.println (average());
    long read2= average();
    
    long sensor1 = (read1 + read2)/2;
    
    Serial.print ("resistance bias =" );
    Serial.println (read1-read2);
    Serial.print ("sensor bias compensated value = ");
    Serial.println (sensor1);
    Serial.println ();
    
     delay (3000);
    
    }
    
    void measure (int sensor, int phase_b, int phase_a, int analog_input)
    {
     
      // read sensor, filter, and calculate resistance value
      // Noise filter: median filter
    
      for (i=0; i<NUM_READS; i++) {
    
        // Read 1 pair of voltage values
        digitalWrite(phase_a, HIGH);                 // set the voltage supply on
        delayMicroseconds(25);
        supplyVoltage = analogRead(analog_input);   // read the supply voltage
        delayMicroseconds(25);
        digitalWrite(phase_a, LOW);                  // set the voltage supply off 
        delay(1);
         
        digitalWrite(phase_b, HIGH);                 // set the voltage supply on
        delayMicroseconds(25);
        sensorVoltage = analogRead(analog_input);   // read the sensor voltage
        delayMicroseconds(25);
        digitalWrite(phase_b, LOW);                  // set the voltage supply off 
    
        // Calculate resistance
        // the 0.5 add-term is used to round to the nearest integer
        // Tip: no need to transform 0-1023 voltage value to 0-5 range, due to following fraction
        long resistance = (knownResistor * (supplyVoltage - sensorVoltage ) / sensorVoltage)-457 ;
        
        delay(1); 
        addReading(resistance);
        Serial.print (resistance); 
        Serial.print ("\t");
      }
      }
      
    
    
    // Averaging algorithm
    void addReading(long resistance){
      buffer[index] = resistance;
      index++;
      if (index >= NUM_READS) index = 0;
    }
    
    long average(){
      long sum = 0;
      for (int i = 0; i < NUM_READS; i++){
        sum += buffer[i];
      }
      return (long)(sum / NUM_READS);
    }
    

    and my hall of fame and shame of sensors I've tried :

    IMG_20150801_083113.jpg


Log in to reply
 

Suggested Topics

0
Online

11.2k
Users

11.1k
Topics

112.5k
Posts