Electronic – How is this Pushbutton Debounce code

buttondebounceinterruptssleepswitches

I am monitoring a pushbutton with a microcontroller where I am trying to take care of four things together:

  1. 50-msec debounce upon push-begin and 25-msec debounce upon push-release
  2. identify a short-press, defined as when button released within < 1 second
  3. identify a long-hold, defined as when 1 second passes since button push-begin
  4. sleep as much as possible when not doing anything else

Below is a short pseudocode of what I have implemented so far. I think it covers all of these cases.

Do you see any possible refinements or potential issues? (E.g., I am interested in any subtle cases that might be blindspots for my approach.)

Pseudocode:

Main loop {
  Sleep
}

Falling-Interrupt {
  Disable Falling-Interrupt
  Enable 50-millisecond-Debounce-Timer-Interrupt
}

50-millisecond-Debounce-Timer-Interrupt {
  if PushButton state is still LOW {
    Enable Rising-Interrupt
    Enable 1000-millisecond-Hold-Timer-Interrupt
  }
}

1000-millisecond-Hold-Timer-Interrupt {
  Register as Pushbutton long-hold
}

Rising-Interrupt {
  if (Time since Falling-Interrupt < 1000 millisecond) {
    Register as Button Short-press
  }
  Disable 1000-millisecond-Hold-Timer-Interrupt
  Enable 25-millisecond-Debounce-Timer-Interrupt
}

25-millisecond-Debounce-Timer-Interrupt {
   Enable Falling-Interrupt
} 

Best Answer

I can't put code in a comment, hence an answer. My 'framework' for simple embedded systems is the main loop with polling. To minimize current consumption the main loop can wait let's say 50 ms in idle mode. I don't know which uC you use, I am familiar with PICs, which can awake from a sleep by an interrupt.

 set up an interrupt to wake me from sleep each 50 ms
 down_counter = 0
 for(;;){
    sleep();
    if( key down ){
       down_counter++;
       if( down_counter == 20 ){
          (start of) long_down detected
       }
    } else {
       if( down_counter > 1 && down_counter < 20 ){
          (end of) short press detected
       }
       down_counter = 0;
    }
 }