Howdy, given 30+ years of coding, 90% assembler, I've hit this wall.... just a few times....
Look in the code repository for my best debounce algorithm:
Set a countout for "debounced loops means valid input", this value is number of scan loops until confident of valid state change.
A> It takes the current switch state, and loops on that it doesn't change, until a countout that means it Didn't change. == exit with new switch state
if it changed: reload countout & current switch state and go back to A>
If you've got a Really noisy environment: set another countout for the number of state change/reloads until you "ignore" it.
Then a Genuinely pushed button will "eventually" win, just by breaking through enough "ignore" loops.
This method is the only nonprobabilistic approach I've ever seen/heard of.
PITA--- I had to think of it, because I didn't have anyone to show it to me...
If you sense some ego in this, consider it frustration that I thought this wheel was already round....
I shouldn't have had to think of it (or did somebody else not want to share...)
Sorry it's written in Freescale SO8 assembler, but if you can't port it, you're not a real coder yet.
Try it... I'm thinking you'll like it. It's eminently tunable (you can even split the state change +->- count from ->+ if you can characterize your switch that well)
It's fun to watch a test pin reflect the switch state as the software scans it on an o'scope. That really lets you set the validity loop counts.
Enjoy.. & G,H... <<<)))