Irrigation lcd menu

Hello everyone, I am trying to make an irrigation system based on moisture sensors and solenoid valves. I am a total noob in programming, so please bare with me. I would like to make a simple menu with a 2X16 lcd shield or just an lcd and a rotary encoder, for a 4 zone controller and I want to be able to set the moisture level for each zone. I dont know how to setup the menu and and how to change the moisture values in the menu. hope anyone can help me :slight_smile:

Colin

What do you have done until now?

As you haven't posted code Im guessing that you are stuck

you are going to require at least 3 buttons which will be edit---up---down

I would use a switch case argument based on the screen. up and down button changes screen
and change setpoints if the edit button is held down

if edit button not pushed then

screen 1 "display zones and readings" //up and down button will scroll screens
screen 2 "display zone one reading and set point"
screen 3 "display zone two reading and set point"

if edit button pushed then and held

screen 2 "setpoint" " press up down to change // up and down buttons will now edit setpoints
screen 3 "setpoint" " press up down to change

little programming to compare zone reading to zone setpoint
turn on water until reading is bigger than setpoint.

Thanks gpop, that sounds like the thing i would need. my problem is that i am not very good at coding, so i usually find different codes and piece them together, but i can´t seem to find any sketches that i can modify.
Could you maybe show me some example code??

post a code that works with your display (hello world) and I will throw some code on top of that for you

Here is what i have so far. I use a DF Robot lcd keypad shield.

#include <Wire.h>
#include <LiquidCrystal.h>

 
// Initialize the library with the numbers of the interface pins
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
 
//States for the menu.
int currentMenuItem = 0;
int lastState = 0;
 
void setup() {
   //Set the characters and column numbers.
   lcd.begin(16, 2);
   //Print default title.
   clearPrintTitle();
}
 
void loop() {
  
mainMenu(); //Call the main menu.
}
 
void mainMenu() {
  //State = 0 every loop cycle.
  int state = 0;
  //Refresh the button pressed.
  int x = analogRead (0);
  //Set the Row 0, Col 0 position.
  lcd.setCursor(0,0);
 
  //Check analog values from LCD Keypad Shield
  if (x < 50) {
    //Right
  } else if (x < 195) {
   //Up
    state = 1;
  } else if (x < 380){
   //Down
    state = 2;
  } else if (x < 555){
    //Left
  } else if (x < 790){
    //Select
    state = 3;
  }
 
  //If we are out of bounds on th menu then reset it.
  if (currentMenuItem < 0 || currentMenuItem > 4) {
   currentMenuItem = 0; 
  }
 
   //If we have changed Index, saves re-draws.
   if (state != lastState) {
      if (state == 1) {
         //If Up
          currentMenuItem = currentMenuItem - 1; 
          displayMenu(currentMenuItem);
      } else if (state == 2) {
         //If Down
          currentMenuItem = currentMenuItem + 1;  
          displayMenu(currentMenuItem);
      } else if (state == 3) {
         //If Selected
         selectMenu(currentMenuItem); 
      }
      //Save the last State to compare.
      lastState = state;
   } 
   //Small delay
  delay(5);
}
 
//Display Menu Option based on Index.
void displayMenu(int x) {
     switch (x) {
      case 1:
        clearPrintTitle();
        lcd.print ("-> ZONE 1");
        break;
      case 2:
        clearPrintTitle();
        lcd.print ("-> ZONE 2");
        break;
       case 3:
        clearPrintTitle();
        lcd.print ("-> ZONE 3");
        break;
      case 4:
        clearPrintTitle();
        lcd.print ("-> ZONE 4");
        break;
    }
}
 
//Print a basic header on Row 1.
void clearPrintTitle() {
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(" Colins Vanding ");
  lcd.setCursor(0,1); 
}
 
//Show the selection on Screen.
void selectMenu(int x) {
   switch (x) {
      case 1:
        clearPrintTitle();
        lcd.print ("SET ZONE 1");
        //Call the function that belongs to Option 1
        break;
      case 2:
        clearPrintTitle();
        lcd.print ("SET ZONE 2");
        //Call the function that belongs to Option 2
        break;
       case 3:
        clearPrintTitle();
        lcd.print ("SET ZONE 3");
        //Call the function that belongs to Option 3
        break;
      case 4:
        clearPrintTitle();
        lcd.print ("SET ZONE 4");
        //Call the function that belongs to Option 4
        break;
    }
}

Your sketch don't make sense with what you say in your first post. In your post you say that you will use an "rotary encoder", but in your sketch you are using the buttons of the "DF Robot lcd keypad shield". So, what you have to do is use only the LCD form the "DF Robot lcd keypad shield" and you need to add a rotatory encoder to select and change your options. So, you don't need this part:

  //Refresh the button pressed.
  int x = analogRead (0);
  //Set the Row 0, Col 0 position.
  lcd.setCursor(0,0);
 
  //Check analog values from LCD Keypad Shield
  if (x < 50) {
    //Right
  } else if (x < 195) {
   //Up
    state = 1;
  } else if (x < 380){
   //Down
    state = 2;
  } else if (x < 555){
    //Left
  } else if (x < 790){
    //Select
    state = 3;
  }

not saying this is the way to do it but this is the way I would tackle it using a key pad like the one you showed in the code.

This sketch compiles but has not been tested. There may be mistakes especially as I copy and pasted it in a hurry

#include <Wire.h>
#include <LiquidCrystal.h>


// Initialize the library with the numbers of the interface pins
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

//States for the menu.
int currentMenuItem = 0;
int lastState = 0;
int z1_set = 25; //setpoint (25% on boot) consider adding to eeprom memory
int z2_set = 25; //setpoint
int z3_set = 25; //setpoint
int z4_set = 25; //setpoint
int z1_reading;//readings from analog sensor
int z2_reading;//readings from analog sensor
int z3_reading;//readings from analog sensor
int z4_reading;//readings from analog sensor
byte edit_mode = 0;//used to detect when in edit
byte screen;//the current screen in use
unsigned long previousMillis = 0; //part of timer
unsigned long interval = 30000; //30 seconds timer

void setup() {
  //Set the characters and column numbers.
  lcd.begin(16, 2);

}

void loop() {

  mainMenu(); //Call the main menu.
}

void mainMenu() {
  //State = 0 every loop cycle.
  int state = 0;
  //Refresh the button pressed.
  int x = analogRead (0);//keypad
  z1_reading = analogRead (1);//to be added soil moisture detector
  z2_reading = analogRead (2);//to be added soil moisture detector
  z3_reading = analogRead (3);//to be added soil moisture detector
  z4_reading = analogRead (4);//to be added soil moisture detector

  
  //used to reset screen and kick out of edit after 30 seconds
  if ((screen != 0) || (edit_mode != 0)) {
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis > interval) {
      screen == 0;
      edit_mode == 0;
      previousMillis = currentMillis;
    }
  }

  z1_reading = map (z1_reading, 0, 1023, 0, 100); //converts raw input to 0-100%
  z2_reading = map (z2_reading, 0, 1023, 0, 100); //converts raw input to 0-100%
  z3_reading = map (z3_reading, 0, 1023, 0, 100); //converts raw input to 0-100%
  z4_reading = map (z4_reading, 0, 1023, 0, 100); //converts raw input to 0-100%




  //Check analog values from LCD Keypad Shield
  if (x < 50) {
    //Right
  } else if (x < 195) {
    //Up
    state = 1;
  } else if (x < 380) {
    //Down
    state = 2;
  } else if (x < 555) {
    state = 4;
  } else if (x < 790) {
    //Select
    state = 3;
  }



  //If we have changed Index, saves re-draws.
  if (state != lastState) {
    if (state == 1) {
      //If Up

      //same up/down buttons are used with 5 diffrent results depending on edit mode and screen number


      if (edit_mode == 0) {
        screen++;
      }
      else {
        switch (screen) {
          case 1:
            z1_set++;
            break;
          case 2:
            z2_set++;
            break;
          case 3:
            z3_set++;
            break;
          case 4:
            z4_set++;
            break;
        }
      }

    } else if (state == 2) {
      //If Down
      if (edit_mode == 0) {
        screen--;
      }
      else {
        switch (screen) {
          case 1:
            z1_set--;
            break;
          case 2:
            z2_set--;
            break;
          case 3:
            z3_set--;
            break;
          case 4:
            z4_set--;
            break;
        }
      }
    } else if (state == 3) {
      //If Selected
      edit_mode = 1;
    }
    //added this so you can hit left button to get out of edit. saves waiting for 30 seconds
    else if (state == 4) {
      //If Selected
      edit_mode = 0;
    }


    //Save the last State to compare.
    lastState = state;

    if (screen < 0 || screen > 4) {
      screen = 0;
    }

    lcd.clear();
    lcd.setCursor(0, 0);

    if (edit_mode == 0) {

      switch (screen) {
        case 0:
          lcd.print(" Colins Vanding ");
          lcd.setCursor(0, 1);
          lcd.print ("blar blar blar");
          break;
        case 1:

          lcd.print ("-> ZONE 1");
          lcd.setCursor(0, 1);
          lcd.print (z1_reading);
          lcd.print (" %");
          break;
        case 2:

          lcd.print ("-> ZONE 2");
          lcd.setCursor(0, 1);
          lcd.print (z2_reading);
          lcd.print (" %");
          break;
        case 3:

          lcd.print ("-> ZONE 3");
          lcd.setCursor(0, 1);
          lcd.print (z3_reading);
          lcd.print (" %");
          break;
        case 4:

          lcd.print ("-> ZONE 4");
          lcd.setCursor(0, 1);
          lcd.print (z4_reading);
          lcd.print (" %");
          break;
      }
    }  else
      switch (screen) {
        case 0:
          lcd.print("select zone");
          lcd.setCursor(0, 1);
          lcd.print ("first");
          break;

        case 1:

          lcd.print ("ZONE 1 set");
          lcd.setCursor(0, 1);
          lcd.print (z1_set);
          lcd.print (" %");
          break;
        case 2:

          lcd.print ("ZONE 2 set");
          lcd.setCursor(0, 1);
          lcd.print (z2_set);
          lcd.print (" %");
          break;
        case 3:

          lcd.print ("ZONE 3 set");
          lcd.setCursor(0, 1);
          lcd.print (z3_set);
          lcd.print (" %");
          break;
        case 4:

          lcd.print ("ZONE 4 set");
          lcd.setCursor(0, 1);
          lcd.print (z4_set);
          lcd.print (" %");
          break;
      }

    if (z1_reading < z1_set) {
      //open water?
    }
    else {
      //close water?
    }
    if (z2_reading < z2_set) {
      //open water?
    }
    else {
      //close water?
    }
    if (z2_reading < z2_set) {
      //open water?
    }
    else {
      //close water?
    }
    if (z2_reading < z2_set) {
      //open water?
    }
    else {
      //close water?
    }



  }
  //Small delay
  delay(5);
}

Thank you very much for great input gpop. luisilva, I decided to go with the keypad shield.
There is still a few issues. I can´t get a reading from the moisture sensor and the relays won´t turn on/off.
also i would like to use the buttons like this. up/down=up/down, select=select, left=go one step back, and if held, go to main menu. any ideas?

Again thank you very much for great input.

#include <Wire.h>
#include <LiquidCrystal.h>


// Initialize the library with the numbers of the interface pins
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

#define RELAY1  7                        
#define RELAY2  6                        
#define RELAY3  5                        
#define RELAY4  4

#define z1  1                        
#define z2  2                        
#define z3  3                        
#define z4  4

  
//States for the menu.
int currentMenuItem = 0;
int lastState = 0;
int z1_set = 25; //setpoint (25% on boot) consider adding to eeprom memory
int z2_set = 25; //setpoint
int z3_set = 25; //setpoint
int z4_set = 25; //setpoint
int z1_reading;//readings from analog sensor
int z2_reading;//readings from analog sensor
int z3_reading;//readings from analog sensor
int z4_reading;//readings from analog sensor
byte edit_mode = 0;//used to detect when in edit
byte screen;//the current screen in use
unsigned long previousMillis = 0; //part of timer
unsigned long interval = 30000; //30 seconds timer



void setup() {
  //Set the characters and column numbers.
  lcd.begin(16, 2);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Colins Water v.2");
   Serial.begin (9600); // set the serial monitor tx and rx speed
      
// Initialise the Arduino data pins for OUTPUT
  pinMode(RELAY1, OUTPUT);       
  pinMode(RELAY2, OUTPUT);
  pinMode(RELAY3, OUTPUT);
  pinMode(RELAY4, OUTPUT);
  
  pinMode(z1_reading, INPUT);       
  pinMode(z2_reading, INPUT);
  pinMode(z3_reading, INPUT);
  pinMode(z4_reading, INPUT);
}

void loop() {

  mainMenu(); //Call the main menu.
}

void mainMenu() {
  //State = 0 every loop cycle.
  int state = 0;
  //Refresh the button pressed.
  int x = analogRead (0);//keypad
  int z1_reading = analogRead (A1);//to be added soil moisture detector
  int z2_reading = analogRead (A2);//to be added soil moisture detector
  int z3_reading = analogRead (A3);//to be added soil moisture detector
  int z4_reading = analogRead (A4);//to be added soil moisture detector

  
  //used to reset screen and kick out of edit after 30 seconds
  if ((screen != 0) || (edit_mode != 0)) {
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis > interval) {
      screen == 0;
      edit_mode == 0;
      previousMillis = currentMillis;
    }
  }

  z1_reading = map (z1_reading, 0, 1023, 0, 100); //converts raw input to 0-100%
  z2_reading = map (z2_reading, 0, 1023, 0, 100); //converts raw input to 0-100%
  z3_reading = map (z3_reading, 0, 1023, 0, 100); //converts raw input to 0-100%
  z4_reading = map (z4_reading, 0, 1023, 0, 100); //converts raw input to 0-100%




/* 
  //Check analog values from LCD Keypad Shield original
  if (x < 50) {
    //Right
  } else if (x < 195) {
    //Up
    state = 1;
  } else if (x < 380) {
    //Down
    state = 2;
  } else if (x < 555) {
    state = 4;
  } else if (x < 790) {
    //Select
    state = 3;
  }
*/
 //Check analog values from LCD Keypad Shield
  if (x < 50) {
    //Right
    state = 4;
  } else if (x < 195) {
    //Up
    state = 1;
  } else if (x < 380) {
    //Down
    state = 2;
  } else if (x < 555) {
    state = 0;
    //Left
  } else if (x < 790) {
    //Select
    state = 3;
  }



  //If we have changed Index, saves re-draws.
  if (state != lastState) {
    if (state == 1) {
      //If Up

      //same up/down buttons are used with 5 diffrent results depending on edit mode and screen number


      if (edit_mode == 0) {
        screen++;
      }
      else {
        switch (screen) {
          case 1:
            z1_set++;
            break;
          case 2:
            z2_set++;
            break;
          case 3:
            z3_set++;
            break;
          case 4:
            z4_set++;
            break;
        }
      }

    } else if (state == 2) {
      //If Down
      if (edit_mode == 0) {
        screen--;
      }
      else {
        switch (screen) {
          case 1:
            z1_set--;
            break;
          case 2:
            z2_set--;
            break;
          case 3:
            z3_set--;
            break;
          case 4:
            z4_set--;
            break;
        }
      }
    } else if (state == 3) {
      //If Selected
      edit_mode = 1;
    }
    //added this so you can hit left button to get out of edit. saves waiting for 30 seconds
    else if (state == 4) {
      //If Selected
      edit_mode = 0;
    }


    //Save the last State to compare.
    lastState = state;

    if (screen < 0 || screen > 4) {
      screen = 0;
    }

    lcd.clear();
    lcd.setCursor(0, 0);

    if (edit_mode == 0) {

      switch (screen) {
        case 0:
          lcd.print("Colins Water v.2");
          lcd.setCursor(0, 1);
          //lcd.print ("blar blar blar");
          break;
        case 1:

          lcd.print ("-> ZONE 1");
          lcd.setCursor(0, 1);
          Serial.println (z1_reading);
          lcd.print (" %");
          break;
        case 2:

          lcd.print ("-> ZONE 2");
          lcd.setCursor(0, 1);
          Serial.println (z2_reading);
          lcd.print (" %");
          break;
        case 3:

          lcd.print ("-> ZONE 3");
          lcd.setCursor(0, 1);
          Serial.println (z3_reading);
          lcd.print (" %");
          break;
        case 4:

          lcd.print ("-> ZONE 4");
          lcd.setCursor(0, 1);
          lcd.print (z4_reading);
          lcd.print (" %");
          break;
      }
    }  else
      switch (screen) {
        case 0:
          lcd.print("select zone");
          lcd.setCursor(0, 1);
          lcd.print ("first");
          break;

        case 1:

          lcd.print ("ZONE 1 set");
          lcd.setCursor(0, 1);
          lcd.print (z1_set);
          lcd.print (" %");
          break;
        case 2:

          lcd.print ("ZONE 2 set");
          lcd.setCursor(0, 1);
          lcd.print (z2_set);
          lcd.print (" %");
          break;
        case 3:

          lcd.print ("ZONE 3 set");
          lcd.setCursor(0, 1);
          lcd.print (z3_set);
          lcd.print (" %");
          break;
        case 4:

          lcd.print ("ZONE 4 set");
          lcd.setCursor(0, 1);
          lcd.print (z4_set);
          lcd.print (" %");
          break;
      }

    if (z1_reading < z1_set) {
    digitalWrite(RELAY1,LOW);    // Turns ON Relays 1                                      
    }
    else {
      digitalWrite(RELAY1,HIGH); // Turns Off Relays 1
    }
    if (z2_reading < z2_set) {
       digitalWrite(RELAY2,LOW); // Turns ON Relays 2
    }
    else {
      digitalWrite(RELAY2,HIGH); // Turns Off Relays 2
      //close water?
    }
    if (z3_reading < z3_set) {
      digitalWrite(RELAY3,LOW); // Turns ON Relays 4
      //open water?
    }
    else {
      digitalWrite(RELAY3,HIGH); // Turns Off Relays 3
      //close water?
    }
    if (z4_reading < z4_set) {
      digitalWrite(RELAY4,LOW); // Turns ON Relays 4
      //open water?
    }
    else {
      digitalWrite(RELAY4,HIGH); // Turns Off Relays 4
      //close water?
    }



  }
  //Small delay
  delay(5);
}

Dahlberg:
also i would like to use the buttons like this. up/down=up/down, select=select, left=go one step back, and if held, go to main menu. any ideas?

What about something like that:

  • Select ==> switching from 'normal mode' into 'menu mode' while in 'normal mode'
  • Left/Right ==> Select function (setpoint-1/2/3/4, save, cancel) while in 'menu mode'
  • Up/Down ==> Value up or down during setpoint setting while in 'menu mode'
  • 'Select' pressed while in menu mode and active function is 'save' ==> SAVE values to EEPROM
  • 'Select' pressed while in menu mode and active function is 'cancel' ==> abort and return to 'normal mode'
  • 5 seconds no button pressed while in 'menu mode' ==> abort and return to 'normal mode'

Your loop() function then might look like:

void loop()
{
  handleMenu();
  if (menuMode==normalMode)
  {
     // do whatever your normal program operation is
  }
}

Your normal program operation would then be inactive while the menu is active at the same time. But on the other side, you could have a timeout fallback from menu mode into normal mode if no button is pressed for a certain amount of time (in case you activate the menu and forget to finish the menu mode).

What do you think about such a programming logic?

First we need to know what works in the sketch and what didnt. Did the screen change when you used up and down.
If you was on screen for zone 3 what did the bottom line of lcd say. If you pressed select did screen change. Did the screen show 25% and did the up and down button change the number. Did the screen go back after 30 seconds. If in select mode did the screen go back if u hit left or right button.

Its no good adding or changing code unless the code works then at least you are modifying something that works rather than coding on top of mistakes

Im unable to get to a pc until later and theres no way i can code on this phone so hopefully someone else can assist till then

ok ive taken a look and the code has a switch in the wrong place which is probably messing with the relay outputs

#include <Wire.h>
#include <LiquidCrystal.h>


// Initialize the library with the numbers of the interface pins
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

#define RELAY1  7                        
#define RELAY2  6                        
#define RELAY3  5                        
#define RELAY4  4

#define z1  1                        
#define z2  2                        
#define z3  3                        
#define z4  4

  
//States for the menu.
int currentMenuItem = 0;
int lastState = 0;
int z1_set = 25; //setpoint (25% on boot) consider adding to eeprom memory
int z2_set = 25; //setpoint
int z3_set = 25; //setpoint
int z4_set = 25; //setpoint
int z1_reading;//readings from analog sensor
int z2_reading;//readings from analog sensor
int z3_reading;//readings from analog sensor
int z4_reading;//readings from analog sensor
byte edit_mode = 0;//used to detect when in edit
byte screen;//the current screen in use
unsigned long previousMillis = 0; //part of timer
unsigned long interval = 30000; //30 seconds timer



void setup() {
  //Set the characters and column numbers.
  lcd.begin(16, 2);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Colins Water v.2");
   Serial.begin (9600); // set the serial monitor tx and rx speed
      
// Initialise the Arduino data pins for OUTPUT
  pinMode(RELAY1, OUTPUT);       
  pinMode(RELAY2, OUTPUT);
  pinMode(RELAY3, OUTPUT);
  pinMode(RELAY4, OUTPUT);
  
  pinMode(z1_reading, INPUT);       
  pinMode(z2_reading, INPUT);
  pinMode(z3_reading, INPUT);
  pinMode(z4_reading, INPUT);
}

void loop() {

  mainMenu(); //Call the main menu.
}

void mainMenu() {
  //State = 0 every loop cycle.
  int state = 0;
  //Refresh the button pressed.
  int x = analogRead (0);//keypad
  int z1_reading = analogRead (A1);//to be added soil moisture detector
  int z2_reading = analogRead (A2);//to be added soil moisture detector
  int z3_reading = analogRead (A3);//to be added soil moisture detector
  int z4_reading = analogRead (A4);//to be added soil moisture detector

  
  //used to reset screen and kick out of edit after 30 seconds
  if ((screen != 0) || (edit_mode != 0)) {
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis > interval) {
      screen == 0;
      edit_mode == 0;
      previousMillis = currentMillis;
    }
  }

  z1_reading = map (z1_reading, 0, 1023, 0, 100); //converts raw input to 0-100%
  z2_reading = map (z2_reading, 0, 1023, 0, 100); //converts raw input to 0-100%
  z3_reading = map (z3_reading, 0, 1023, 0, 100); //converts raw input to 0-100%
  z4_reading = map (z4_reading, 0, 1023, 0, 100); //converts raw input to 0-100%




/* 
  //Check analog values from LCD Keypad Shield original
  if (x < 50) {
    //Right
  } else if (x < 195) {
    //Up
    state = 1;
  } else if (x < 380) {
    //Down
    state = 2;
  } else if (x < 555) {
    state = 4;
  } else if (x < 790) {
    //Select
    state = 3;
  }
*/
 //Check analog values from LCD Keypad Shield
  if (x < 50) {
    //Right
    state = 4;
  } else if (x < 195) {
    //Up
    state = 1;
  } else if (x < 380) {
    //Down
    state = 2;
  } else if (x < 555) {
    state = 0;
    //Left
  } else if (x < 790) {
    //Select
    state = 3;
  }



  //If we have changed Index, saves re-draws.
  if (state != lastState) {
    if (state == 1) {
      //If Up

      //same up/down buttons are used with 5 diffrent results depending on edit mode and screen number


      if (edit_mode == 0) {
        screen++;
      }
      else {
        switch (screen) {
          case 1:
            z1_set++;
            break;
          case 2:
            z2_set++;
            break;
          case 3:
            z3_set++;
            break;
          case 4:
            z4_set++;
            break;
        }
      }

    } else if (state == 2) {
      //If Down
      if (edit_mode == 0) {
        screen--;
      }
      else {
        switch (screen) {
          case 1:
            z1_set--;
            break;
          case 2:
            z2_set--;
            break;
          case 3:
            z3_set--;
            break;
          case 4:
            z4_set--;
            break;
        }
      }
    } else if (state == 3) {
      //If Selected
      edit_mode = 1;
    }
    //added this so you can hit left button to get out of edit. saves waiting for 30 seconds
    else if (state == 4) {
      //If Selected
      edit_mode = 0;
    }}


    //Save the last State to compare.
    lastState = state;

    if (screen < 0 || screen > 4) {
      screen = 0;
    }

    lcd.clear();
    lcd.setCursor(0, 0);

    if (edit_mode == 0) {

      switch (screen) {
        case 0:
          lcd.print("Colins Water v.2");
          lcd.setCursor(0, 1);
          //lcd.print ("blar blar blar");
          break;
        case 1:

          lcd.print ("-> ZONE 1");
          lcd.setCursor(0, 1);
          Serial.println (z1_reading);
          lcd.print (" %");
          break;
        case 2:

          lcd.print ("-> ZONE 2");
          lcd.setCursor(0, 1);
          Serial.println (z2_reading);
          lcd.print (" %");
          break;
        case 3:

          lcd.print ("-> ZONE 3");
          lcd.setCursor(0, 1);
          Serial.println (z3_reading);
          lcd.print (" %");
          break;
        case 4:

          lcd.print ("-> ZONE 4");
          lcd.setCursor(0, 1);
          lcd.print (z4_reading);
          lcd.print (" %");
          break;
      }
    }  else
      switch (screen) {
        case 0:
          lcd.print("select zone");
          lcd.setCursor(0, 1);
          lcd.print ("first");
          break;

        case 1:

          lcd.print ("ZONE 1 set");
          lcd.setCursor(0, 1);
          lcd.print (z1_set);
          lcd.print (" %");
          break;
        case 2:

          lcd.print ("ZONE 2 set");
          lcd.setCursor(0, 1);
          lcd.print (z2_set);
          lcd.print (" %");
          break;
        case 3:

          lcd.print ("ZONE 3 set");
          lcd.setCursor(0, 1);
          lcd.print (z3_set);
          lcd.print (" %");
          break;
        case 4:

          lcd.print ("ZONE 4 set");
          lcd.setCursor(0, 1);
          lcd.print (z4_set);
          lcd.print (" %");
          break;
      }

    if (z1_reading < z1_set) {
    digitalWrite(RELAY1,LOW);    // Turns ON Relays 1                                      
    }
    else {
      digitalWrite(RELAY1,HIGH); // Turns Off Relays 1
    }
    if (z2_reading < z2_set) {
       digitalWrite(RELAY2,LOW); // Turns ON Relays 2
    }
    else {
      digitalWrite(RELAY2,HIGH); // Turns Off Relays 2
      //close water?
    }
    if (z3_reading < z3_set) {
      digitalWrite(RELAY3,LOW); // Turns ON Relays 4
      //open water?
    }
    else {
      digitalWrite(RELAY3,HIGH); // Turns Off Relays 3
      //close water?
    }
    if (z4_reading < z4_set) {
      digitalWrite(RELAY4,LOW); // Turns ON Relays 4
      //open water?
    }
    else {
      digitalWrite(RELAY4,HIGH); // Turns Off Relays 4
      //close water?
    }



  
  //Small delay
  delay(5);
}

this should fix it. (never noticed the switch just before the delay so it was stuck in a if statement)

now you said you would like to hold a button but im afraid that's not easy on a keypad as holding one button disables every other button.

You need to draw on paper what screens you want and the order they are to be accessed. Just remember that buttons can not do more than one job in any set mode. So up/down can either change the screen or the set point they can not change both with out changing mode as you can not hold a button.

Also whats up with the moisture sensor. Have you tried making a sketch just to test the sensor and print the result to the serial port?

Great work gpop :smiley: most of it seems to work, the left button dosn´t go back but the right button does. up/down works fine, all presets are on 25% on bootup, and I can change the value. I do have a little bit of flickering when it delays. the only problem i have is that I don´t have enough outputs, because of the key pad shield. any ideas??

Which board. I presummed a uno

yes it is an uno. I only need 2 more outputs.

You have some funny defines in the sketch any idea what they are for. Some defines are using the same pins as the lcd. You should be able to run the lcd then relays on 10 to 13 and the sensors and keypad on a0 to a5

ok is this the shield?

http://www.robotshop.com/en/dfrobot-lcd-keypad-shield-arduino.html

if so then pin 10 can not be used but that still leaves you with

d3,d11,d12,d13 for the relays

A0 is used for the keypad
A1,A2,A3,A4 are used for the analog inputs

can you list the sensors you are using please so we can work out how they interface with the code

ok relays should be coded as

#define RELAY1  3                        
#define RELAY2  11                        
#define RELAY3  12                        
#define RELAY4  13

remember D10 can not be used with the shield

no idea what this code was added for

#define z1  1                       
#define z2  2                      
#define z3  3                       
#define z4  4

these pins are being used for analog so no idea why you are trying to set them as inputs (see analogread in learning references)

pinMode(z1_reading, INPUT);       
  pinMode(z2_reading, INPUT);
  pinMode(z3_reading, INPUT);
  pinMode(z4_reading, INPUT);

The moisture sensors are analog?????? make and model?????

this code here says that if right button then exit edit mode. If you want to use left change left button to state = 4;

if (x < 50) {
    //Right
    state = 4;

 else if (state == 4) {
      //If Selected
      edit_mode = 0;

once we can get the analog sensors working then we can do fun stuff like moving the set point to memory so what ever you set the 25% to once you turn it off it will remember that setting instead.

bad code is any code you can not read and understand. If theres something in the code that you don't understand just copy that section and ask. Im trying to help "you" write a code and understand it. I have all the time in the world so im happy to spend time as long as you are learning.

I am slowly lerning. and I love it. :smiley:

This is the keypad shield:

http://www.dfrobot.com/wiki/index.php?title=Arduino_LCD_KeyPad_Shield_(SKU:_DFR0009)

These are the moisture sensors:

http://www.ebay.com/itm/5pcs-Soil-Hygrometer-Detection-Module-Soil-Moisture-Sensor-/281237690165?hash=item417b129735

It is all working. the only problem is, I can´t get a precise reading from the sensor, it is either 1-2% or 98-99% so i am not able to use the settting function.

I have set the digital inputs to 3,11,12,13 and it works like a charm.
I have also tried to remove the input part on the reading, but then it doesn´t work

  pinMode(z1_reading,INPUT);       
  pinMode(z2_reading,INPUT);
  pinMode(z3_reading,INPUT);
  pinMode(z4_reading,INPUT);