auto water coding help

hey i was wondering if anyone could help me. Im new to Arduino and have set up an auto watering system with individually pumps and sensors. O have also hooked up an LCD to and my code is working and everything is running. I just have a few problems I cant seem to figure out because I just started learning how to code a couple weeks ago. My first problem is that whenever the pump for that specific plant is turned on by the capacitive soil moisture sensor, the sensor turns it off too quickly and the plant doesn't get enough water. My other problems are that I cant figure out how to individually calibrate each sensor in the code and also cant figure out how to print data from sensor1 and sensor 2 on separate rows with the lcd at the same time rather then displaying 1 then 2 then 3 then 4. This is my code and if anyone can help i would be very grateful.

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 10, 9, 8, 7);

const int AirValue = 620;
const int WaterValue = 315;
int intervals = (AirValue - WaterValue)/3;
int soilmoisturepercent=0;
int IN1 = 2;
int IN2 = 3;
int IN3 = 4;
int IN4 = 5;
int Pin1 = A0;
int Pin2 = A1;
int Pin3 = A2;
int Pin4 = A3;
float value1 = 0;
float value2 = 0;
float value3 = 0;
float value4 = 0;
void setup() {
lcd.begin(16, 2);
Serial.begin(9600);
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
pinMode(Pin1, INPUT);
pinMode(Pin2, INPUT);
pinMode(Pin3, INPUT);
pinMode(Pin4, INPUT);
digitalWrite(IN1, HIGH);
digitalWrite(IN2, HIGH);
digitalWrite(IN3, HIGH);
digitalWrite(IN4, HIGH);
delay(500);
}
void loop() {
value1 = analogRead(Pin1);
Serial.println(value1);
soilmoisturepercent = map(value1, AirValue, WaterValue, 0, 100);
if (soilmoisturepercent > 100)
{
Serial.println("100 %");
lcd.setCursor(0, 0);
lcd.print("10th Planet C1:");
lcd.setCursor(0, 1);
lcd.print("100 %");
delay(3000);
lcd.clear();
delay(250);
}
else if (soilmoisturepercent <0)
{
Serial.println("0 %");
lcd.setCursor(0, 0);
lcd.print("10th Planet C1:");
lcd.setCursor(0, 1);
lcd.print("0 %");
delay(3000);
lcd.clear();
delay(250);
}
else if (soilmoisturepercent >0 && soilmoisturepercent < 100)
{
Serial.print(soilmoisturepercent);
Serial.println(" %");
lcd.setCursor(0, 0);
lcd.print("10th Planet C1:");
lcd.setCursor(0, 1);
lcd.print(soilmoisturepercent);
lcd.print(" %");
delay(3000);
lcd.clear();
delay(250);
}
value2 = analogRead(Pin2);
Serial.println(value2);
soilmoisturepercent = map(value2, AirValue, WaterValue, 0, 100);
if (soilmoisturepercent > 100)
{
Serial.println("100 %");
lcd.setCursor(0, 0);
lcd.print("10th Planet C2:");
lcd.setCursor(0, 1);
lcd.print("100 %");
delay(3000);
lcd.clear();
delay(250);
}
else if (soilmoisturepercent <0)
{
Serial.println("0 %");
lcd.setCursor(0, 0);
lcd.print("10th Planet C2:");
lcd.setCursor(0, 1);
lcd.print("0 %");
delay(3000);
lcd.clear();
delay(250);
}
else if (soilmoisturepercent >0 && soilmoisturepercent < 100)
{
Serial.print(soilmoisturepercent);
Serial.println(" %");
lcd.setCursor(0, 0);
lcd.print("10th Planet C2:");
lcd.setCursor(0, 1);
lcd.print(soilmoisturepercent);
lcd.print(" %");
delay(3000);
lcd.clear();
delay(250);
}
value3 = analogRead(Pin3);
Serial.println(value3);
soilmoisturepercent = map(value3, AirValue, WaterValue, 0, 100);
if (soilmoisturepercent > 100)
{
Serial.println("100 %");
lcd.setCursor(0, 0);
lcd.print("10th Planet C3:");
lcd.setCursor(0, 1);
lcd.print("100 %");
delay(3000);
lcd.clear();
delay(250);
}
else if (soilmoisturepercent <0)
{
Serial.println("0 %");
lcd.setCursor(0, 0);
lcd.print("10th Planet C3:");
lcd.setCursor(0, 1);
lcd.print("0 %");
delay(3000);
lcd.clear();
delay(250);
}
else if (soilmoisturepercent >0 && soilmoisturepercent < 100)
{
Serial.print(soilmoisturepercent);
Serial.println(" %");
lcd.setCursor(0, 0);
lcd.print("10th Planet C3:");
lcd.setCursor(0, 1);
lcd.print(soilmoisturepercent);
lcd.print(" %");
delay(3000);
lcd.clear();
delay(250);
}
value4 = analogRead(Pin4);
Serial.println(value4);
soilmoisturepercent = map(value4, AirValue, WaterValue, 0, 100);
if (soilmoisturepercent > 100)
{
Serial.println("100 %");
lcd.setCursor(0, 0);
lcd.print("10th Planet C4:");
lcd.setCursor(0, 1);
lcd.print("100 %");
delay(3000);
lcd.clear();
delay(250);
}
else if (soilmoisturepercent <0)
{
Serial.println("0 %");
lcd.setCursor(0, 0);
lcd.print("10th Planet C4:");
lcd.setCursor(0, 1);
lcd.print("0 %");
delay(3000);
lcd.clear();
delay(250);
}
else if (soilmoisturepercent >0 && soilmoisturepercent < 100)
{
Serial.print(soilmoisturepercent);
Serial.println(" %");
lcd.setCursor(0, 0);
lcd.print("10th Planet C4:");
lcd.setCursor(0, 1);
lcd.print(soilmoisturepercent);
lcd.print(" %");
delay(3000);
lcd.clear();
delay(250);
}
value1 = analogRead(Pin1);
if(value1 < AirValue && value1 > (AirValue - intervals))
{
digitalWrite(IN1, LOW);
}
else
{
digitalWrite(IN1, HIGH);
}
value2 = analogRead(Pin2);
if(value2 < AirValue && value2 > (AirValue - intervals))
{
digitalWrite(IN2, LOW);
}
else
{
digitalWrite(IN2, HIGH);
}
value3 = analogRead(Pin3);
if(value3 < AirValue && value3 > (AirValue - intervals))
{
digitalWrite(IN3, LOW);
}
else
{
digitalWrite(IN3, HIGH);
}
value4 = analogRead(Pin4);
if(value4 < AirValue && value4 > (AirValue - intervals))
{
digitalWrite(IN4, LOW);
}
else
{
digitalWrite(IN4, HIGH);
}
Serial.println();
delay(1000);
}

