What to do next?

Hi Guys!
So I hooked up a 16x2 LCD to an Arduino and also I hooked up a tactile button which is debounced with the Bounce2 library. I am trying to create a menu on the LCD with 4 options and each option(when selected) opens up a screen with some text. What I don’t understand is what to do when the button is not pressed. You’ll better understand when you’ll read the code. I have made the code very modular and easy to use. Please help. Here is the code:

#include <Bounce2.h>

#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

#define BUTTON_PIN 10
Bounce debouncer = Bounce(); 

byte data;
char *menu[] = {
  "1)Play","2)Instructions","3)About","4)Exit" };

int potPin = 0;
int lastVal = 0;
int button = 10;

void setup(){
   
  lcd.begin(16, 2);
  
  Serial.begin(9600);
  pinMode(potPin, INPUT);
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  pinMode(13, OUTPUT);
  
  debouncer.attach(BUTTON_PIN);
  debouncer.interval(50);

}

void loop()
{
 dataRead();
}

int dataRead() {
  int val = analogRead(potPin);
  val = map(val,0,1023,0,100);
  
  if(val>0 && val<20) {
  updateDisplay(1);
  }
  
  else if(val>20 && val<40) {
  updateDisplay(2);
  }
  
  else if(val>40 && val<60) {
  updateDisplay(3);
  } 
 
  else if(val>60 && val<80) {
  updateDisplay(4);
  } 
  else {
    
  }
}

void updateDisplay(int number) {
if(number==1 && number != lastVal) {
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(menu[0]);
  lcd.setCursor(0,1);
  lcd.print(menu[1]);
  lastVal=number;
  displayMarker(1);
}

else if(number==2 && number != lastVal) {
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(menu[0]);
  lcd.setCursor(0,1);
  lcd.print(menu[1]);
  lastVal=number;
  displayMarker(2);
}

else if(number==3 && number != lastVal) {
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(menu[2]);
  lcd.setCursor(0,1);
  lcd.print(menu[3]);
  lastVal=number;
  displayMarker(1);
}

else if(number==4 && number != lastVal) {
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(menu[2]);
  lcd.setCursor(0,1);
  lcd.print(menu[3]);
  lastVal=number;
  displayMarker(2);
}

else {

}
}

void displayMarker(int number) {
if(number==1) {
lcd.setCursor(15,0);
lcd.print("<");
select(1);
}

else if(number==2) {
lcd.setCursor(15,1);
lcd.print("<");
select(2);
}

else if(number==3) {
lcd.setCursor(15,0);
lcd.print("<");
select(3);
}

else if(number==4) {
lcd.setCursor(15,1);
lcd.print("<");
select(4);
}

else {

}
} 


int check() {
debouncer.update();
int val = debouncer.read();
if(val==HIGH) {
  Serial.println("Button Debounced!");
  Serial.println("Not Pressed");
return 0;
}

else if(val==LOW) {
  Serial.println("Button Debounced!");
  Serial.println("Pressed");
return 1;
}

else {

}
} 

void select(int number) {
if(check()==1) {
  if(number==1) {
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Let's Play!");
  }
  else if(number==2) {
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("These are the");
    lcd.setCursor(0,1);
    lcd.print("Instructions!");
  }
  else if(number==3) {
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Made By:");
    lcd.setCursor(0,1);
    lcd.print("Owais Bin Asad");
  }
  else if(number==4) {
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Bye Bye :D");
  }
}

else {
// What to do here???
}
}

The menu works nicely but when I press the button on an option, nothing happens! Help. I think it has something to do with the empty else statement in the “select” function at the end.

Maybe I don't understand what your're doing. It appears that you have a single switch connected to pin 10, which should read either HIGH or LOW depending on its state. However, you treat it as a potentiometer in the code and map the value returned from it and then use a bunch of if statements to decide which option was selected. If you're using a pot, those are usually attached to an analog pin (A0-A5) and the return value is mapped. So what's really on pin 10, a pot or a switch?

Pin 10 is a tactile switch which is debounced by the Bounce2 library. So the thing is that whenever i press the button to select an option, nothing happens. Maybe there is some other bug in the code. Please could you help me with this?

You are using pin 0 as potPin. Pin 0 is serial receive on Uno and Leonardo. You should only use this one (and pin 1) if you really know what you're doing, or else you might be in for surprises. Next, you are setting up a serial connection. So you are in for surprises.

Then, after setting that up, you're going to do an analog read on the serial connection, which isn't able to do that. You'll get a 0 or a 1, depending on what you're sending over serial..

Now it appears to be time to do an update to the display (1), as that's what happens if the just obtained value was below 21, and we know it was.

There will never be an update (2), (3),(4) or whatever.

You are never ever reading pin 10, called button.

This sketch is very busy doing nothing at all. It certainly doesn't do what you seem to be expecting from it.

By the way, it is very well possible to to what you want, using just 1 button. You'll have to work out some tricks to get that done.

you may want to look to cover if pinPot is 0, 20, 40, 60,…

because you won’t capture those here…

