So one of my favorite debounce methods goes like this.
In the ISR (which is just a thread as I understand it so no need to worry about being as fast as possible) you use say an 8bit integer as a kind of stream input and define a bit pattern that represents the edge you want. So for a clean/sustained rising edge we need to see 01111111b. So when the ISR trips, we do this:
Code: Select all
uint8_t edge = 0x7F // 01111111
unit8_t stream = 0;
for(int i=0, i<16, i++)
{
stream <<= 1;
stream |= digitalRead(pinnum);
if (stream == edge)
{
g_external_flag = true;
break;
}
delay(3);
}
So when the ISR fires we will collect samples of the input and if a nice steady stream of 1's comes in following a 0 over seven samples (21ms) we probably have a good solid button press. If not and we wind up with something like 01101111, then we will collect 3 more samples before it ends up matching the edge pattern. Now, if after 16 samples we don't have a match we give up. If that's happening a lot maybe slow down the loop or get a better switch.
You could handle the second spurious queued interrupt by looking at g_external_flag, if it's still true then return from the ISR without bothering to sample since we have not yet processed the original button press yet. When you're ready to handle another press, clear your flag in the main program.
Just make sure that your edge is always at the far left. Don't use 00001111 as the pattern since it's possible that bounce in the left side will prevent you from making a match on the pattern like this 01001111. In that case you got the four 1's you wanted but can't pick up the edge because the spurious 1 in bit 6 stops it and it will now never match.
rising:
edge = 01111111
stream = 0000000 <-Starting value;
falling:
edge = 10000000
stream = 11111111 <-Starting value
I'm free typing this so hopefully it's not to error-filled but I think you can get the picture.