OneButton and long press problem

Hi there

I've a problem with the OneButton library and a very simple sketch.

I connected an led from D7 to a 220 ohms resistor to ground and
I connected an pushbutton from A0 to Ground.

My sketch contains only two functions, menu0 and menu1. On
powerup menu0 is called by default.

If I long-press the button I enter menu1 and the led lights up.
The goal is if I long-press the button again while I am in menu1
the sketch should go back into menu0 and the led goes off.

The problem is it does not go back to menu0 OR it does but instantly returns back to
menu1 because the led flickers shortly. So my guess is that as I long-press the button it recognizes it as multiple long-press...

Thats my sketch:

#include "OneButton.h"

unsigned short cur_menu = 0;
unsigned short ledPin = 7;
OneButton button(A0, true);

void setup() {
  button.attachClick(click);
  button.attachDuringLongPress(lp);
  pinMode(ledPin, OUTPUT);
  menu0();
}

void loop() {
  button.tick();
  delay(20);
}

void click() {
 
}

void lp() {
  
  if(cur_menu == 1)
    menu0();
    
  if(cur_menu == 0)
    menu1();
}

void menu0() {
  cur_menu = 0;
  digitalWrite(ledPin, LOW);
}

void menu1() {
  cur_menu = 1;
  digitalWrite(ledPin, HIGH);
}

Any ideas how to solve that?

Read the method name again:

button.attachDuringLongPress(lp);

During long press means the function is repeatedly called as long as you press the button for a longer time. What you probably want to use is the method “attachLongPressStop”.

Thanks, I changed it to

button.attachDuringLongPress(lp);

to

button.attachLongPressStop(lp);

but this changed nothing in the behavior, I still cant turn off
the led with a long-press.

I somehow solved the problem. I narrowed it down to the if conditions in my lp() function.
Just fur fun I modified the second if condition to an “else if” condition and ta-da it works, the
led turns off on the second long-press.

...
void lp() {
  if(cur_menu == 1)
    menu0();
  else if(cur_menu == 0)
    menu1();
}
...

But I don’t really understand why is that so…

But I don't really understand why is that so...

If cur_menu is set to 1, menu0() is called. Inside menu0() you set cur_menu to 0. On return from menu0(), the next statement is a check if cur_menu is set to 0 (which it is now), so menu1 is called. The "else" breaks this double-action.

thanks a lot, I took quite a while to figure out what you wrote and it reinforced my doubts that I will ever try to start a professional coding career :smiley: