Help with irrigation schedule sketch

Hi everyone,

I am quite new to Arduino programming and got stuck with my plant irrigation project with 4 soil moisture sensors. The aim ist to design an irrigation schedule that does nothing until one of the soil sensors shows a moisture below 30%. When soil moisture of one oft he sensors is below 30% the corresponding relay should start a water pump for 1,5 seconds and then stop again. This should be repeated until a soil moisture of 50% is reached.

My code does not work properly, when I run it, at first everything is fine, it reads the soil sensor values and displays them on the serial montor properly. When sensor1 drops below 30% then relay1 starts pump1 for 1.5 seconds, returnes the moisture status and repeats this until soil moisture of 50% is detected. However, when sensor 2,3,4 drop below 30%, the arduino only returns the current state oft he soil moisture, appart from that nothing happens. Pump 2,3,4 do not turn on and I dont know why.

Can anybody help me please?

thank you and best wishes

DJ Greenhouse

Irrigation_Sketch.ino (11.3 KB)

Hi,
Welcome to the forum.

Please read the post at the start of any forum , entitled "How to use this Forum".
OR
http://forum.arduino.cc/index.php/topic,148850.0.html.
Then look down to item #7 about how to post your code.
It will be formatted in a scrolling window that makes it easier to read.

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Thanks.. Tom... :slight_smile:

Okay sorry, here is the void and loop part of the code:

 void setup() {

 pinMode(moistureSensor1, INPUT);
 pinMode(moistureSensor2, INPUT);
 pinMode(moistureSensor3, INPUT);
 pinMode(moistureSensor4, INPUT);

 pinMode(WaterPump1, OUTPUT);
 pinMode(WaterPump2, OUTPUT);
 pinMode(WaterPump3, OUTPUT);
 pinMode(WaterPump4, OUTPUT);

 Serial.begin(9600);

 // Set Calibration Values obtained during Calibration
 
 AirValue1 = 589;                                      // Use Calibration Algorithm to determine AirValue
 AirValue2 = 589;                                      // Use Calibration Algorithm to determine AirValue
 AirValue3 = 588;                                      // Use Calibration Algorithm to determine AirValue
 AirValue4 = 588;                                      // Use Calibration Algorithm to determine AirValue
 
 WaterValue1 = 307;                                    // Use Calibration Algorithm to determine WaterValue
 WaterValue2 = 310;                                    // Use Calibration Algorithm to determine WaterValue
 WaterValue3 = 320;                                    // Use Calibration Algorithm to determine WaterValue
 WaterValue4 = 310;                                    // Use Calibration Algorithm to determine WaterValue


// Set the Watring intervals and Thresholds

 WaterTime1 = 1500;                                    // Duration of active water flow (in milliseconds)
 WaterTime1 = 1500;                                    // Duration of active water flow (in milliseconds)
 WaterTime1 = 1500;                                    // Duration of active water flow (in milliseconds)
 WaterTime1 = 1500;                                    // Duration of active water flow (in milliseconds)
 
 WaterInt1 = 9000;                                     // Intervall time between water flow (in milliseconds)
 WaterInt2 = 9000;                                     // Intervall time between water flow (in milliseconds)
 WaterInt3 = 9000;                                     // Intervall time between water flow (in milliseconds)
 WaterInt4 = 9000;                                     // Intervall time between water flow (in milliseconds)

 ThresholdStart1 = 30;                                 // Threshold Soil Moisture at wich irrigation starts                               
 ThresholdStart2 = 30;                                 // Threshold Soil Moisture at wich irrigation starts                      
 ThresholdStart3 = 30;                                 // Threshold Soil Moisture at wich irrigation starts                               
 ThresholdStart4 = 30;                                 // Threshold Soil Moisture at wich irrigation starts                               

 ThresholdStop1 = 50;                                  // Threshold Soil Moisture at wich irrigation stops                                
 ThresholdStop2 = 50;                                  // Threshold Soil Moisture at wich irrigation stops                                
 ThresholdStop3 = 50;                                  // Threshold Soil Moisture at wich irrigation stops                                
 ThresholdStop4 = 50;                                  // Threshold Soil Moisture at wich irrigation stops   
 
 SamplingTime =  15000;                            

}