if(val>0 && val<20) {
  updateDisplay(1);
  }
  
  else if(val>20 && val<40) {
  updateDisplay(2);
  }
  
  else if(val>40 && val<60) {
  updateDisplay(3);
  } 
 
  else if(val>60 && val<80) {
  updateDisplay(4);
  } 
  else {

but then again, that may be what you want…

You are never ever reading pin 10, called button.

OP attached the Bounce2 library to pin 10

 // Update the debouncer
  debouncer.update();
 
 // Get the update value
 int value = debouncer.read();

You are using pin 0 as potPin.
Pin 0 is serial receive on Uno and Leonardo.

You should be OK with using analog pin 0; analogRead understands what you are doing.

I have used pin 0 because it is pin A0 not the RX 0. If I typed A0, he compiler would have given me an error so I used only 0. It has always worked out for me before, because the compiler knows that a serial RX pin can not accept analog data.

And the dataRead function is working perfectly because it checks if the value is under the accepted conditions and whether it has changed or not. All other functions are called if the first function accepts all the input data.

Hey Hey! Look what do we have here. :smiley:
I was banging my head on the wall :smiley: trying to think of the solution when suddenly I realized that the select function was not being given a chance to check for a press. I designed the program so one function does its work and automatically hands it over to the next one but what I didn’t realize was that I programmed the main dataRead function to execute only if there has been a change in selection. So I re positioned the select function at the end of the IF statements and it works!
Here is the NEW code:

#include <Bounce2.h>

#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

#define BUTTON_PIN 10
Bounce debouncer = Bounce(); 

byte data;
char *menu[] = {
  "1)Play","2)Instructions","3)About","4)Exit" };

int potPin = 0;
int lastVal = 0;
int button = 10;

void setup(){

  lcd.begin(16, 2);

  Serial.begin(9600);
  pinMode(potPin, INPUT);
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  pinMode(13, OUTPUT);

  debouncer.attach(BUTTON_PIN);
  debouncer.interval(50);

}

void loop()
{
  dataRead();
}

int dataRead() {
  int val = analogRead(potPin);
  val = map(val,0,1023,0,100);

  if(val>0 && val<20) {
    updateDisplay(1);
  }

  else if(val>20 && val<40) {
    updateDisplay(2);
  }

  else if(val>40 && val<60) {
    updateDisplay(3);
  } 

  else if(val>60 && val<80) {
    updateDisplay(4);
  } 
  else {

  }
}

void updateDisplay(int number) {
  if(number==1 && number != lastVal) {
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print(menu[0]);
    lcd.setCursor(0,1);
    lcd.print(menu[1]);
    lastVal=number;
    displayMarker(1);
  }

  else if(number==2 && number != lastVal) {
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print(menu[0]);
    lcd.setCursor(0,1);
    lcd.print(menu[1]);
    lastVal=number;
    displayMarker(2);
  }

  else if(number==3 && number != lastVal) {
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print(menu[2]);
    lcd.setCursor(0,1);
    lcd.print(menu[3]);
    lastVal=number;
    displayMarker(1);
  }

  else if(number==4 && number != lastVal) {
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print(menu[2]);
    lcd.setCursor(0,1);
    lcd.print(menu[3]);
    lastVal=number;
    displayMarker(2);
  }

  else {

  }
  select(number);
}

void displayMarker(int number) {
  if(number==1) {
    lcd.setCursor(15,0);
    lcd.print("<");
    
  }

  else if(number==2) {
    lcd.setCursor(15,1);
    lcd.print("<");
    
  }

  else if(number==3) {
    lcd.setCursor(15,0);
    lcd.print("<");
    
  }

  else if(number==4) {
    lcd.setCursor(15,1);
    lcd.print("<");
   
  }

  else {

  }
} 


int check() {
  debouncer.update();
  int val = debouncer.read();
  if(val==HIGH) {
    return 0;
  }

  else if(val==LOW) {
    return 1;
  }

  else {

  }
} 

void select(int number) {
  if(check()==1) {
    if(number==1) {
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("Let's Play!");
    }
    else if(number==2) {
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("These are the");
      lcd.setCursor(0,1);
      lcd.print("Instructions!");
    }
    else if(number==3) {
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("Made By:");
      lcd.setCursor(0,1);
      lcd.print("Owais Bin Asad");
    }
    else if(number==4) {
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("Bye Bye :D");
    }
  }

  else {
    // What to do here???
  }
}

P.S Nobody gives a damn about what to do in the ELSE part of the IF statement. It works perfectly.

I'm still puzzled why A0 didn't compile for you. As MAS3 mentions, pins 0 and 1 are used by the Serial object so I'd stay away from using 0 for analog pin 0 even if analogRead() is smart enough to make the right call. If nothing else, using A0 helps to document your code. The fact that your code doesn't recognize A0 would make me a little worried.

Another thing to keep in mind is that most Arduino boards make the external interrupt routines available on pin 2 and 3. Because you may need to add an ISR sometimes, I always change:

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

to

LiquidCrystal lcd(12, 11, 7,6,5,4);

so I won't impinge on any potential ISR down the road.

I am also confused because of the 0/A0 issue but now that the problem is solved, I don't think I need to worry unless the compiler throws another error at me.