I want to use a debouncer within an ISR, and this is the code I wrote:
ISR(PCINT0_vect) {
// Interrupt service request for external interrupt
// Interpret switches position
static uint8_t prevState = 0x03;
// Get current state
uint8_t startState = ((((PINC >> _swA) & 0x01) << 2) | (((PINC >> _swB) & 0x01) << 1) | ((PINC >> _swPb) & 0x01));
// Simple debouncing. 1 nop = 62.5 ns, 1600 nops approx 100 us
for (int i=0; i < 1600; i++)
asm volatile ("NOP");
// Get current state
uint8_t stopState = ((((PINC >> _swA) & 0x01) << 2) | (((PINC >> _swB) & 0x01) << 1) | ((PINC >> _swPb) & 0x01));
// Check if the previous state was stable and different from the previous one
if ((startState == stopState) && (stopState != prevState)) {
_buttonDown = (~startState & 0x01); // Update button state
if ((startState >> 1) == 0x03) { // If in idle state
// Decode steps pattern
if (patternBuffer == patternCW)
_counts++;
if (patternBuffer == patternCCW)
_counts--;
patternBuffer = 0x00; // reset buffer
}
else {
// Append state to the buffer
patternBuffer <<= 2;
patternBuffer |= (startState >> 1) ;
}
prevState = stopState; // Record state for next change
}
}
It sounds like there are much better solutions. Does one of you has contructive comments and suggestions?