This is the normal way to connect a 4 channel relay board.

Of course the external power supply voltage must match the relay coil voltage.

Suggest you convert your code to a “State Machine” type of sketch.

Also research the BWD “BLINK WITHOUT DELAY”.


“. . . it off too quickly and the plant doesn't get enough water. ”

You would set up a minimum amount of time to water the plant.


These lines are not needed if your sensors are outputting an analog voltage 0-5v

pinMode(Pin1, INPUT);
pinMode(Pin2, INPUT);
pinMode(Pin3, INPUT);
pinMode(Pin4, INPUT);


So can you not power the relay off the 5V on the arduino instead of an external power source? And what's a state machine type of sketch?

niallfo:
So can you not power the relay off the 5V on the arduino instead of an external power source?

That's not what was said:

larryd:
This is the normal way to connect a 4 channel relay board.

It's a better way, since it provides electrical isolation and reduces the risk of trying to draw too much current from the Arduino, since those relays draw about 75mA each.

And what's a state machine type of sketch?

See here, here or here.

So what could I use as a 5V power supply? I'm sorry I'm really new to this

First off, are your relays 5VDC ?

If they are, many cell phone chargers are 5 volts at 1 amp or more.


Also you should place reversed biased snubbing diodes across each motor pump as these motors produce a great deal of electrical noise.


