"Stock" answer:
Govner:
Thanks for the reply. This comment has my curiosity aroused. I am using the Trinket M0, 5 pins total. All pins except 1 are 'busy', thus the MCP23008. Where's the 'overkill' ? I must be overlooking a good alternative.
Whenever I see a post which includes the word "interrupt", I instinctively cringe.
Seems you - and many other "newbies" of course - do not understand what an interrupt is.
An interrupt is a mechanism for performing a task that can be performed virtually instantaneously, that must be performed virtually immediately, and that is not in itself intended to affect the flow of the main program (or delay it) in any way. Servicing a pushbutton essentially tends to fail all three criteria. The terms "instantaneously" and "immediately" are here defined in microprocessor, not human context, that is in terms of microseconds.
You wish to "interrupt" the operation of a particular part of your code. This is quite different to the above; to do this, you must insert decisions into the code where you wish it to be "interrupted".
What you can do - if precise timing is necessary and it is perfectly valid - is to record a value of millis() within an ISR so that you know precisely (to plus or minus a millisecond) when an event occurred. And while an interrupt cannot affect the flow of the main program, it can do something (called a flag) which is recognised in the main loop to affect the flow of that program.
The trick is to write "non-blocking" code. This prohibits the use of "While" loops or equivalent constructs (which automatically precludes "delay()"), but is instead, a chain of "If" constructs within the main loop(). Which incidentally, is a state machine. The important thing is that many different tasks are allowed to be performed apparently simultaneously given that each only does what it must at any given instant, promptly passing on to the next.
De-bouncing of contact closures or opening is performed by such a sub-process which repeatedly polls a button, key or switch and indicates a valid press or release only when a change from a previously accepted state is maintained on every poll while the millis() count advances a given interval, such as ten (milliseconds). Every time the change reverts to the previous within the prescribed de-bounce interval, the status is reset and a new starting millis() count will then be determined if and when a change from the previously accepted stable state is again found.