void loop() {

  digitalWrite(WaterPump1,HIGH);
  digitalWrite(WaterPump2,HIGH);
  digitalWrite(WaterPump3,HIGH);
  digitalWrite(WaterPump4,HIGH);
  
  sensorValue1 = analogRead(moistureSensor1);
  sensorValue2 = analogRead(moistureSensor2);
  sensorValue3 = analogRead(moistureSensor3);
  sensorValue4 = analogRead(moistureSensor4);
  SoilMoisture1 = map(sensorValue1,AirValue1,WaterValue1,0,100);
  SoilMoisture2 = map(sensorValue2,AirValue2,WaterValue2,0,100);
  SoilMoisture3 = map(sensorValue3,AirValue3,WaterValue3,0,100);
  SoilMoisture4 = map(sensorValue4,AirValue4,WaterValue4,0,100);
  
  Serial.print("Soil_Moisture_1(%):");
  Serial.print("\t");
  Serial.print("Soil_Moisture_2(%):");
  Serial.print("\t");
  Serial.print("Soil_Moisture_3(%):");
  Serial.print("\t");
  Serial.print("Soil_Moisture_4(%):");
  Serial.println();

  while (SoilMoisture1 >= ThresholdStart1 && SoilMoisture2 >= ThresholdStart2 && SoilMoisture3 >= ThresholdStart3 && SoilMoisture4 >= ThresholdStart4) {
                  
                  Serial.print(SoilMoisture1);
                  Serial.print("                \t");
                  Serial.print(SoilMoisture2);
                  Serial.print("                \t");
                  Serial.print(SoilMoisture3);
                  Serial.print("                \t");
                  Serial.print(SoilMoisture4);
                  Serial.println();
                  
                  delay(SamplingTime);
                  
                  sensorValue1 = analogRead(moistureSensor1);
                  sensorValue2 = analogRead(moistureSensor2);
                  sensorValue3 = analogRead(moistureSensor3);
                  sensorValue4 = analogRead(moistureSensor4);
                  SoilMoisture1 = map(sensorValue1,AirValue1,WaterValue1,0,100);
                  SoilMoisture2 = map(sensorValue2,AirValue2,WaterValue2,0,100);
                  SoilMoisture3 = map(sensorValue3,AirValue3,WaterValue3,0,100);
                  SoilMoisture4 = map(sensorValue4,AirValue4,WaterValue4,0,100);
                  
                  }


   
     if(SoilMoisture1 < ThresholdStart1){
      
              while(SoilMoisture1 < ThresholdStop1){ 
                 digitalWrite(WaterPump1,LOW);
                 delay(WaterTime1);
                 digitalWrite(WaterPump1,HIGH);
                 delay(WaterInt1);
                 sensorValue1 = analogRead(moistureSensor1);
                 SoilMoisture1 = map(sensorValue1,AirValue1,WaterValue1,0,100);
                 Serial.print("Moisture1: ");
                 Serial.print(SoilMoisture1);
                 Serial.println("%");
                  }
                 }  
   
    else if(SoilMoisture2 < ThresholdStart2){
      
              while(SoilMoisture2 < ThresholdStop2){ 
                 digitalWrite(WaterPump2,LOW);
                 delay(WaterTime2);
                 digitalWrite(WaterPump2,HIGH);
                 delay(WaterInt2);
                 sensorValue2 = analogRead(moistureSensor2);
                 SoilMoisture2 = map(sensorValue2,AirValue2,WaterValue2,0,100);
                 Serial.print("Moisture2:");
                 Serial.print(SoilMoisture2);
                 Serial.println("%");                 
                  }
                 }

     else if(SoilMoisture3 < ThresholdStart3){
      
              while(SoilMoisture3 < ThresholdStop3){ 
                 digitalWrite(WaterPump3,LOW);
                 delay(WaterTime3);
                 digitalWrite(WaterPump3,HIGH);
                 delay(WaterInt3);
                 sensorValue3 = analogRead(moistureSensor3);
                 SoilMoisture3 = map(sensorValue3,AirValue3,WaterValue3,0,100);
                 Serial.print("Moisture3:");
                 Serial.print(SoilMoisture3);
                 Serial.println("%");
                  }
                 }
   
      else if(SoilMoisture4 < ThresholdStart4){
      
              while(SoilMoisture4 < ThresholdStop4){ 
                 digitalWrite(WaterPump4,LOW);
                 delay(WaterTime4);
                 digitalWrite(WaterPump4,HIGH);
                 delay(WaterInt4);
                 sensorValue4 = analogRead(moistureSensor4);
                 SoilMoisture4 = map(sensorValue4,AirValue4,WaterValue4,0,100);
                 Serial.print("Moisture4:");
                 Serial.print(SoilMoisture4);
                 Serial.println("%");
                  }
                 }
     
      else delay(SamplingTime);
  
     }

