Will the code I have written send an output to low within the parameters I set?

Hello everyone, I am working on an automatic plant watering system. Here's how it is setup to run

  • potLow - potentiometer to set the driest the soil can get (point where valve opens to water plant)
  • potHigh - potentiometer to set the wettest the soil can get (point where watering valve closes)
  • Four watering zones

Will the 'if' statement I wrote in the loop close the valve once the value for potHigh is reached or will it stay open and continuously flow? The way I have it written, I am not completely sure.

If the code causes the valve to open and stay open, can someone suggest how I should modify the code to correct the issue?

Thanks

//First attempt at making a 4 zone auto watering system
//potPins values are just for setup purposes, must be calibrated once placed in soil
//potPins are to adjust the high and low moisture ranges for each zone
//

const int zone1 = A0;
const int zone2 = A1;
const int zone3 = A2;
const int zone4 = A3;

const int potLow = A4;
const int potHigh = A5;

const int valve1 = 2;
const int valve2 = 3;
const int valve3 = 4;
const int valve4 = 5; 


void setup()
  {
   pinMode(valve1,OUTPUT);
   pinMode(valve2,OUTPUT);
   pinMode(valve3,OUTPUT);
   pinMode(valve4,OUTPUT);
  }

void loop()
  {
    if(analogRead(zone1) <= potLow){           //read the value from the soil moisture sensor
      digitalWrite(valve1,HIGH);}              //open the valve
      if(analogRead(zone1) >= potHigh){        //when value from soil moisture sensor reaches the upper limit
        digitalWrite(valve1,LOW);              //close the valve
      }
    }

If you want to know what the code does wouldn't it be easier just to test it rather than asking a bunch of random strangers what they think it will do?

It looks reasonable to me depending on what is actually connected to zone1 and valve1. I.e. I have no idea if you're reading the sensor correctly or driving the valve correctly. There probably isn't much point switching a valve on and then a few microseconds later checking to see if things are better but the program obviously isn't complete yet.

Steve

Thanks Steve, I'm asking rather than testing because I have a few days before the remainder to the parts come in and I would like to work out any issues before hand.

The issue I'm working on now is adding a standard 16x2 LCD screen to display the moisture values. Would you mind also checking out this code also?

I cant seem to get the values to display properly on the display, Im pretty sure it's just a rookie mistake but I am scratching my head getting it figured out.

Thanks

#include <LiquidCrystal.h>

//First attempt at making a 4 zone auto watering system
//potPins values are just for setup purposes, must be calibrated once placed in soil
//potPins are to adjust the high and low moisture ranges for each zone
//must be used with Arduino Mega

const int numRows = 2;                      //two rows
const int numCols = 16;                     //sixteen columns

LiquidCrystal lcd(12, 11, 10, 9, 8, 7);     //initialize library with the interface pins (these might need to be adjusted in the future)

const int zone1 = A0;                       //soil sensor for zone 1
const int zone2 = A1;                       //soil sensor for zone 2
const int zone3 = A2;                       //soil sensor for zone 3
const int zone4 = A3;                       //soil sensor for zone 4

const int potLow = A4;                      //low moisture level setting
const int potHigh = A5;                     //high moisture level setting

const int valve1 = 2;                       //water valve 1
const int valve2 = 3;                       //water valve 2
const int valve3 = 4;                       //water valve 3
const int valve4 = 5;                       //water valve 4

int percent1;                               //mapped value of zone1
int percent2;                               //mapped value of zone2
int percent3;                               //mapped value of zone3
int percent4;                               //mapped value of zone4


void setup()
  {
   lcd.begin(numCols,numRows);
   pinMode(valve1,OUTPUT);
   pinMode(valve2,OUTPUT);
   pinMode(valve3,OUTPUT);
   pinMode(valve4,OUTPUT);
  }
  

void loop()
  {
    if(analogRead(zone1) <= potLow){           //read the value from the soil moisture sensor
      digitalWrite(valve1,HIGH);}              //open the valve
      if(analogRead(zone1) >= potHigh){        //when value from soil moisture sensor reaches the upper limit
        digitalWrite(valve1,LOW);              //close the valve
      }
        {
        percent1 = map(zone1,0,1023,0,99);       //map zone1 range to 0-99
        percent2 = map(zone2,0,1023,0,99);       //map zone2 range to 0-99
        percent3 = map(zone3,0,1023,0,99);       //map zone3 range to 0-99
        percent4 = map(zone4,0,1023,0,99);       //map zone4 range to 0-99
      }
      
      lcd.setCursor(0,0);                             //set the cursor to the first row and the first column
      lcd.print(percent1);                            //print mapped value of zone1              
      lcd.setCursor(9,0);                             //set the cursor to the first row and the ninth column
      lcd.print(percent2);                            //print mapped value of zone2
      lcd.setCursor(1,0);                             //set the cursor to the second row and the first column
      lcd.print(percent3);                            //print mapped value of zone3
      lcd.setCursor(1,9);                             //set the cursor to the second row and the ninth column
      lcd.print(percent4);                            //print mapped value of zone4
    }

I cant seem to get the values to display properly on the display

Do they display at all and if so what is wrong ?

I get forward slashes in every location on the display

Does a simple "Hello World" program work correctly ?

Yes it does, I just double checked

      lcd.setCursor(1,0);                             //set the cursor to the second row and the first column

The comment in this statement and on the other setCursor which follows are wrong.

const int potLow = A4;                      //low moisture level setting
const int potHigh = A5;                     //high moisture level setting

A4 and A5 are pin numbers. They aren't going to be much use as high or low settings.

Pete

Ahh, you are right! I'll go work on that. I also noticed I made a mistake where I set the cursor for the LCD. I corrected it but still no display

Thanks

If the code for each zone does the exact same thing then it makes more sense to parameterize the code and have only one block instead of four. Then you will fix each mistake in one place instead of four places.

If this were my project I would probably store the info for each zone in an array of structures like this:

typedef struct {
  int sensorPin;    // soil sensor
  int valvePin;     // water valve
  int reading;      // mapped value
  int lcd_row;      // LCD coordinates for reading
  int lcd_col;
} zone;


zone zoneInfo[]  = {{A0, 2, 0, 0, 0}, {A1, 3, 0, 0, 9}, {A2, 4, 0, 1, 0}, {A3, 5, 0, 1, 9}};

const int NUM_ZONES = 4;  // # of zones to process
byte zoneIdx = 0;         // index to current zone

Each time through loop() I would only process one zone and would start with the value of NUM_ZONES set to 1 to test the first zone. When that zone was working it would be set to 2 to test the first two zones and so on.

With all the data held in an array and only one zone processed at a time the amount of code in the loop() function would be reduced.

void loop()
{
  //read the value from the soil moisture sensor
  int moistureValue = analogRead(zoneInfo[zoneIdx].sensorPin);

  if ( moistureValue <= potLow )
  {
    //open the valve
    digitalWrite(zoneInfo[zoneIdx].valvePin, HIGH);

  } else if ( moistureValue >= potHigh ) {

    //close the valve
    digitalWrite(zoneInfo[zoneIdx].valvePin, LOW);

  } // else

  //map zone range to 0-99
  zoneInfo[zoneIdx].reading = map(moistureValue, 0, 1023, 0, 99);

  //set the cursor
  lcd.setCursor(zoneInfo[zoneIdx].lcd_col, zoneInfo[zoneIdx].lcd_row);

  //print mapped value of zone1
  lcd.print(zoneInfo[zoneIdx].reading);

  // increment zone index, wrap to zero
  ++zoneIdx %= NUM_ZONES;

}

Blue, THANKS! That's really good info. I appreciate the time you spent on helping me out! I was thinking there was a way to simplify what I'm trying to sketch and this looks much better than what I've got so far. I'm going to have to go look at some array tutorials because your code looks much more efficient than mine.

I would still like to understand why I'm not getting the correct readout on the display. I made some changes to the code I'm working but when I upload it, I only get one zero (0) in each space I have set for output on the display. I'm making progress but I'm still not there. Code is below.

#include <LiquidCrystal.h>

//First attempt at making a 4 zone auto watering system
//potPins values are just for setup purposes, must be calibrated once placed in soil
//potPins are to adjust the high and low moisture ranges for each zone
//must be used with Arduino Mega


LiquidCrystal lcd(7,8,9,10,11,12);          //initialize library with the interface pins (these might need to be adjusted in the future)

