debounce in an interrupt

Thread Starter

bug13

Joined Feb 13, 2012
2,002
Hi guys

I am working on a project, it's a battery power device. So the device needs to sleep as much as possible. And I don't want to use delay within interrupt to debounce.

The interrupt is triggered by a push button. Thanks guys!

Code:
uint8_t global_var_state_1;
uint8_t global_var_state_2;
uint8_t global_var_state_3;

while(1)
{
    //state machine bases on
    //input from global variables
    sleep();
}

void interrupt buttonPress(void)
{
    //debounce (how? don't want to use delay here)
   if (button_press_is_valid)
    {
        //change values of global_var
        //for state machine.
    }
}
 
Last edited:

MrChips

Joined Oct 2, 2009
30,821
After your interrupt from the button, turn off the interrupt, set the timer to interrupt after 50ms and go back to sleep.

(I'm going back to sleep now.):)
 

ErnieM

Joined Apr 24, 2011
8,377
What mystery function does this button start off?

A complete answer would require knowing lots more then there is a button doing "something."
 

Thread Starter

bug13

Joined Feb 13, 2012
2,002
What mystery function does this button start off?

A complete answer would require knowing lots more then there is a button doing "something."
The button interrupt will just change the value of a couple global vars, and increase the counter by one. There are three buttons in total.

Code:
uint8_t global_var_state_1;
uint8_t global_var_state_2;
uint8_t global_var_state_3;

while(1)
{
//state machine bases on
//input from global variables
sleep();
}

void interrupt button_01_Press(void)
{
    //debounce (how? don't want to use delay here)
   global_var_state_1 = 0; 
   global_var_state_2 = 1;
   global_counter++;
}
 

ErnieM

Joined Apr 24, 2011
8,377
Instead of directly setting these global state variables use the ISR to set global button flags that the main code can detect, debounce, and process. That's one general way to get the debounce out of the ISR to respond to other events.

Not much more can be said as are still leaving your device function as a mystery.
 

John P

Joined Oct 14, 2008
2,026
If the issue is "//debounce (how? don't want to use delay here)" then what you could do is run a repetitive timer counting up (say) milliseconds during the time when the button is not pushed, up to some maximum. Then as soon as the button is pressed, you check that total and if it's found to be at its maximum, do whatever the button does and reset the count to zero. But if there's a second or third closure of the button contacts, the intervening bounce time won't be enough for the counter to reach its limit, so those instances can be ignored. Note that here you're not waiting for the button contacts to become stable, but waiting for a button operation after a period of stability.
 

Thread Starter

bug13

Joined Feb 13, 2012
2,002
Not much more can be said as are still leaving your device function as a mystery.
Oh, I misunderstand your last replay.

So there are two buttons, and one lower power PIR sensor.
SW_Power_ON - connected to interrupt pin
SW_Power_OFF - connected to interrupt pin

For the end user, power off is PIR_Disable, power on is PIR_Enable. And the PIR sensor is connected to one of the interrupt pin too.

when SW_Power_ON is pressed:
A special sequence of LED is displayed.

when SW_Power_OFF is pressed:
A different sequence of LED is displayed.

And don't ask me why I can't just hook up a PIR sensor with a mechanical switch. This is how the user is requested, and this is how I will give to the user.
 

takao21203

Joined Apr 28, 2012
3,702
You need a "rastering" interrupt, like 20 to 50 msec., then you just set a flag, and call your tasks.

One could be to check keys, and update their variables.
you only need 3 states: 0, 1, and 2.

Then you can also test the variables if one has reached 2.
 

ErnieM

Joined Apr 24, 2011
8,377
So one button turns it on, another turns it off.

ON turns it ON till OFF is hit.

OFF turns it OFF till ON is hit.

And you need to debounce that because?
 

ErnieM

Joined Apr 24, 2011
8,377
And what does this mysterious counter do? Is there a second function of these buttons?

Are you just counting turn on and turn off, or are you also setting some other function?
 
Last edited:

ErnieM

Joined Apr 24, 2011
8,377
Yes just counting turn on and off.
Excellent. Now we see the whole function. Good news: you have no need to do any debouncing at all.

Why not? Over the long term # time turn off = # times turn on. Even over the short term these never differ more than 1.

So let's press the ON button: device wakes, disables whatever sleep mode it is in, exits the ISR and goes about it's business. Should the button bounce for another trip to the ISR none of these actions have any affect the 2nd or 200th time they get performed. But I would set a flag bit somewhere for turn off.

Now press the OFF button: the ISR increments the counter and calls sleepy time. Now there is a conflict if the OFF button bounces because each bounce wakes you up just long enough for the counter to get incremented. That is why the flag was set at turn on: when going to sleep check the bit: ONLY if set inc the counter, then clear the flag and go to sleep.
 

Thread Starter

bug13

Joined Feb 13, 2012
2,002
Excellent. Now we see the whole function. Good news: you have no need to do any debouncing at all.

Why not? Over the long term # time turn off = # times turn on. Even over the short term these never differ more than 1.

So let's press the ON button: device wakes, disables whatever sleep mode it is in, exits the ISR and goes about it's business. Should the button bounce for another trip to the ISR none of these actions have any affect the 2nd or 200th time they get performed. But I would set a flag bit somewhere for turn off.

Now press the OFF button: the ISR increments the counter and calls sleepy time. Now there is a conflict if the OFF button bounces because each bounce wakes you up just long enough for the counter to get incremented. That is why the flag was set at turn on: when going to sleep check the bit: ONLY if set inc the counter, then clear the flag and go to sleep.
Hi guys

Just some feedback, I have decided to use this method because it's easier, and I don't need a timer to keep track of the time. No extra timer means less power consumption during sleep.

Thanks all your replies, as always, every reply gives me something to think about about, and I learn something new. And something I can use on other project even I don't use it on this project.
 
Top