and here is a picture of the circuit as provided by the manufacturer.

Thank you TomGeorge for your hints on proper posting. The code was too long to post completely.

I don’t understand this bit:

  else if (SoilMoisture2 < ThresholdStart2)

Why did you use else if? I would expect that pump2 would be independent of pump1. As you have it, you only check pump2 if pump1 isn’t flowing water. Get rid of the else, just use a standalone if. Same for the other pumps too.

Dj_Greenhouse:
Thank you TomGeorge for your hints on proper posting. The code was too long to post completely.

Okay, you can attach the ino file to your post.
Tom... :slight_smile:

Hi,
OPs schematic.


Have you got your pump wiring well away from the sensor wiring.
Can I suggest a 0.1uF capacitor across each of the pump terminals, to help minimise electrical noise from the motors.

A picture of your project will help, as we can see your component layout.
Tom... :slight_smile:

Hi,
Can I suggest you change;

sensorValue1 = analogRead(moistureSensor1);
sensorValue2 = analogRead(moistureSensor2);
sensorValue3 = analogRead(moistureSensor3);
sensorValue4 = analogRead(moistureSensor4);

To;

sensorValue1 = analogRead(moistureSensor1);
sensorValue1 = analogRead(moistureSensor1);
sensorValue2 = analogRead(moistureSensor2);
sensorValue2 = analogRead(moistureSensor2);
sensorValue3 = analogRead(moistureSensor3);
sensorValue3 = analogRead(moistureSensor3);
sensorValue4 = analogRead(moistureSensor4);
sensorValue4 = analogRead(moistureSensor4);

The controller only has one ADC, it has to switch to each input to read the analog level.
The ADC has a capacitor on its input that charges to the selected input, this takes time.
If you switch quickly, the capacitor will not have time to change its charge from one channel to the next.
By double reading, you only take the second value of each channel you give time for the charge to stabilise, which is more representative of the input being sampled.

Tom.... :slight_smile:

op's

WaterTime1 = 1500; // Duration of active water flow (in milliseconds)
WaterTime1 = 1500; // Duration of active water flow (in milliseconds)
WaterTime1 = 1500; // Duration of active water flow (in milliseconds)
WaterTime1 = 1500; // Duration of active water flow (in milliseconds)

wildbill:
I don’t understand this bit:

  else if (SoilMoisture2 < ThresholdStart2)

Why did you use else if? I would expect that pump2 would be independent of pump1. As you have it, you only check pump2 if pump1 isn’t flowing water. Get rid of the else, just use a standalone if. Same for the other pumps too.

Hi wildbill,

thank you for your help. I was just trying different combinations of if and else if, but the result was not changed. Also I wanted only one pump to run at a time, so I think I must use else if, or not?

The moment you feel the need to use numbers in variable names, you’re due to learn about arrays.

Then the code of #8 can become:

for (uint8_t i = 0; i < nSensors; i++) {
  sensorValue[i] = analogRead(moistureSensor[i]);
  sensorValue[i] = analogRead(moistureSensor[i]);
}

where nSensors is the number of sensors (4 for you); makes your code more readable and makes it very easy to add or remove sensors later.

Still no need for else if. IIRC, you're using delay to control water flow, so pump one will be off by the time you check moisture for pump two.

dave-in-nj:
op’s

WaterTime1 = 1500; // Duration of active water flow (in milliseconds)
WaterTime1 = 1500; // Duration of active water flow (in milliseconds)
WaterTime1 = 1500; // Duration of active water flow (in milliseconds)
WaterTime1 = 1500; // Duration of active water flow (in milliseconds)

