Hey all.. so I am trying to integrate a menu system into a graphical LCD project that I am currently working on. As I am a novice at programming I have had to struggle to get this far, but I have had some success, and I am now stumped as to what to do next.
I have had success in using switch case to setup a simple menu where I can use two buttons (right & left) to scroll from menu to menu.. this success is limited in that the menu will change but only while the button is held high. Once I release the button it goes back to the default menu/case 1.
Here is a snippet of my code:
int left = 12;
int right = 13;
int screennumber = 1;
if(digitalRead(right) == HIGH)
{
screennumber++;
if(screennumber > 2)
{
screennumber = 2;
}
}
else if(digitalRead(left) == HIGH)
{
screennumber--;
if(screennumber < 1)
{
screennumber = 1;
}
}
switch (screennumber)
{
case 1:
//code for all the functions on screen 1
break;
case 2:
//code for screen 2
break;
All of this takes place with in the void loop(). I suspect that part of the problem maybe that it is looping this code over and over again.. but then again I am a novice programmer and still am trying to grasp the concepts of function declaration and how to setup a "clean" program and call functions when necessary.. but I suppose that will come in time.
All I am trying to achieve at this point is a method for switching to another case and latching into that state so that the screen designated to that case will stay in view even after the button is released.
Any help or pointers that will push me in the right direction will be greatly appreciated! Thanks!
I think what you need to remember is that "loop" operates (to humans) incredibly quickly - if you test to see if a button is pressed, you can be fairly sure it will still be pressed next time you run through loop, so you may well race through your menu.
Try testing for a change in the button state, or have a look at the button handling libraries.
Sounds reasonable, and the advice is good.. but the one thing I am still not totally clear on is.. that in a switch case scenario, the conditions for a case.. lets say a particular screen in a menu should not change as long as the case is true.. correct?
If that is correct then that leads me to assume that there is a problem with the way I am handling the button to be read?
lets say a particular screen in a menu should not change as long as the case is true.. correct?
Without a little more context, like how your menu code is structured, it is a difficult question to answer.
From looking at the code I assume that you have two push buttons wired from pins to +5V. When you push the button connection is made from the pin to +5V but what happens when the button is NOT pushed? If the pin is left 'floating' (not connected to anything) its level is undetermined. Electrical noise pick-up might make it HIGH or might make it LOW. This can cause all sorts of problems. Do you have a resistor from the pin to ground (say 5 to 20 k ohms) to bring the pin LOW when the button isn't pushed?
Were I doing this I'd wire my buttons from the input pins to ground and turn on the built-in pullup resistors (saves adding them externally) then in my code test for LOW (instead of HIGH) to indicate that the button is pushed.
Finally note that at the beginning of loop() you are setting screennumber to 1 every time loop() is entered!
int screennumber = 1; Not surprising that when you test for it with no buttons pressed it's 1
int left = 12; // a pushbutton is wired from pin 12 to ground
int right = 13; // a pushbutton is wired from pin 13 to ground
int screennumber = 1;
void setup()
{
pinMode left(INPUT); // these are INPUTS by default but I like to
pinMode right(INPUT); // explicitly declare them to make it clear
digitalWrite(left,HIGH); // this enables an internal 20k resistor between pin 12 and VCC (5v)
digitalWrite(right,HIGH); // same for pin 13
}
void loop()
{
if(digitalRead(right) == LOW) // was HIGH
{
screennumber++;
if(screennumber > 2)
{
screennumber = 2;
}
}
else if(digitalRead(left) == LOW) // was HIGH
{
screennumber--;
if(screennumber < 1)
{
screennumber = 1;
}
}
switch (screennumber)
{
case 1:
//code for all the functions on screen 1
break;
case 2:
//code for screen 2
break;
}