I would like to interrupt a program when a key is pressed on a keypad, and figure out which key has been pressed. I do not care much for ghosting effects, this is supposed to be operated with one finger.

I came up with the following schematic, and I would like to know if this is going to work. enter image description here

Normally, this circuit protects against shorts from wrong output configurations. It provides 15Hz debouncing, and a common interrupt pin.

Note the KEYPAD_INT net is connected to D13 on an Arduino Mega, which is connected to a LED. I assumed this is not an issue since the ~100k input pullup is not enough to light it, and pushing a key will always force ~0.3V on this pin.

The columns are all inputs, built-in pull-up removed.

  • In sleep mode: all rows are driven LOW. When a key is pressed, KEYPAD_INT is driven low and a pin change interrupt is generated.
  • In ISR: all rows are high-Z, and for each row, drive it low and loop on each column until a low is detected. If none detected, it's a key release.
  • \$\begingroup\$ I could not find a circuit online combining both interrupts and debouncing, so this post should help others trying to do the same. \$\endgroup\$
    – user42875
    Commented Mar 19, 2021 at 15:17
  • 1
    \$\begingroup\$ Your large RC time constants for debouncing mean that some processor inputs will have very slow rise times. That can be problematic for some types of input pins. You also added a lot of extra components when this could normally be done in software. This might be a good solution for you but I don't think it is a good solution in general. \$\endgroup\$ Commented Mar 19, 2021 at 15:46
  • \$\begingroup\$ It might work but is sub-optimal for cost and noise-induced slow-rising multiple edges. and 15 Hz debounce is excessive even for clunky switches. \$\endgroup\$ Commented Mar 19, 2021 at 20:52

1 Answer 1


It depends if you want exclusive button reads or any combination.

You can use the data (or its inverse to trigger IRQ) then MASK the IRQ until no button is pressed and debounce the switch in S/W. Discrete or a 9-pin 8R-array may be used with a PISO.

I simulated a 4 kHz Clock and 250 Hz sample rate for 16 buttons. 4 may be left out.

One way is the traditional matrix read using 3 clock ports from uC and 1 serial data port.

There are ways to simplify this further, maybe.

IF you have trouble finding a non-blocking debounce routine you could always old-school put a cap across every switch with 1M*10nF=10ms that holds up more than the 5ms bounce time (typ) and then the cycle time of 4ms will capture on the 1st instant even if pressed for only 1us. Otherwise in S/W, you are just looking for 2 consecutive states to validate the change... More if you want to slow down the response time for changes. But n-key rollover is possible. Make or IRQ service routine as short as possible.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.