Unfortunately, I'm not sure what the right question is; I'have a 12-key keypad. I wanted to utilise a matrix based approach, except that they all seem to be connected in such a way, that they're floating when not pressed; when you press one, it connects to ground. This seems to me as if it's prepared for a set-up with a pull-up resistor on the wire over to the MCU, and not a matrix-style reading, where I (if I understand correctly) sequentially pulse on the rows, and sequentially read the voltage on columns.

However, I don't have 12 spare pins on my MCU, so I'm wondering how to minimize the number of pins needed to read this 12-key keypad.

Are there any ICs that I might use? Any approaches?

If I recall correctly, the board it used to be connected to had several (de)multiplexers connected in cascade, but I couldn't figure out the way it worked. However, I'm pretty sure the keypad itself is wired like this (it has its own connector as it's on a separate board which I'd like to keep), and that makes me confused.

  • \$\begingroup\$ So, electrically, this keypad is wired as a 12x1 instead of the typical 4x3 matrix? Not sure who thought that was a good idea... \$\endgroup\$ – ThreePhaseEel Jan 4 '17 at 0:07
  • \$\begingroup\$ It seems so, yes; unless there's something I've overlooked. Visually, it's actually a 6x2 matrix, but I've tested with the multimeter that all the buttons seem to map on the 1-12 pins of its connector. \$\endgroup\$ – Tomáš M. Jan 4 '17 at 0:09
  • \$\begingroup\$ If you have six pins to spare, you could use two 74148 8-to-3 encoders. Or with four pins: drive a 74154 decoder from three outputs and read the common line. \$\endgroup\$ – Ken Shirriff Jan 4 '17 at 0:11
  • \$\begingroup\$ I do indeed have 6 pins to spare, do you mean simply wiring one to buttons 1-8 and the other to 9-12? \$\endgroup\$ – Tomáš M. Jan 4 '17 at 0:11
  • \$\begingroup\$ @TomášM: yes, three pins to read one set of buttons and three pins to read the other set. Edit: 1-6 and 7-12 would be better so you can distinguish the no-button-pressed case. \$\endgroup\$ – Ken Shirriff Jan 4 '17 at 0:13

Here ya go. Schematic below. I've only shown 8 buttons, but 74HC4067 has 16 analog channels for up to 16 buttons.

Select which button you want to check by driving the 4 bit line to the desired channel, then read the MCU input. High = button not pressed. Low = button pressed.

Simple debounce algorithm is to only scan say 30x per second max.


simulate this circuit – Schematic created using CircuitLab

  • \$\begingroup\$ Do you think I can use two CD54HCT151 multiplexers? \$\endgroup\$ – Tomáš M. Jan 10 '17 at 23:33
  • \$\begingroup\$ Well... you could... but then it gets complicated. You need to use SEL3 (the highest bit) to enable one HCT151 or the other HCT151. Then you have to combine the outputs of the two ICs to one MCU input, or use two MCU inputs. But sure, it's possible. \$\endgroup\$ – Vince Patron Jan 11 '17 at 1:52
  • \$\begingroup\$ Sorry for being dense, but how would I use SEL3 for that? Having one output which is just pulled to 5V on both, so I don't have to use the enable pin? \$\endgroup\$ – Tomáš M. Jan 11 '17 at 10:19
  • \$\begingroup\$ Oh right. You're right. You can drive both HCT151 with same 3 data bits, leave both enabled, and the output of each one can go to two MCU inputs. Yup, that will work well; just adds an extra pin, but will work perfectly. \$\endgroup\$ – Vince Patron Jan 11 '17 at 14:56

If the common connection is floating, an approach using an output pin and an ADC would be to tie one switch input terminal the output pin and the common input to the ADC input. Then connect another switch input to ground and connect all the other switches to points on a string of eleven 1K resistors. If one needs low-power wakeup and the processor's ADC pin doesn't have weak pull-up that can be pulled low through about 3K of resistance, add a 100K pull-up to the ADC pin.

When idle, ground the isolated I/O pin and set the other for weak pull-up. That pin will be pulled down if any button is pushed.

To find out which button is pushed, set the output to VDD and read the ADC (preferably with the pull-up disabled). The voltage will then indicate which pin is pressed. If the switch makes even halfway decent contact (e.g. 3K or less of resistance) the voltage should be largely independent of switch resistance.

  • \$\begingroup\$ I do not have an output pin, the buttons are connected to ground directly \$\endgroup\$ – Tomáš M. Jan 10 '17 at 23:05

There are many solutions. Just how many IO pins do you have available?

  1. Use a 16-bit I2C expander IC. Plenty out there. If your MCU has no I2C, you can bit-bang the interface. Downside is this would require 12 pull resistors.

  2. If you have 4 outputs and 1 input available, use a demux IC (e.g. 74HC154) to "scan" the keypad. Each demux output drives a key and the common output of the keypad goes to your MCU input. When your scan hits a key that is pressed, the input will be driven high. This takes 5 IO lines but advantage is it needs only 1 pull resistor on your MCU input (or none if your MCU has built-in pull). It might need 12 diodes or a demux that has open-collector outputs if keys can be pressed simultaneously.

  3. A totally cheesy design is to have a different value resistor for each key. Then use either a divider or a current source/sink read by an ADC so that each key presents a different voltage to the ADC. I've seen this used in actual commercial products but use only if you are desperate and can only spare 1 IO pin; this takes a lot of good SW to debounce and get working reliably. It also very difficult to detect simultaneous key presses.

I can draw you a schematic if Option 2 circuit is not obvious to you.

Also, you need to consider: 1) debounce algorithm, 2) tracking the press and release of multiple key presses. For example, when someone is typing very fast their keystrokes will overlap. You need to consider if you need to allow for this or not.

  • \$\begingroup\$ I'm actually indeed a bit unclear about 2; I don't really have access to the common output, the common connection of all the buttons is just ground, electrically on the board itself. I'm not sure if this is an issue? \$\endgroup\$ – Tomáš M. Jan 4 '17 at 0:23
  • 1
    \$\begingroup\$ Ah, ok, keys only GND. Well, you can still use same concept but kind of backwards. Take a look at 74HC4067 16:1 analog mux. The "scan" can connect your MCU input to any one of 12 keys. The input needs a pullup. When your "scan" hits a key that is pressed, it pulls down the input. Let me know if that's clear or if a schematic is needed. I can add another answer. \$\endgroup\$ – Vince Patron Jan 4 '17 at 0:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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