Please explain these:

const int AirValue = 620;
const int WaterValue = 315;
int intervals = (AirValue - WaterValue)/3;

Ok and yes they are 5VDC relays.
Would those reverse diodes just help with the sound? I'm not really worried about the noise.

const int AirValue = 620;
const int WaterValue = 315;
int intervals = (AirValue - WaterValue)/3;

And this is how I was told to calibrate the capacitive soil moisture sensors. The airValue is the value from the sensor when it's out of soil just in the air. And the waterValue is the value when the sensor is in complete water but I couldnt figure out how to code each specific sensors airValue and waterValue so I just did that average of 620 and 315 for all of them.

When you turn a DC motor or relay off they generate a voltage spike that can damage things - the diode is to control the voltage spike

Thank you very much for your help!

Do you have a link to the documentation for the moisture sensor ?

Is this your sensor ?

No I'm using the capacitive soil moisture sensor v1.2

Try the attached sketch at the bottom of this page:

PlantWateringLCDcapacitiveSensor.ino


Also, you might want to consider changing this:

void   checkPlant1()
{
  Sensor1 = analogRead(Analog1);

  //                 620  - 101 = 519                620
  if (Sensor1 > (AirValue - intervals) && Sensor1 < AirValue)
  {
    digitalWrite(relayIN1, WATERon);

    if (sensor1Flag == true)
    {
      //start the TIMER
      sensor1Millis = currentMillis;
      
      //disable starting of the TIMER
      sensor1Flag = false;
    }
  }

To:

void   checkPlant1()
{
  Sensor1 = analogRead(Analog1);

  //                 620  - 101 = 519     
  if (Sensor1 > (AirValue - intervals))
  {
    digitalWrite(relayIN1, WATERon);

    if (sensor1Flag == true)
    {
      //start the TIMER
      sensor1Millis = currentMillis;
      
      //disable starting of the TIMER
      sensor1Flag = false;
    }
  }

Same with:
checkPlant2()
checkPlant3()
checkPlant4()


EDIT

Update sketch: PlantWateringLCDcapacitiveSensor.ino Version 2.04

PlantWateringLCDcapacitiveSensor.ino (11 KB)

omg thank you so much. So where would i put in the timer value for the pumps to be on for? if say i were to put them on for 30 seconds

#define moistureLow 0
#define minimumTime 10 * 1000ul //minimum water time = 10 seconds

just change the 10 to 30? whats ul?

#define minimumTime 30 * 1000ul //minimum water time = 30 seconds


‘ul’ tells the compiler this is an ‘unsigned long’ number.

Suggest you add ‘ul’ when using the ‘unsigned long’ data type such as used here with timing.

When math is being use ‘ul’ tells the compiler to use ‘unsigned long’ math rather than the default integer math.

‘ul’ reminds you 3 months from now of the data ‘type’ being used ;).

Example: 60 * 60 * 1000ul for 1 hour.


Also, see the suggestion to remove “ && Sensor1 < AirValue” from those sections mentioned in post #14.

ok ya I see what your saying and ya i just removed it those other lines too. Thought about it and if the sensors reading anything higher then air then the pumps definitely need to be on lol. So the thing is, I was hoping there would be a way to trigger the pumps when the sensor reads the (AirValue - intervals) amount for 10 seconds then shuts off, takes another reading and if its not at 60% yet, it turns back on for another 10 seconds and so on and so on until it reaches say a desired percentage like 60%

You should have enough of an example now to accomplish those things mentioned in your post #17.

However, think the way things are now will be sufficient as there is feed back when the sensor says it is too dry.

You can always adjust the minimum time variable too.

Ok your awesome Larry I could hug you.
Is there a serial monitor type thing to see what your codes doing with having arduino on?

I thought I saw someone using something beside theyre arduino sketch and it looked like it was a serial monitor showing you what each line of code was doing or something