debounce problem

tuxduino:
That's a nested interrupt scenario, isn't it ?

You make this a lot more complicated than it really is. Your comments are comparable to someone hinting about using a voltage divider and having to explain the concept of a resistor, the fact that we need two of them, the use of power rails and how it all comes together. And surely, if none of these concepts are known, it is complicated. When working with electronics we need basic skills and the same applies to coding.

When we push a mechanical button, this typically results in a burst of pin state changes until the contacts make firm connection. The basic requirement of debouncing is to record this as a single event. Without some form of debouncing, we would otherwise record multiple key push events. We can avoid this with a single order external low pass filter (a RC circuit) or we can handle it in software (because we’re using a microcontroller) without additional components.

The software approach simply requires that we record the time of the first pin state change (someone pushed the button), and ignore additional pin state changes until a time period has elapsed. That’s all there is. How we detect the pin state change (interrupt, polled or otherwise) is irrelevant in this context.

Then to basic coding skills - we do not call the delay() function in ISR’s (in fact we have no use for a delay function at all in well written code). In ISR’s, we simply record the event (write to a global variable) and leave actual processing of the event for the loop() function. Rather than using delay(), we use the recorded time of the event and calculate the difference between current time and event time every time through our loop() function. In the first few milliseconds after the event, we simply ignore additional pin state changes (we already acted on the first state change). Once the debounce period has expired (say 5ms or so) we’re back to where we started and ready to act on new button push events.

We could also contain the debounce logic (no delay) within the ISR itself based on time between successive change events and so only report debounced events to the outside world (the loop function). This is just a matter of style.

Another approach again is to disable pin state interrupts within the ISR itself and then re-enable in the loop function once the debounce period has expired.