title: Switch Debouncing Logic in C
body: <p>I came across <a href="https://www.embedded.com/electronics-blogs/break-points/4024981/My-favorite-software-debouncers" rel="nofollow noreferrer">this code by Ganssle</a> regarding switch debouncing. The code seems pretty efficient, and the few questions I have maybe very obvious, but I would appreciate clarification.</p>
  
  <ul>
  <li>Why does he check 10 msec for button press and 100 msec for button release. Can't he just check 10 msec for press and release?</li>
  <li>Is polling this function every 5 msec from main the most effecient way to execute it or should I check for an interrupt in the pin and when there is a interrupt change the pin to GPI and go into the polling routine and after we deduce the value switch the pin back to interrupt mode?  </li>
  </ul>
  
  <p><sub></sub></p>
  
  <pre><code>#define CHECK_MSEC  5   // Read hardware every 5 msec
  #define PRESS_MSEC  10  // Stable time before registering pressed
  #define RELEASE_MSEC    100 // Stable time before registering released
  // This function reads the key state from the hardware.
  extern bool_t RawKeyPressed();
  
  // This holds the debounced state of the key.
  bool_t DebouncedKeyPress = false;
  
  // Service routine called every CHECK_MSEC to
  // debounce both edges
  void DebounceSwitch1(bool_t *Key_changed, bool_t *Key_pressed)
  {
      static uint8_t Count = RELEASE_MSEC / CHECK_MSEC;
      bool_t RawState;
      *Key_changed = false;
      *Key_pressed = DebouncedKeyPress;
      RawState = RawKeyPressed();
      if (RawState == DebouncedKeyPress) {
          // Set the timer which will allow a change from the current state.
          if (DebouncedKeyPress) Count = RELEASE_MSEC / CHECK_MSEC;
          else                 Count = PRESS_MSEC / CHECK_MSEC;
      } else {
          // Key has changed - wait for new state to become stable.
          if (--Count == 0) {
              // Timer expired - accept the change.
              DebouncedKeyPress = RawState;
              *Key_changed=true;
              *Key_pressed=DebouncedKeyPress;
              // And reset the timer.
              if (DebouncedKeyPress) Count = RELEASE_MSEC / CHECK_MSEC;
              else                 Count = PRESS_MSEC / CHECK_MSEC;
          }
      }
  }
  </code></pre>