const int zone1 = A0;                       //soil sensor for zone 1
const int zone2 = A1;                       //soil sensor for zone 2
const int zone3 = A2;                       //soil sensor for zone 3
const int zone4 = A3;                       //soil sensor for zone 4

const int potPinLow = A4;                      //low moisture pot
const int potPinHigh = A5;                     //high moisture pot

int potLow;
int potHigh;

const int valve1 = 2;                       //water valve 1
const int valve2 = 3;                       //water valve 2
const int valve3 = 4;                       //water valve 3
const int valve4 = 5;                       //water valve 4

int percent1;                               //mapped value of zone1
int percent2;                               //mapped value of zone2
int percent3;                               //mapped value of zone3
int percent4;                               //mapped value of zone4

int display1;
int display2;
int display3;
int display4;

void setup()
  {
   lcd.begin(16,2);
   
   pinMode(valve1,OUTPUT);
   pinMode(valve2,OUTPUT);
   pinMode(valve3,OUTPUT);
   pinMode(valve4,OUTPUT);

   pinMode(potLow,INPUT);
   pinMode(potHigh,INPUT);

   int potLow = analogRead(potPinLow);
   int potHigh = analogRead(potPinHigh);
   
   int percent1 = analogRead(zone1);
   
  }
  

void loop()
  {
    if(analogRead(zone1) <= potLow){           //read the value from the soil moisture sensor
      digitalWrite(valve1,HIGH);}              //open the valve
      //delay(180000);                           //delay 3 minutes
      if(analogRead(zone1) >= potHigh){        //when value from soil moisture sensor reaches the upper limit
        digitalWrite(valve1,LOW);              //close the valve
      }

        {
        display1 = map(percent1,0,1023,0,99);       //map zone1 range to 0-99
        display2 = map(percent2,0,1023,0,99);       //map zone2 range to 0-99
        display3 = map(percent3,0,1023,0,99);       //map zone3 range to 0-99
        display4 = map(percent4,0,1023,0,99);       //map zone4 range to 0-99
      }
      
      lcd.setCursor(0,0);                             //set the cursor to the first row and the first column
      lcd.print(display1);                            //print mapped value of zone1              
      lcd.setCursor(9,0);                             //set the cursor to the first row and the ninth column
      lcd.print(display2);                            //print mapped value of zone2
      lcd.setCursor(0,1);                             //set the cursor to the second row and the first column
      lcd.print(display3);                            //print mapped value of zone3
      lcd.setCursor(9,1);                             //set the cursor to the second row and the ninth column
      lcd.print(display4);                            //print mapped value of zone4
    }

I forgot to add thi to the sketch before I uploaded it, obviously this goes just below percent1

int percent2 = analogRead(zone2);
int percent3 = analogRead(zone3);
int percent4 = analogRead(zone4);

This code before setup()

int percent1;                               //mapped value of zone1
int percent2;                               //mapped value of zone2
int percent3;                               //mapped value of zone3
int percent4;                               //mapped value of zone4

defines 4 int values. This code in setup()

  int percent1 = analogRead(zone1);
  int percent2 = analogRead(zone2);
  int percent3 = analogRead(zone3);
  int percent4 = analogRead(zone4);

defines 4 new int values that only setup() knows about and assigns a value to them.

This code in loop()

        display1 = map(percent1,0,1023,0,99);       //map zone1 range to 0-99
        display2 = map(percent2,0,1023,0,99);       //map zone2 range to 0-99
        display3 = map(percent3,0,1023,0,99);       //map zone3 range to 0-99
        display4 = map(percent4,0,1023,0,99);       //map zone4 range to 0-99

references those 4 ints defined outside of setup(), which were never given a value.

Remove the "int" before the four assignments in setup() and the code will be referring to the same variables in all places. If you are still printing all zeros, maybe it's because you are reading all zeros. Try setting display1-4 to arbitrary values as a sanity check to see if they print correctly.

Man thanks Blue! I've been busy the past few days but I'm gonna work on this now. I really appreciate it. Karma coming your way!

Progress made! I removed "int" from "percent" in setup and all of the readings are showing up properly on the display. THe only issue I'm having now is that the readings on the screen are not changing as the analog values are changing. I have to hit reset to get an up to date reading. I think I can fix this fairly easily. Thanks everyone for the help, I greatly appreciate it everyone. Now on to learn about arrays!