Button event driven possible?

Hi,

I have few buttons in my project but as I start coding with switch case and adding more code, the button sense have delay quite a lot. I need to hold down the button for awhile before it enter the function.

void loop()

{

if(digitalRead(Button1) == LOW){
-- do something
}

-- more code...

actionFunc();

}

void actionFunc(){

switch (Var1)
{
	case 0:
		switch (Var2)
		{
			case 0:
...... mode cases
		}
....... mode cases
}

}

Is it possible to make the buttons event driven or other solutions? I think when I pressed the button the systems is still in the switch loop. Thanks for the help.

You could do something like:

if(digitalRead(Button1) == LOW)
{
    delay(2000);
    if (digitalRead(Button1) == LOW) // If still pressing the button after 2 seconds...
    {
        // Do something
    }
}

@nrobinson2000, if the user pressed the button, I want the system to recognized right away. With all the switch case statement, the current system does not recognized the pressed button right away. I need to either hold down the button longer time or pressed the button 3 or 4 times before it enter the pressed button function. Since actionFunc() is not inside the button pressed loop, its call every time and independent of button pressed.

So you what are you planning for the behavior of the button? Could you please describe?

Since a button press is an asynchronous event, it would be better to use an interrupt to respond to the press. Just make sure that your ISR is short and returns quickly. If you’re unfamiliar with using interrupts, look up attachInterrupt() in the docs.

3 Likes

While I’d also go for interrupts, if you got more buttons than available interrupts you could also go for asynchronous polling of your buttons in a software timer.
One important point in user interaction is that your user gets feedback that his action was registered near instant, that might not necessarily mean that the respective action has to be performed immediately as long you “tell” the user you’re on it. After that it doesn’t matter too much if your code takes a few milliseconds more.

And also revisit your other code whether it’s acting slower than actually necessary.
Remove any delays or waits to get the overall performance of your code up.

Base on attachInterrupt() docs, I am not sure I could use it since I have case statement action and a duel mode for the buttons. I might need to read up on asynchronous polling. Currently, I am using 4.7k ext pull up. Should I use internal pull up instead? Not sure on the reaction time for ext pull vs internal pull up.

I don’t think the case statements should preclude using an interrupt, though it’s hard to tell without seeing more of your code. What do you mean by “dual mode” for the buttons? Also, how many buttons do you have?

@Ric, I have five buttons. Two of them have duel function such as mode/exit, confirm/next depend on the menu of the screen. Since ISR need to be short and returns quickly, I thought it does not accept case or function call inside. As @ScruffR suggest, I will need to revisit my code and see if I can make it faster.

@sheng, you may also want to consider using the clickButton library which does all the debouncing but also allows for single, double and long click actions on a single button. :smiley:

2 Likes