Button debouncing using bit shifting

The relevant Jack Ganssle code is:

// from https://www.ganssle.com/debouncing-pt2.htm
// Idea courtesy Ganssle Group. Called from a 5ms timer,
// the debounced state only ever changes when the pin
// has been stable for 40ms. Initialize debounced_state
// to whatever is  "inactive" for the system (HIGH or LOW)
//
uint8_t DebouncePin(uint8_t pin)
{
  static  uint8_t debounced_state = LOW;
  static  uint8_t candidate_state = 0;
  candidate_state = candidate_state << 1 | digitalRead(pin);
  if  (candidate_state == 0xff)
    debounced_state = HIGH;
  else  if (candidate_state == 0x00)
    debounced_state = LOW;
  return  debounced_state;
}

without this strange end condition:

that was highlighted in:

The awkward value of using 0xFFF0 as the end condition is that it sort of does the work of state change detection--in a bounce-free release, there's only one iteration where 0xFFF0 matches the record of history. If there is a bounce on release, the release would not match and be ignored.

Jack Ganssle's code does debouncing, not the uncertain falling-edge-detection that the OP's code attempts.

If the goal is clean edge detection, consider rate-limiting the edge detection: