One adruino four soil moisture sensors



  • Hi everybody,
    I just begin with adruino and mysensors, i dont have my equipement yet (thank ebay) but i try to prepare my code.
    I want to make a soil moisture sensor, the tutorial is pretty clear but after some research on the forum an im not sure about how to connect 4 soil moisture sensors.
    Can anyone can tell me if my code look ok ? Im a bit a noob and not sure about my Child-id management...
    Thanks in adavance !

    /**
     * The MySensors Arduino library handles the wireless radio link and protocol
     * between your home built sensors/actuators and HA controller of choice.
     * The sensors forms a self healing radio network with optional repeaters. Each
     * repeater and gateway builds a routing tables in EEPROM which keeps track of the
     * network topology allowing messages to be routed to nodes.
     *
     * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
     * Copyright (C) 2013-2015 Sensnology AB
     * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
     *
     * Documentation: http://www.mysensors.org
     * Support Forum: http://forum.mysensors.org
     *
     * This program is free software; you can redistribute it and/or
     * modify it under the terms of the GNU General Public License
     * version 2 as published by the Free Software Foundation.
     *
     *******************************
     *
     * REVISION HISTORY
     * Version 1.0 - Henrik Ekblad
     *
     * DESCRIPTION
     * Example sketch sending soil moisture alarm to controller
     * http://www.mysensors.org/build/moisture
     */
    
    #include <SPI.h>
    #include <MySensor.h>
    
    #define DIGITAL_INPUT_SOIL_SENSOR 3   // Digital input did you attach your soil sensor.
    #define DIGITAL_INPUT_SOIL_SENSOR1 4   // Digital input did you attach your soil sensor. 
    #define DIGITAL_INPUT_SOIL_SENSOR2 5   // Digital input did you attach your soil sensor. 
    #define DIGITAL_INPUT_SOIL_SENSOR3 6   // Digital input did you attach your soil sensor.   
    #define INTERRUPT DIGITAL_INPUT_SOIL_SENSOR-2 // Usually the interrupt = pin -2 (on uno/nano anyway)
    #define CHILD_ID 0   // Id of the sensor child
    #define CHILD_ID_1 1 // moist sensor 2
    #define CHILD_ID_2 2 // moist sensor 3
    #define CHILD_ID_3 3 // moist sensor 4
    
    MySensor gw;
    MyMessage msg(CHILD_ID, V_TRIPPED);
    int lastSoilValue = -1;
    MyMessage msg1(CHILD_ID_1, V_TRIPPED);
    int lastSoilValue1 = -1;
    MyMessage msg2(CHILD_ID_2, V_TRIPPED);
    int lastSoilValue2 = -1;
    MyMessage msg3(CHILD_ID_3, V_TRIPPED);
    int lastSoilValue3 = -1;
    
    void setup()
    {
      gw.begin();
    
      // Send the sketch version information to the gateway and Controller
      gw.sendSketchInfo("Soil Moisture Sensor", "1.0");
      // sets the soil sensor digital pin as input
      pinMode(DIGITAL_INPUT_SOIL_SENSOR, INPUT);
      pinMode(DIGITAL_INPUT_SOIL_SENSOR1, INPUT);
      pinMode(DIGITAL_INPUT_SOIL_SENSOR2, INPUT);
      pinMode(DIGITAL_INPUT_SOIL_SENSOR3, INPUT);
      // Register all sensors to gw (they will be created as child devices)
      gw.present(CHILD_ID, S_MOTION);
      gw.present(CHILD_ID_1, S_MOTION);
      gw.present(CHILD_ID_2, S_MOTION);
      gw.present(CHILD_ID_3, S_MOTION);
    
    }
    
    void loop()
    {
      // Read digital soil value
      int soilValue = digitalRead(DIGITAL_INPUT_SOIL_SENSOR); // 1 = Not triggered, 0 = In soil with water
      if (soilValue != lastSoilValue) {
        Serial.println(soilValue);
        gw.send(msg.set(soilValue == 0 ? 1 : 0)); // Send the inverse to gw as tripped should be when no water in soil
        lastSoilValue = soilValue;
      }
      int soilValue1 = digitalRead(DIGITAL_INPUT_SOIL_SENSOR1); // 1 = Not triggered, 0 = In soil with water
      if (soilValue1 != lastSoilValue1) {
        Serial.println(soilValue1);
        gw.send(msg.set(soilValue1 == 0 ? 1 : 0)); // Send the inverse to gw as tripped should be when no water in soil
        lastSoilValue1 = soilValue1;
      }
      int soilValue2 = digitalRead(DIGITAL_INPUT_SOIL_SENSOR2); // 1 = Not triggered, 0 = In soil with water
      if (soilValue2 != lastSoilValue2) {
        Serial.println(soilValue2);
        gw.send(msg.set(soilValue2 == 0 ? 1 : 0)); // Send the inverse to gw as tripped should be when no water in soil
        lastSoilValue2 = soilValue2;
      }
      int soilValue3 = digitalRead(DIGITAL_INPUT_SOIL_SENSOR3); // 1 = Not triggered, 0 = In soil with water
      if (soilValue3 != lastSoilValue3) {
        Serial.println(soilValue3);
        gw.send(msg.set(soilValue3 == 0 ? 1 : 0)); // Send the inverse to gw as tripped should be when no water in soil
        lastSoilValue3 = soilValue3;
      }
      // Power down the radio and arduino until digital input changes.
      gw.sleep(INTERRUPT, CHANGE);
    }
    
    
    
    

  • Admin

    Looks good except interrupt wake from sleep won't work for all soil sensors pins used.

    I'd suggest you just sleep for a few hours and read the pins. Plants usually don't require instant watering 🙂



  • @hek Oh cool ! thank you a lot for your reply, im glad that's its seems to be ok.
    But im really a beginner with arduino, and i need to learn about this awake timer for modifying it, I guess i have to manipuate the variable of the function, maybe one time per hours will be enough (its for an automated growbox)
    But if you have time and would like to help me with that, i would be glad and very thankfull !


  • Admin

    Ok, then replace with

    gw.sleep(60L*60L*1000L)

    (as sleep time is in milliseconds)



  • @hek thank you a lot ! i will learn and read about it for understand it but thank you very much i will test it as soon as i receive my parts.



  • Hi everbody !
    I haved modify this sketch to use analog pin and send moisture in percent every 15min.
    Im not sure about my "gw.send", I think it will send the value of the soil but without the sign "%" how can I do that ?
    thank very much in advance for those who will look at my code

    /**
     * The MySensors Arduino library handles the wireless radio link and protocol
     * between your home built sensors/actuators and HA controller of choice.
     * The sensors forms a self healing radio network with optional repeaters. Each
     * repeater and gateway builds a routing tables in EEPROM which keeps track of the
     * network topology allowing messages to be routed to nodes.
     *
     * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
     * Copyright (C) 2013-2015 Sensnology AB
     * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
     *
     * Documentation: http://www.mysensors.org
     * Support Forum: http://forum.mysensors.org
     *
     * This program is free software; you can redistribute it and/or
     * modify it under the terms of the GNU General Public License
     * version 2 as published by the Free Software Foundation.
     *
     *******************************
     *
     * REVISION HISTORY
     * Version 1.0 - Henrik Ekblad
     *
     * DESCRIPTION
     * Example sketch sending soil moisture alarm to controller
     * http://www.mysensors.org/build/moisture
     */
    
    #include <SPI.h>
    #include <MySensor.h>
    
    #define ANALOG_INPUT_SOIL_SENSOR A0   // Analog input did you attach your soil sensor.
    #define ANALOG_INPUT_SOIL_SENSOR1 A1   // Analog input did you attach your soil sensor. 
    #define ANALOG_INPUT_SOIL_SENSOR2 A2   // Analog input did you attach your soil sensor. 
    #define ANALOG_INPUT_SOIL_SENSOR3 A3   // Analog input did you attach your soil sensor.   
    #define INTERRUPT DIGITAL_INPUT_SOIL_SENSOR-2 // Usually the interrupt = pin -2 (on uno/nano anyway)
    #define CHILD_ID 0   // Id of the sensor child
    #define CHILD_ID_1 1 // moist sensor 2
    #define CHILD_ID_2 2 // moist sensor 3
    #define CHILD_ID_3 3 // moist sensor 4
    
    MySensor gw;
    MyMessage msg(CHILD_ID, V_HUM);
    int lastSoilValue = 0;
    MyMessage msg1(CHILD_ID_1, V_HUM);
    int lastSoilValue1 = 0;
    MyMessage msg2(CHILD_ID_2, V_HUM);
    int lastSoilValue2 = 0;
    MyMessage msg3(CHILD_ID_3, V_HUM);
    int lastSoilValue3 = 0;
    int soil = 0;
    int soil1 = 0;
    int soil2 = 0;
    int soil3 = 0;
    
    void setup()
    {
      gw.begin();
    
      // Send the sketch version information to the gateway and Controller
      gw.sendSketchInfo("Soil Moisture Sensor", "1.0");
      // sets the soil sensor analogique pin as input
      pinMode(ANALOG_INPUT_SOIL_SENSOR, INPUT);
      pinMode(ANALOG_INPUT_SOIL_SENSOR1, INPUT);
      pinMode(ANALOG_INPUT_SOIL_SENSOR2, INPUT);
      pinMode(ANALOG_INPUT_SOIL_SENSOR3, INPUT);
      // Register all sensors to gw (they will be created as child devices)
      gw.present(CHILD_ID, S_HUM);
      gw.present(CHILD_ID_1, S_HUM);
      gw.present(CHILD_ID_2, S_HUM);
      gw.present(CHILD_ID_3, S_HUM);
    
    }
    
    void loop()
    {
      // Read digital soil value
      int soilValue = analogRead(ANALOG_INPUT_SOIL_SENSOR); // Lecture des valeurs du capteur1
      soilValue = constrain(soilValue, 485, 1023); // This is taken from an another project on internet with same type of moisture sensor, i will check this value when i receive my sensors
      soil = map(soilValue, 485, 1023, 100, 0);
      if (soil != lastSoilValue) {
        Serial.print("pot 1 : ");
        Serial.println(soil);
        Serial.print("%");
        gw.send(msg.set(soil)); // Send in percent
        lastSoilValue = soil;
      }
      int soilValue1 = analogRead(ANALOG_INPUT_SOIL_SENSOR1); // Lecture des valeurs du capteur2
      soilValue1 = constrain(soilValue1, 485, 1023);
      soil1 = map(soilValue1, 485, 1023, 100, 0);
      if (soil1 != lastSoilValue1) {
        Serial.print("pot 2 : ");
        Serial.println(soil1);
        Serial.print("%");
        gw.send(msg1.set(soil1)); // Send in percent
        lastSoilValue1 = soil1;
      }
      int soilValue2 = analogRead(ANALOG_INPUT_SOIL_SENSOR2); // Lecture des valeurs du capteur3
      soilValue2 = constrain(soilValue2, 485, 1023);
      soil2 = map(soilValue2, 485, 1023, 100, 0);
      if (soil2 != lastSoilValue2) {
        Serial.print("pot 3 : ");
        Serial.println(soil2);
        Serial.print("%");
        gw.send(msg2.set(soil2)); // Send in percent
        lastSoilValue2 = soil2;
      }
      int soilValue3 = analogRead(ANALOG_INPUT_SOIL_SENSOR3); // // Lecture des valeurs du capteur4
      soilValue3 = constrain(soilValue3, 485, 1023);
      soil3 = map(soilValue3, 485, 1023, 100, 0);
      if (soil3 != lastSoilValue3) {
        Serial.print("pot 4 : ");
        Serial.println(soil3);
        Serial.print("%");
        gw.send(msg3.set(soil3)); // Send in percent
        lastSoilValue3 = soil3;
      }
      gw.sleep(15L*15L*1000L);  // Timer for checkin every 15min
    }
    
    
    
    

    ps: for those who want, here is the link to the project where i took the code to transform in percent the value http://arduinotronics.blogspot.fr/2014/01/when-do-i-water-my-plants-soil.html

    edit
    After some research i found some thread on the forum -> here talking about this moisture sensor, thank to @mfalkvidd for his code.
    I copy this sketch and modify it for my use : no battery for now and add a "if" to it for checking if the value of the moisture have change since the last check (i hope it will save some battery with sending data just when needed)
    I just have one more question if someone know... Can I connect all my sensors (4) to the same power pin (in parallele) ?

    #include <SPI.h>
    #include <MySensor.h>
    
    #define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))
    
    #define CHILD_ID_MOISTURE1 0
    #define CHILD_ID_MOISTURE2 1
    #define CHILD_ID_MOISTURE3 2
    #define CHILD_ID_MOISTURE4 3
    //#define CHILD_ID_BATTERY 1
    #define SENSOR_ANALOG_PIN 0
    #define SENSOR_ANALOG_PIN1 1
    #define SENSOR_ANALOG_PIN2 2
    #define SENSOR_ANALOG_PIN3 3
    #define SENSOR_POWER_PIN 8
    #define SLEEP_TIME 600000 // Sleep time between reads (in milliseconds) (=10 MINUTES)
    #define STABILIZATION_TIME 500 // Let the sensor stabilize before reading
    //#define BATTERY_FULL 3700 // 3,700 millivolts
    //#define BATTERY_ZERO 1700 // 1,700 millivolts
    
    MySensor gw;
    MyMessage msg(CHILD_ID_MOISTURE1, V_HUM);
    MyMessage msg2(CHILD_ID_MOISTURE2, V_HUM);
    MyMessage msg3(CHILD_ID_MOISTURE3, V_HUM);
    MyMessage msg4(CHILD_ID_MOISTURE4, V_HUM);
    //MyMessage voltage_msg(CHILD_ID_BATTERY, V_VOLTAGE);
    int lastsoilValue1 = 0;
    int lastsoilValue2 = 0;
    int lastsoilValue3 = 0;
    int lastsoilValue4 = 0;
    
    void setup()
    {
    	pinMode(SENSOR_POWER_PIN, OUTPUT);
    	gw.begin();
    
    	gw.sendSketchInfo("Plant moisture w bat", "1.1");
    
    	gw.present(CHILD_ID_MOISTURE1, S_HUM);
    	gw.present(CHILD_ID_MOISTURE2, S_HUM);
    	gw.present(CHILD_ID_MOISTURE3, S_HUM);
    	gw.present(CHILD_ID_MOISTURE4, S_HUM);
    	//delay(250);
    	//gw.present(CHILD_ID_BATTERY, S_CUSTOM);
    }
    
    void loop()
    {
    	digitalWrite(SENSOR_POWER_PIN, HIGH); // Power on the sensors
    	
    	gw.sleep(STABILIZATION_TIME); 		//stabilization before mesuring
    	
    	int moistureLevel = (1023 - analogRead(SENSOR_ANALOG_PIN)) / 10.23; // read moisture of the first sensor
    	if (moistureLevel != lastsoilValue1) {								//test if moisture is different than before
    		gw.send(msg.set(moistureLevel));									//send to controller moisture level of sensor 1
    		lastsoilValue1 = moistureLevel;
    	}
    	
    	int moistureLevel1 = (1023 - analogRead(SENSOR_ANALOG_PIN1)) / 10.23; // read moisture of the second sensor
    	if (moistureLevel1 != lastsoilValue2) {									//test if moisture is different than before
    		gw.send(msg2.set(moistureLevel1));									//send to controller moisture level of sensor 2
    		lastsoilValue2 = moistureLevel1;
    	}
    	
    	int moistureLevel2 = (1023 - analogRead(SENSOR_ANALOG_PIN2)) / 10.23; // read moisture of the third sensor
    	if (moistureLevel2 != lastsoilValue3) {									//test if moisture is different than before
    		gw.send(msg3.set(moistureLevel2));									//send to controller moisture level of sensor 3
    		lastsoilValue3 = moistureLevel2;
    	}
    	
    	int moistureLevel3 = (1023 - analogRead(SENSOR_ANALOG_PIN3)) / 10.23; // read moisture of fourth sensor
    	if (moistureLevel3 != lastsoilValue4) {								//test if moisture is different than before
    		gw.send(msg4.set(moistureLevel3));									//send to controller moisture level of sensor 4
    		lastsoilValue3 = moistureLevel3;
    	}
    	
    	//debugging comment it when dont use
    	Serial.print("first plant :");
    	Serial.println(moistureLevel);
    	Serial.print("second plant :");
    	Serial.println(moistureLevel1);
    	Serial.print("third plant :");
    	Serial.println(moistureLevel2);
    	Serial.print("fourth plant :");
    	Serial.println(moistureLevel3);
    	
    	digitalWrite(SENSOR_POWER_PIN, LOW); //spower off sensors
    	
    	//long voltage = readVcc();
    	//gw.send(voltage_msg.set(voltage / 1000.0, 3)); // redVcc returns millivolts and set wants volts and how many decimals (3 in our case)
    	//gw.sendBatteryLevel(round((voltage - BATTERY_ZERO) * 100.0 / (BATTERY_FULL - BATTERY_ZERO)));
    	gw.sleep(SLEEP_TIME);
    }
    
    /*long readVcc()
    {
    	// From http://provideyourown.com/2012/secret-arduino-voltmeter-measure-battery-voltage/
    	// Read 1.1V reference against AVcc
    	// set the reference to Vcc and the measurement to the internal 1.1V reference
    #if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
    	ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
    #elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
    	ADMUX = _BV(MUX5) | _BV(MUX0);
    #elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
    	ADMUX = _BV(MUX3) | _BV(MUX2);
    #else
    	ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
    #endif
    
    	delay(2); // Wait for Vref to settle
    	ADCSRA |= _BV(ADSC); // Start conversion
    	while (bit_is_set(ADCSRA, ADSC)); // measuring
    
    	uint8_t low  = ADCL; // must read ADCL first - it then locks ADCH
    	uint8_t high = ADCH; // unlocks both
    
    	long result = (high << 8) | low;
    
    	result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000
    	return result; // Vcc in millivolts
    }*/```


  • Hi
    I am just in the beginning to build one soil moisture sensor battery powered.

    Any update from your test?



  • @damien
    Is there an update for this sketch to use in V2?


Log in to reply
 

Suggested Topics

1
Online

11.4k
Users

11.1k
Topics

112.7k
Posts