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: