Menu for changing values - difficulty implementing

Hi all,
I am still a newbie, so pls be gentle!

I am trying to get a menu that will enable me to change the values of the Setpoint, as well as the Proportional, Integral & Derivative values of a Arduino PID controller (from the playground) .

I find that if I add discrete values for Setpoint, P, I, D, each as menu items, I start running out of memory pretty quickly.

I need a way of being able to increment or decrement the values with greater range.

So I figured I could have a menu subtree for each variable each with children "+" and "-".
So when I am in the "Item2 ++" option and press "Enter", the value increments and prints on the LCD, and when I am in the "Item2 --" option and press "Enter", the value decrements and prints on the LCD.

I adapted some existing menu code, but am having trouble making it work. Currently it fails to print on the LCD the counter value, which make me think that the counter is likely not incrementing/decrementing,

Any suggestions of better ways of doing this are most welcome....

/*
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 <Wire.h>
#include <LiquidCrystal_I2C.h>


const int buttonPinLeft = 4;      // pin for the Up button
const int buttonPinRight = 5;    // pin for the Down button
const int buttonPinEsc = 3;     // pin for the Esc button
const int buttonPinEnter = 2;   // pin for the Enter button

int IncDec = 0;    //variable for ++ and -- 

int lastButtonPushed = 0;

int lastButtonEnterState = LOW;   // the previous reading from the Enter input pin
int lastButtonEscState = LOW;   // the previous reading from the Esc input pin
int lastButtonLeftState = LOW;   // the previous reading from the Left input pin
int lastButtonRightState = LOW;   // the previous reading from the Right input pin

long lastEnterDebounceTime = 0;  // the last time the output pin was toggled
long lastEscDebounceTime = 0;  // the last time the output pin was toggled
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

int Counter = 0; //counter to display incrementing or decrementing values

LiquidCrystal_I2C lcd(0x27,16,2); // set the LCD address to 0x27 for a 16 chars and 2 line display

//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 menuItem3SubItem3 = MenuItem("Item2SubItem3");
    MenuItem menu1Item3 = MenuItem("Item3");


void setup()
{
  pinMode(buttonPinLeft, INPUT);
  pinMode(buttonPinRight, INPUT);
  pinMode(buttonPinEnter, INPUT);
  pinMode(buttonPinEsc, INPUT);
    
  lcd.init();
  lcd.backlight();

  //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();
 
}  // 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("Item2 ++");
       IncDec = 1;
  }else if(newMenuItem.getName()=="Item2SubItem2"){
      lcd.print("Item2 --");
      IncDec == 2;
  }else if((IncDec = 1) && (buttonPinEnter == HIGH)) {
  Counter = Counter ++;
   lcd.setCursor(10,1); 
   lcd.print ( Counter );
}else if((IncDec = 2) && (buttonPinEnter == HIGH)) {
  Counter = Counter --;
  lcd.setCursor(10,1);
  lcd.print ( Counter );
}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 buttonEnterState=LOW;             // the current reading from the Enter input pin
  int buttonEscState=LOW;             // the current reading from the input pin
  int buttonLeftState=LOW;             // the current reading from the input pin
  int buttonRightState=LOW;             // the current reading from the input pin

and the rest

 //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 
                  // (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 != lastButtonEnterState) {
                    // reset the debouncing timer
                    lastEnterDebounceTime = millis();
                  } 
                  
                  if ((millis() - lastEnterDebounceTime) > debounceDelay) {
                    // whatever the reading is at, it's been there for longer
                    // than the debounce delay, so take it as the actual current state:
                    buttonEnterState=reading;
                    lastEnterDebounceTime=millis();
                  }
                  
                  // save the reading.  Next time through the loop,
                  // it'll be the lastButtonState:
                  lastButtonEnterState = reading;
                  

    //Esc button               
                  // read the state of the switch into a local variable:
                  reading = digitalRead(buttonPinEsc);

                  // 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 != 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; 
                  
                     
   //Down 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;                  
                  
                  
    //Up 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 (buttonEnterState==HIGH){
                    lastButtonPushed=buttonPinEnter;

                  }else if(buttonEscState==HIGH){
                    lastButtonPushed=buttonPinEsc;

                  }else if(buttonRightState==HIGH){
                    lastButtonPushed=buttonPinRight;

                  }else if(buttonLeftState==HIGH){
                    lastButtonPushed=buttonPinLeft;

                  }else{
                    lastButtonPushed=0;
                  }                  
}

void navigateMenus() {
  MenuItem currentMenu=menu.getCurrent();
  
  switch (lastButtonPushed){
    case buttonPinEnter:
      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 buttonPinEsc:
      menu.toRoot();  //back to main
      break;
    case buttonPinRight:
      menu.moveRight();
      break;      
    case buttonPinLeft:
      menu.moveLeft();
      break;      
  }
  
  lastButtonPushed=0; //reset the lastButtonPushed variable
}

I would wire up three buttons to three input pins.

Then I would make them mean:
"toggle what to set"
"increment"
"decrement"

Then I would run the code something like:

/* whatever values you want */
int setpoint = 100;
int P = 100;
int I = 0;
int D = 0;
int mode = 0;

bool modeWasDown = false;
bool incWasDown = false;
bool decWasDown = false;

...

loop() {
  char display[17];
  int adj = 0;
  if (digitalRead(INC_PIN)) {
    if (!incWasDown) {
      adj = 1;
    }
    incWasDown = true;
  }
  else {
    incWasDown = false;
  }
  if (digitalRead(DEC_PIN)) {
    if (!decWasDown) {
      adj = -1;
    }
    decWasDown = true;
  }
  else {
    decWasDown = false;
  }
  if (digitalRead(MODE_PIN)) {
    if (!modeWasDown) {
      mode = (mode + 1) % 5;
    }
    modeWasDown = true;
  }
  else {
    modeWasDown = false;
  }
  switch (mode) {
  case 0:
    // do nothing -- "display mode"
    sprintf(display, "value is %d", value);
    break;
  case 1:
    setpoint += adj;
    sprintf(display, "setpoint: %d", setpoint);
    break;
  case 2:
    P += adj;
    sprintf(display, "P: %d", P);
    break;
  case 3:
    I += adj;
    sprintf(display, "I: %d", I);
    break;
  case 4:
    D += adj;
    sprintf(display, "D: %d", D);
    break;
  }
  // now, display the "display" string if appropriate
}

Note: this is not a working sketch, it's an illustration of how to build a simple menu using three micro buttons tied to the Arduino. What's cool about this is that you're now closer to a working, stand-alone system!

Thanks for your reply.
I already have 4 buttons (Enter, Esc, L, R), so would prefer not to add more.
Any suggestions on why my code isn't working?