Hi, I am trying to create a menu system using a RepRapDiscount Smart Controller and the Arduino MEGA 2560.
My problem is that the menu items are automatically scrolled/cycled through on the screen (line 4) and a temporary selection is stored (line 2). I would like to be able to scroll through the menu items with the encoder (lines 1-4). select an item by pressing the encoder, and then scrolling through the subitems and selecting one with another press of the encoder.
Here is my code: starting with defined global variables:
#include <MenuBackend.h> //MenuBackend library - copyright by Alexander Brevig
#include <LiquidCrystal.h>
const int buttonPinLeft = 31; // pin for the Up button
const int buttonPinRight = 33; // pin for the Down button
const int buttonPinEsc = 41; // pin for the Esc button
const int buttonPinEnter = 35; // pin for the Enter button
int lastButtonPushed = 0;
int lastButtonEnterState = LOW;
int lastButtonEscState = LOW;
int lastButtonLeftState = LOW;
int lastButtonRightState = LOW;
long lastEnterDebounceTime = 0;
long lastEscDebounceTime = 0;
long debounceDelay = 500;
int buttonRightState = 0;
int buttonLeftState = 0;
int ENCODER_PULSES_PER_STEP = 4;
int lastEncoded = 0;
long encoderValue = 0; //keeps track of absolute position of encoder
int encoderPosition;
LiquidCrystal lcd(16, 17, 23, 25, 27, 29);
//Menu variables
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 menuItem2SubItem3 = MenuItem("Item2SubItem3");
MenuItem menu1Item3 = MenuItem("Item3");
HERE IS VOID SETUP()
void setup()
{
Serial.begin(9600);
pinMode(buttonPinLeft, INPUT);
pinMode(buttonPinRight, INPUT);
pinMode(buttonPinEnter, INPUT);
pinMode(buttonPinEsc, INPUT);
digitalWrite(buttonPinEnter, LOW);
digitalWrite(buttonPinEsc, HIGH);
digitalWrite(buttonPinLeft, HIGH);
digitalWrite(buttonPinRight, HIGH);
lcd.begin(20, 4);
//Serial.print("in setup");
//configure menu
menuSetup();
// menu.toRoot();
lcd.setCursor(0,0);
lcd.print("Mosaic Manufacturing");
}
AND VOID LOOP:
void loop()
{
Serial.println(lastButtonPushed);
readButtons();
navigateMenus();
}
HERE I SETUP THE MENU
void menuSetup()
{
Serial.println("Setting up menu...");
//add the file menu to the menu root
menu.getRoot().add(menu1Item1);
//setup the settings menu item
menu1Item1.addRight(menu1Item2).addRight(menu1Item3);
menu1Item1.add(menuItem1SubItem1).addRight(menuItem1SubItem2);
menu1Item2.add(menuItem2SubItem1).addRight(menuItem2SubItem2).addRight(menuItem2SubItem3);
}
MENUCHANGED SUBFUNCTION:
void menuChanged(MenuChangeEvent changed){
MenuItem newMenuItem=changed.to; //get the destination menu
lcd.setCursor(0,3); //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 ");
}
}
MENUUSED SUBFUNCTION:
void menuUsed(MenuUseEvent used){
lcd.setCursor(0,0);
lcd.print("You used ");
lcd.setCursor(0,1);
lcd.print(used.item.getName());
//delay(1000); //delay to allow message reading
lcd.setCursor(0,0);
lcd.print("Mosaic Manufacturing");
menu.toRoot(); //back to Main
}
CODE TO READ BUTTONS:
void readButtons(){ //read buttons status
int reading;
int buttonEnterState=HIGH; // the current reading from the Enter input pin
int buttonEscState=HIGH;
int buttonLeftState=HIGH;
int buttonRightState=HIGH;
//Enter button
// read the state of the switch into a local variable:
reading = digitalRead(buttonPinEnter);
// check to see if you just pressed the enter button
// If the switch changed
if (reading != lastButtonEnterState) {
// reset the debouncing timer
lastEnterDebounceTime = millis();
}
if ((millis() - lastEnterDebounceTime) > debounceDelay) {
// whatever the reading is at, take it as the actual current state:
buttonEnterState=reading;
lastEnterDebounceTime=millis();
}
// save the reading.
lastButtonEnterState = reading;
//Esc button
// state of the switch into a local variable:
reading = digitalRead(buttonPinEsc);
// check to see if you just pressed the Down button
// If the switch changed, due to noise or pressing:
if (reading != lastButtonEscState) {
// reset the debouncing timer
lastEscDebounceTime = millis();
}
if ((millis() - lastEscDebounceTime) > debounceDelay) {
// whatever the reading is at, it's been there for longer
// than the debounce delay, so take it as the actual current state:
buttonEscState = reading;
lastEscDebounceTime=millis();
}
// save the reading. Next time through the loop,
// it'll be the lastButtonState:
lastButtonEscState = reading;
//Update encoder wheel
buttonRightState = HIGH;
buttonLeftState = HIGH;
updateEncoder();
if (abs(encoderValue) >= ENCODER_PULSES_PER_STEP)
{
encoderPosition = encoderValue / ENCODER_PULSES_PER_STEP;
encoderValue = 0;
if (encoderPosition == 1){
buttonRightState = LOW;
}
if (encoderPosition == -1){
buttonLeftState = LOW;
}
}
//Down button
lastButtonRightState = buttonRightState;
//Up button
lastButtonLeftState = buttonLeftState;
//records which button has been pressed
if (buttonEnterState==LOW){
lastButtonPushed=buttonPinEnter;
}else if(buttonEscState==LOW){
lastButtonPushed=buttonPinEsc;
}else if(buttonRightState==LOW){
lastButtonPushed=buttonPinRight;
}else if(buttonLeftState==LOW){
lastButtonPushed=buttonPinLeft;
}else{
lastButtonPushed=0;
}
}
I believe the encoder code is working correctly, it's the menu system that has an error. I want the items to show up on the screen to be able to scroll through them and select by pressing the encoder button. Right now the items are being cycled through on line 4 and it stores an item on line 2.