I got the menubackend example I found here working with the switch: http://www.coagula.org/content/pages/tutorial-manage-menu-and-lcd-display-arduino

The benefit of this button over four is that it only takes up one analog pin! The only problem is that I cannot figure out how to adapt the debounce part of the code to work with this type of switch. The switch is pretty unusable right now because the smallest touch causes it to drill all the way down into the menu. I have tried a ton of things. Any ideas on how I could approach this problem? I am a hobbyist when it comes to programming so maybe that is why I am having trouble making the example code work with the special switch. A pointer in the right direction would be awesome! Note I use a funky serial LCD so that is why the print to serial code is a little weird. Here is the jumpy code I have without any attempt at debounce:

/*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 195void toRoot() {setCurrent( &getRoot() );}*/#include <MenuBackend.h> //MenuBackend library - copyright by Alexander Brevig

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; }

Tried the running average. That was fun to read about but it didn't work or I haven't identified the correct problem. The resistance values that come from the switch are very stable, however, when you toggle the switch it seems the commands (Enter, Esc, Left, Right) are coming so fast that that the code interprets one toggle as dozens of toggles. Thus, it advances through the menu until it reaches the last item for that particular command. At least I think that is what is going on. Did I implement the running average correctly? Any other ideas? Thanks!

/*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 195void toRoot() {setCurrent( &getRoot() );}*/#include <MenuBackend.h> //MenuBackend library - copyright by Alexander Brevig

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)

// subtract the last reading: total= total - readings[index]; // read from the sensor: readings[index] = analogRead(inputPin); // add the reading to the total: total= total + readings[index]; // advance to the next position in the array: index = index + 1;

// if we're at the end of the array... if (index >= numReadings) // ...wrap around to the beginning: index = 0;

// calculate the average: average = total / numReadings; // send it to the computer as ASCII digits Serial.println(average); delay(1); // delay in between reads for stability

} //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

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; }

The problem is not the debouncing as such, it is that you are not detecting CHANGES in the button state. If the button remains 'pressed' you will process that as a separate command each time round the loop.

What you need to do is apply your range checks to determine the current button state, which will presumably be one of a set of discrete values representing the different directions your button can be operated, plus a value (let's say zero) for the 'not pressed' state.

In your readButtons() function you need to remember what poosition the button was in previously and do your range checks to see what position it is in now. If they are different, the button has been pressed or released so set lastButtonPushed to indicate the new position. Otherwise (the position has not changed) set lastButtonPushed to zero, or whatever value you're using to represent the 'not pressed' position.

I only provide help via the forum - please do not contact me for private consultancy.

Assuming that each position has an output voltage not close to the others (I look at the circuit and that seems like a safe assumption) that you can know each one,

Maybe when you detect a change, you keep reading over and over until the new value stays within +/- perhaps .2V of one of the accepted values for 20 to 50 reads in a row which should take less than 10 ms. You could be pretty certain the switch has settled by then.

In your readButtons() function you need to remember what poosition the button was in previously and do your range checks to see what position it is in now. If they are different, the button has been pressed or released so set lastButtonPushed to indicate the new position. Otherwise (the position has not changed) set lastButtonPushed to zero, or whatever value you're using to represent the 'not pressed' position.

I got it working much better. Thoughts on improvements? Here is what I did:

/*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 195void toRoot() {setCurrent( &getRoot() );}*/#include <MenuBackend.h> //MenuBackend library - copyright by Alexander Brevig

// compare the buttonState to its previous state if (buttonState != lastButtonState) { // if the state has changed, increment the counter if (buttonState != 0 ) { // if the current state is HIGH then the button // wend from off to on: buttonPushCounter++; lastButtonPushed = buttonPushed; } else { // if the current state is LOW then the button // wend from on to off: lastButtonPushed = 0; } } // save the current state as the last state, //for next time through the loop lastButtonState = buttonState;}

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; }

I'm a bit perplexed by the number of state variables you are using in readButtons.

Using buttonState and lastButtonState looks fine to hold the current detected state and previously detected state so you can detect changes. Using lastButtonPushed as a way to pass the change from readButtons() to navigateMenus() (and then clear it once it's been processed) is also OK. Personally I'd have preferred to have readButtons() return the key that was pressed (or 0 is nothing was pressed) rather than using a global variable, because this reduces the amount of global data and that is always a good thing, but that's mainly a matter of style. But then you also have buttonPushed and buttonPushCounter, and I have no idea what they're for. If you can eliminate them that would reduce the complexity by a useful amount.

I only provide help via the forum - please do not contact me for private consultancy.

I think you want discrete intervals for a settled button press. The first two and last two are back to back. At the speed the Arduino does even analog reads you can see the voltage change before it is done changing, you can 'see the bounce'. When there's no room between two states, you will get a 'valid' state even as the state itself is changing.

If you press the Esc button and leave it for a while, do repeated analog reads fall in the range of 140 to 160 or something closer to 150?

I'm a bit perplexed by the number of state variables you are using in readButtons.

Using buttonState and lastButtonState looks fine to hold the current detected state and previously detected state so you can detect changes. Using lastButtonPushed as a way to pass the change from readButtons() to navigateMenus() (and then clear it once it's been processed) is also OK. Personally I'd have preferred to have readButtons() return the key that was pressed (or 0 is nothing was pressed) rather than using a global variable, because this reduces the amount of global data and that is always a good thing, but that's mainly a matter of style. But then you also have buttonPushed and buttonPushCounter, and I have no idea what they're for. If you can eliminate them that would reduce the complexity by a useful amount.

Another good point. Got the code from the ButtonStateChange example. I was running out the door when I added it and didn't clean it up very well. Not sure how it would look to eliminate the lastButtonPushed. This is what I have now:

/*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 195void toRoot() {setCurrent( &getRoot() );}*/#include <MenuBackend.h> //MenuBackend library - copyright by Alexander Brevig//#include <LiquidCrystal.h> //this library is included in the Arduino IDE

// compare the buttonState to its previous state if (buttonState != lastButtonState) { if (buttonState != 0 ) { lastButtonPushed = buttonState; } else { lastButtonPushed = 0; } } // save the current state as the last state for next time through the loop lastButtonState = buttonState;}

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; }