Hi There,
I'm new to Arduino so I apologize beforehand if my question seems stupid, I just don't know how to set this up.
I've been looking at this tutorial:
on how to set a menu with an LCD display.
Since I only want a simple menu, where the main page shows temperature and humidity values, and then a second page where CO2 readings are shown, it would be perfect with one button which scrolls to the side, or two buttons (right, left).
I have been altering the code from the link to include only two buttons, but I just can't get it to work. The LCD display only shows the main page, and none of the buttons work.
What is wrong with the code, and is there a simpler way to create a menu like the one I want?
The code:
#include <MenuBackend.h>
/*
Copyright Giuseppe Di Cillo (www.coagula.org)
Contact: dicillo@coagula.org
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along
with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
IMPORTANT: to use the menubackend library by Alexander Brevig download it at http://www.arduino.cc/playground/uploads/Profiles/MenuBackend_1-4.zip and add the next code at line 195
void toRoot() {
setCurrent( &getRoot() );
}
*/
#include <MenuBackend.h> //MenuBackend library - copyright by Alexander Brevig
#include <LiquidCrystal.h> //this library is included in the Arduino IDE
const int buttonPinLeft = 8; // pin for the Up button
const int buttonPinRight = 9; // pin for the Down button
int lastButtonPushed = 0;
int lastButtonLeftState = LOW; // the previous reading from the Left input pin
int lastButtonRightState = LOW; // the previous reading from the Right input pin
long lastLeftDebounceTime = 0; // the last time the output pin was toggled
long lastRightDebounceTime = 0; // the last time the output pin was toggled
long debounceDelay = 500; // the debounce time
LiquidCrystal lcd(2, 3, 4, 5, 6, 7);
//Menu variables
static void menuUsed(MenuUseEvent used);
static void menuChanged(MenuChangeEvent changed);
MenuBackend menu = MenuBackend(menuUsed,menuChanged);
//initialize menuitems
MenuItem menu1Item1 = MenuItem("Item1");
MenuItem menuItem1SubItem1 = MenuItem("Item1SubItem1");
MenuItem menuItem1SubItem2 = MenuItem("Item1SubItem2");
MenuItem menu1Item2 = MenuItem("Item2");
MenuItem menuItem2SubItem1 = MenuItem("Item2SubItem1");
MenuItem menuItem2SubItem2 = MenuItem("Item2SubItem2");
MenuItem menuItem3SubItem3 = MenuItem("Item2SubItem3");
MenuItem menu1Item3 = MenuItem("Item3");
void setup()
{
pinMode(buttonPinLeft, INPUT);
pinMode(buttonPinRight, INPUT);
lcd.begin(16, 2);
//configure menu
menu.getRoot().add(menu1Item1);
menu1Item1.addRight(menu1Item2).addRight(menu1Item3);
menu1Item1.add(menuItem1SubItem1).addRight(menuItem1SubItem2);
menu1Item2.add(menuItem2SubItem1).addRight(menuItem2SubItem2).addRight(menuItem3SubItem3);
menu.toRoot();
lcd.setCursor(0,0);
lcd.print("www.coagula.org");
} // setup()...
void loop()
{
readButtons(); //I splitted button reading and navigation in two procedures because
navigateMenus(); //in some situations I want to use the button for other purpose (eg. to change some settings)
} //loop()...
void menuChanged(MenuChangeEvent changed){
MenuItem newMenuItem=changed.to; //get the destination menu
lcd.setCursor(0,1); //set the start position for lcd printing to the second row
if(newMenuItem.getName()==menu.getRoot()){
lcd.print("Main Menu ");
}else if(newMenuItem.getName()=="Item1"){
lcd.print("Item1 ");
}else if(newMenuItem.getName()=="Item1SubItem1"){
lcd.print("Item1SubItem1");
}else if(newMenuItem.getName()=="Item1SubItem2"){
lcd.print("Item1SubItem2 ");
}else if(newMenuItem.getName()=="Item2"){
lcd.print("Item2 ");
}else if(newMenuItem.getName()=="Item2SubItem1"){
lcd.print("Item2SubItem1 ");
}else if(newMenuItem.getName()=="Item2SubItem2"){
lcd.print("Item2SubItem2 ");
}else if(newMenuItem.getName()=="Item2SubItem3"){
lcd.print("Item2SubItem3 ");
}else if(newMenuItem.getName()=="Item3"){
lcd.print("Item3 ");
}
}
void menuUsed(MenuUseEvent used){
lcd.setCursor(0,0);
lcd.print("You used ");
lcd.setCursor(0,1);
lcd.print(used.item.getName());
delay(3000); //delay to allow message reading
lcd.setCursor(0,0);
lcd.print("www.coagula.org");
menu.toRoot(); //back to Main
}
void readButtons(){ //read buttons status
int reading;
int buttonLeftState=LOW; // the current reading from the input pin
int buttonRightState=LOW; // the current reading from the input pin
//Right button
// read the state of the switch into a local variable:
reading = digitalRead(buttonPinRight);
// check to see if you just pressed the Down button
// (i.e. the input went from LOW to HIGH), and you've waited
// long enough since the last press to ignore any noise:
// If the switch changed, due to noise or pressing:
if (reading != lastButtonRightState) {
// reset the debouncing timer
lastRightDebounceTime = millis();
}
if ((millis() - lastRightDebounceTime) > debounceDelay) {
// whatever the reading is at, it's been there for longer
// than the debounce delay, so take it as the actual current state:
buttonRightState = reading;
lastRightDebounceTime =millis();
}
// save the reading. Next time through the loop,
// it'll be the lastButtonState:
lastButtonRightState = reading;
//Left button
// read the state of the switch into a local variable:
reading = digitalRead(buttonPinLeft);
// check to see if you just pressed the Down button
// (i.e. the input went from LOW to HIGH), and you've waited
// long enough since the last press to ignore any noise:
// If the switch changed, due to noise or pressing:
if (reading != lastButtonLeftState) {
// reset the debouncing timer
lastLeftDebounceTime = millis();
}
if ((millis() - lastLeftDebounceTime) > debounceDelay) {
// whatever the reading is at, it's been there for longer
// than the debounce delay, so take it as the actual current state:
buttonLeftState = reading;
lastLeftDebounceTime=millis();;
}
// save the reading. Next time through the loop,
// it'll be the lastButtonState:
lastButtonLeftState = reading;
//records which button has been pressed
if(buttonRightState==HIGH){
lastButtonPushed=buttonPinRight;
}else if(buttonLeftState==HIGH){
lastButtonPushed=buttonPinLeft;
}else{
lastButtonPushed=0;
}
}
void navigateMenus() {
MenuItem currentMenu=menu.getCurrent();
switch (lastButtonPushed){
case buttonPinRight:
if(!(currentMenu.moveDown())){ //if the current menu has a child and has been pressed enter then menu navigate to item below
menu.use();
}else{ //otherwise, if menu has no child and has been pressed enter the current menu is used
menu.moveDown();
}
break;
case buttonPinLeft:
menu.moveLeft();
break;
}
lastButtonPushed=0; //reset the lastButtonPushed variable
}
sketch_buttons.ino (7.82 KB)