Hi dave-in-nj,

thank you for your help, this solved the probem. I dont know why I did not see that myself

TomGeorge:
Hi,
Can I suggest you change;

sensorValue1 = analogRead(moistureSensor1);

sensorValue2 = analogRead(moistureSensor2);
sensorValue3 = analogRead(moistureSensor3);
sensorValue4 = analogRead(moistureSensor4);



To;



sensorValue1 = analogRead(moistureSensor1);
sensorValue1 = analogRead(moistureSensor1);
sensorValue2 = analogRead(moistureSensor2);
sensorValue2 = analogRead(moistureSensor2);
sensorValue3 = analogRead(moistureSensor3);
sensorValue3 = analogRead(moistureSensor3);
sensorValue4 = analogRead(moistureSensor4);
sensorValue4 = analogRead(moistureSensor4);



The controller only has one ADC, it has to switch to each input to read the analog level.
The ADC has a capacitor on its input that charges to the selected input, this takes time.
If you switch quickly, the capacitor will not have time to change its charge from one channel to the next.
By double reading, you only take the second value of each channel you give time for the charge to stabilise, which is more representative of the input being sampled.

Tom.... :)

Hi Tom,

thank you for your suggestion. I will try it out. Here some pictures of the Project so far. I did not connect the pumps yet.

wvmarle:
The moment you feel the need to use numbers in variable names, you’re due to learn about arrays.

Then the code of #8 can become:

for (uint8_t i = 0; i < nSensors; i++) {

sensorValue[i] = analogRead(moistureSensor[i]);
 sensorValue[i] = analogRead(moistureSensor[i]);
}




where nSensors is the number of sensors (4 for you); makes your code more readable and makes it very easy to add or remove sensors later.

Hi wvmarle,

thank you so much for this. I was going to ask about those “for” loops next.

thx :smiley:

wildbill:
Still no need for else if. IIRC, you're using delay to control water flow, so pump one will be off by the time you check moisture for pump two.

okay, yes I see. i remoed the else

TomGeorge:
Hi,
OPs schematic.


Have you got your pump wiring well away from the sensor wiring.
Can I suggest a 0.1uF capacitor across each of the pump terminals, to help minimise electrical noise from the motors.

A picture of your project will help, as we can see your component layout.
Tom... :slight_smile:

thank you Tom, wher exactly do I have to connect those capaitors?

it would seem that your pump logic can be rather simple

int pump1run, pump2run, pump3run, pump4run;


if (sensorValue1 <=  ThresholdStart1 )  pump1run = 1 ; 
if (sensorValue2 <=  ThresholdStart2 )  pump2run = 1 ; 
if (sensorValue3 <=  ThresholdStart3 )  pump3run = 1 ;
if (sensorValue4 <=  ThresholdStart4 )  pump4run = 1 ;

if (sensorValue1 >= ThresholdStop1 )  pump1run = 0  ;
if (sensorValue2 >= ThresholdStop2 )  pump1run = 0  ;
if (sensorValue3 >= ThresholdStop3 )  pump1run = 0  ;
if (sensorValue4 >= ThresholdStop4 )  pump1run = 0  ;


if ( pump1run == 1 ) {
   digitalWrite(WaterPump1,LOW); 
   delay(WaterTime1); 
   digitalWrite(WaterPump1,HIGH);
}

if ( pump2run == 1 ) {
   digitalWrite(WaterPump2,LOW); 
   delay(WaterTime2); 
   digitalWrite(WaterPump2,HIGH);
}

if ( pump3run == 1 ) {
   digitalWrite(WaterPump3,LOW); 
   delay(WaterTime3); 
   digitalWrite(WaterPump3,HIGH);
}

if ( pump4run == 1 ) {
   digitalWrite(WaterPump4,LOW); 
   delay(WaterTime4); 
   digitalWrite(WaterPump4,HIGH);
}

since each motor runs, times out, then is turrned off, none would be able to run at the same time.

Hi,
Thanks for the pics.



The caps are across the two wires each going to the pump motors.

Tom.... :slight_smile: