Button Help, Up, Down, Select

I am trying to create a timer for my aeroponic system. The menu will display to choices.

  1. Off time (which will be the amount of time in minutes that the timer will be off.
  2. On time (which will be the amount of time in minutes that the timer will be on.
    The timer “on time” will activate a solid state relay and will keep power on to my pump for the amount of time selected.

I pulled some code off the internet and would like some guidance.
Digital pins 5 and 6 are attached to tactile switches, they increment the on time variable.
I have added a 3rd tactile switch on digital pin 3, I would like this to be my “select button” which will let me choose whether I am working with “time off” or “time on”
Right now the following code is working and displays "Time On myVar.
I hope this makes sense, if not I will attempt to provide more information.
Thanks, John

#include <LiquidCrystal.h>

LiquidCrystal lcd(7,8,9,10,11,12);

//Set buttons pin numbers
byte incrementButton = 5;
byte decrementButton = 6;
byte SelectButton = 3;

//Global variables
int incrementState = 0; //variable that will read the increment button (either HIGH or LOW)
int decrementState = 0; //variable that will read the decrement button (either HIGH or LOW)
int counter = 0; //variable that will store the count
int lastIncrementState = 0;
int lastDecrementState = 0;

void setup()
{
   pinMode(incrementButton, INPUT); //set incrementButton as INPUT
   pinMode(decrementButton, INPUT); //set decrementButton as INPUT
   lcd.begin(16, 2); //set up the LCD's number of columns and rows:
   lcd.print("Time On"); //print a message on the LCD "Time On"
   lcd.setCursor(0,2); //Set the cursor at row 2 to print next line
   lcd.print("Time Off"); ////print a message on the LCD "Time Off"
}//end of setup

void loop()
{
   lcd.setCursor(12, 0);
   incrementState = digitalRead(incrementButton); //read the increment button state
   decrementState = digitalRead(decrementButton); //read the decrement button state
   if(incrementState != lastIncrementState) //compare increment button state to its last state
   {
      if(incrementState == LOW)//increment button is pressed
      {
         counter = counter + 1; //increment the counter
         lcd.print(counter); //print it on serial monitor
         lcd.print("   "); //3 blank spaces
         delay(20); //debounce delay
      }
   }
   lastIncrementState = incrementState;

   if(decrementState != lastDecrementState)//compare decrement state to its lastState
   {
      if(decrementState == LOW)//decrement button is pressed
      {
         counter = counter - 1; //decrement the counter
         lcd.print(counter); //print it on serial monitor
         lcd.print("   "); //3 blank spaces
         delay(20); //debounce delay
      }
   }
   lastDecrementState = decrementState;
}//end of loop

So you want the third button to toggle between the two states? Ok, so then use a latch.

static boolean select = digitalRead(3);
if(select !=  lastSelectState) // lastSelectState will need to be declaired boolean too at the top of your code.
{
   if(select == HIGH)
   {
     lastSelectState = select; // Notice I put this in here and not outside the if statement.
     State = !State; // also declare boolean at the top of your code. Set to false
   }
}

if(State == HIGH)
{
  // code for time on
}
else 
{
  //time off
}

Yes I want to toggle between timer on value and timer off value. I am going to try to wrap my brain around what you sent and give it a try. Thanks

Aftrer looking at this, I guess I just don’t understand it. I am going to try and re-describe my goal. Here is where I am at with my code, questions will be below.

#include <LiquidCrystal.h>

LiquidCrystal lcd(7,8,9,10,11,12);

//Set buttons pin numbers
byte incrementButton = 5;
byte decrementButton = 6;
byte SelectButton = 3;

//Global variables
int incrementState = 0; //variable that will read the increment button (either HIGH or LOW)
int decrementState = 0; //variable that will read the decrement button (either HIGH or LOW)
int counter = 0; //variable that will store the count
int lastIncrementState = 0;
int lastDecrementState = 0;
int selectState = 0;
int led = 13;

void setup()
{
   pinMode(led, OUTPUT);	
   pinMode(incrementButton, INPUT); //set incrementButton as INPUT
   pinMode(decrementButton, INPUT); //set decrementButton as INPUT
   pinMode(SelectButton, INPUT); //set decrementButton as INPUT
   lcd.begin(16, 2); //set up the LCD's number of columns and rows:
   lcd.print("Time On"); //print a message on the LCD "Time On"
   lcd.setCursor(0,2); //Set the cursor at row 2 to print next line
   lcd.print("Time Off"); ////print a message on the LCD "Time Off"
}//end of setup

void loop()
{
   //lcd.setCursor(12, 0);
   //incrementState = digitalRead(incrementButton); //read the increment button state
   //decrementState = digitalRead(decrementButton); //read the decrement button state
   //selectState = digitalRead(SelectButton); //read the Select button state
   lcd.setCursor(12, 1);
   incrementState = digitalRead(incrementButton); //read the increment button state
   decrementState = digitalRead(decrementButton); //read the decrement button state 
   selectState = digitalRead(SelectButton); //read the Select button state 
   digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
   delay(10000);               // wait for a 10 seconds
   digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
   delay(10000);               // wait for a 10 seconds   
   if(incrementState != lastIncrementState) //compare increment button state to its last state
   {
      if(incrementState == LOW)//increment button is pressed
      {
         counter = counter + 1; //increment the counter
         lcd.print(counter); //print it on serial monitor
         lcd.print("   "); //3 blank spaces
         delay(20); //debounce delay
      }
   }
   lastIncrementState = incrementState;

   if(decrementState != lastDecrementState)//compare decrement state to its lastState
   {
      if(decrementState == LOW)//decrement button is pressed
      {
         counter = counter - 1; //decrement the counter
         lcd.print(counter); //print it on serial monitor
         lcd.print("   "); //3 blank spaces
         delay(20); //debounce delay
      }
   }
   lastDecrementState = decrementState;
}//end of loop

What I want is the “SelectButton” on digital 3, is to bounce between the two menu items. (“Timer Off” and “Timer On”)
If the “SelectButton” is pushed once it will set the cursor for increment for “Timer On” If pushed again it will set the cursor to change to the menu item (Timer Off) which will then be able to increment.

Ultimately these selections will set the values for this bit of code.

digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
   delay(10000);               // wait for a 10 seconds
   digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
   delay(10000);               // wait for a 10 seconds

Thanks again for your help, I am new to the arduino and C++ but once I get past this I think I will be able to expand on it and further learn.

What menu items are you referring to? All I see are printed messages on your display, what exactly is getting changed?

I am calling the printed “Timer On” and Timer Off" menu items. With the code that I posted if I hit the increment buttons it will show a number next to the printed “Timer Off” I want to use that number in my code to set the led time off for the amount of seconds set by the increment button. Then be able to push the select button again to set the number of seconds the timer should remain on.

So something like this?

#include <LiquidCrystal.h>

LiquidCrystal lcd(7,8,9,10,11,12);


#define factor 1000
//Set buttons pin numbers
const byte incrementButton = 5;
const byte decrementButton = 6;
const byte SelectButton = 3;

//Global variables
boolean incrementState = 0; //variable that will read the increment button (either HIGH or LOW)
boolean decrementState = 0; //variable that will read the decrement button (either HIGH or LOW)
int counter = 0; //variable that will store the count
boolean lastIncrementState = 0;
boolean lastDecrementState = 0;
boolean selectState = 0;
boolean lastSelectState = false, State = false, ON = true;
int led = 13;
unsigned long Ontime = 0, Offtime = 0;
byte TimeOn = 1, TimeOff = 1;

void setup()
{
  lcd.begin(16, 2); //set up the LCD's number of columns and rows:
  pinMode(led, OUTPUT);	
  pinMode(incrementButton, INPUT); //set incrementButton as INPUT
  pinMode(decrementButton, INPUT); //set decrementButton as INPUT
  pinMode(SelectButton, INPUT); //set decrementButton as INPUT

  lcd.setCursor(1,0);
  lcd.print("Time On"); //print a message on the LCD "Time On"
  lcd.setCursor(1,1); //Set the cursor at row 2 to print next line
  lcd.print("Time Off"); ////print a message on the LCD "Time Off"
  lcd.setCursor(0,1);
  lcd.print(">");
}//end of setup

void loop()
{
  incrementState = digitalRead(incrementButton); //read the increment button state
  decrementState = digitalRead(decrementButton); //read the decrement button state 
  selectState = digitalRead(SelectButton); //read the Select button state 

  if(selectState !=  lastSelectState) // lastSelectState will need to be declaired boolean too at the top of your code.
  {
    if(selectState == HIGH)
    {
      // Notice I put this in here and not outside the if statement.
      State = !State; // also declare boolean at the top of your code. Set to false
    }
    if(State)
    {
      lcd.setCursor(0,0);
      lcd.print(">");
      lcd.setCursor(0,1);
      lcd.print(" ");
    }
    else
    {
      lcd.setCursor(0,0);
      lcd.print(" ");
      lcd.setCursor(0,1);
      lcd.print(">");
    }

    lastSelectState = selectState;
  }

  if(incrementState != lastIncrementState) //compare increment button state to its last state
  {
    if(incrementState == HIGH)//increment button is pressed
    {
      //increment the counter
      if(State == HIGH)
        TimeOn++;
      else
        TimeOff++;
      delay(20); //debounce delay
    }
    lastIncrementState = incrementState;
  }

  if(decrementState != lastDecrementState)//compare decrement state to its lastState
  {
    if(decrementState == HIGH)//decrement button is pressed
    {
      //decrement the counter
      if(State == HIGH) 
        TimeOn--;
      else
        TimeOff--;

      delay(20); //debounce delay
    }
    lastDecrementState = decrementState;
  }

  lcd.setCursor(10, 0);
  lcd.print(TimeOn); //print it on serial monitor        
  lcd.print("   "); //3 blank spaces
  lcd.setCursor(10, 1);
  lcd.print(TimeOff); //print it on serial monitor
  lcd.print("   "); //3 blank spaces

  LEDState();
}//end of loop

void LEDState()
{
  if(millis() - Ontime > (TimeOn * factor) && ON == true) // ON in this case looks to see if the LED itself is on. So before this IF statement is true, the LED is on
  {
    Offtime = millis(); // Notice it does not say Ontime, but instead it says Offtime. This is because when the 
                        // LED is OFF, we want to start the timer to turn it back ON.
    digitalWrite(led, LOW);   // turn off LED
    ON = false;
  } 
  if(millis() - Offtime > (TimeOff * factor) && ON == false) // LED is currently off, now keep counting to turn it on.
  {
    Ontime = millis();
    digitalWrite(led, HIGH);    // turn on LED
    ON = true;
  }
}

Hazards, that is exactly what I needed, thanks for sticking with me and all the help you have given.

John