Do you have them wired to Arduino pins already?
When you want your code to always see all button press and release, your code can't use delay() without become massive and problematic and always slower response than...
No-blocking, event-driven code that lets you sense and respond 10's of times per millisecond. Your button code reads the contacts bouncing like a dozen press-release events in 2 ms, button debounce routines find ways to determine a stable state or just assume one after 20 to 100 ms which is way too long to wait with multiple buttons, leave some acting dead half the time.
What I wrote takes 3.5 ms of the same pin state after the last bounce, could take less by reading more often than twice a ms.
You don't need to know the button code to use it but may need help expanding from 2 buttons to 11 and reading every 40 or 50 micros instead of 250 --- only 1 pin is read in any read, it shortens void loop() greatly.
YOUR CODE only needs to read buttonHistory[ button # ] for (had to edit an error)
0 is the button held down
255 is the button left up
127 is the button changing from up to down, button just released & stable 3.5 ms.
128 is the button changing from down to up, button just pressed & stable 3.5 ms.
everything else is bounce.
If you see bounce and feel safe, you may assume the next stable state will be the opposite of the last.
For most uses,
void loop()
{
multiButtonsTask();
// make one of these for each button, ask for help making short steps out of long code.
if ( buttonHistory[ 0 ] == 127 ) // buttonHistory does not change as fast as this runs
{
// code for what pressing that button does -- May be broken into steps as switch/case
if ( finished ) or in final case buttonHistory[ 0 ] = 255; // quit triggering
}
Arduino can do light work in about 20 microseconds (320 cycles), if your sketch should read a pin every 50 us then make sure that void loop runs at least that often.
I predict that you will try what looks easiest first.