9
\$\begingroup\$

Here is the product. I understand the idea: these 16 buttons use a 4x4 matrix. 4 lines for rows, 4 lines for columns, and we have 8 cables.

enter image description here

But:

  1. How can this work without any multiplexer ?

  2. Can this detect accurately presses of multiple buttons? Even if buttons use same row or same column? Example: buttons at position (2,2) (2,3), (3,2), and (3,3) pressed at the same time.

  3. How does it work?

\$\endgroup\$
15
  • 7
    \$\begingroup\$ This is common knowledge as you'll find with a Google search for 'keypad multiplexing' or suchlike. Did you not try that first, before posting this? \$\endgroup\$
    – TonyM
    Commented Mar 7, 2017 at 14:10
  • 3
    \$\begingroup\$ @TonyM Of course I did, many searches, and I even ordered a few multiplexer chips 74HC164 that arrived at home a few days ago. I was about to wire everything with this multiplexer chip when I found this. Then I was wondering "how can this work without any multiplexer" ? \$\endgroup\$
    – Basj
    Commented Mar 7, 2017 at 14:15
  • 1
    \$\begingroup\$ The device on the left must have a code of multiplexing inside it \$\endgroup\$ Commented Mar 7, 2017 at 14:20
  • 3
    \$\begingroup\$ @TonyM Thanks for pointing me this. Can you link the PDF instead of making a mystery ;)? Maybe I searched with other keywords than keypad, etc. and I probably didn't find the same. \$\endgroup\$
    – Basj
    Commented Mar 7, 2017 at 14:35
  • 1
    \$\begingroup\$ @Basj: having multiple presses is not a problem. You scan all four lines one after the other. If a button is found pressed in line 1, you note it. When it comes to line 3, you find another button pressed there, you note it, too. In the end, you get both buttons. As long as you're able to scan significantly faster than people can press buttons, you won't miss it. \$\endgroup\$
    – Gábor
    Commented Mar 7, 2017 at 18:18

4 Answers 4

23
\$\begingroup\$
How can this work without any multiplexer?

It doesn't. The keypad board seems to have just switches, with maybe some diodes we can't see. However, the left board looks like it has a processor on it. Almost certainly, multiplexing is being done in firmware.

The multiplexing algorithm works something like this:

  1. Drive one row high, the others low.

  2. Enable passive pulldowns on the column lines.

  3. See which column lines are high. The buttons at the intersections of those column lines with the one asserted row line are pressed. The other buttons on that row are released.

  4. Repeat back to step one, asserting the next row in sequence.

The above process is repeated fast enough so that all the buttons are checked within a time that still feels instantaneous to a human observer. The human limit of "instantaneous" in this context is about 50 ms. Even a low end microcontroller can scan a 4x4 keypad in much less time than that.

Can this detect accurately presses of multiple buttons?

Probably yes. One way is to put a diode in series with each button. Those could be on the bottom side of the board you show. With the diodes, the algorithm described above just works.

Another way is by putting resistors in series with lines and measuring their analog voltage. Even with multiple buttons shorting multiple row/column lines together, you can eventually figure out which buttons are pressed. This requires A/D inputs in the micro, not just digital inputs as when diodes are used.

\$\endgroup\$
9
  • 1
    \$\begingroup\$ Thanks. What about multiple presses at the same time then? Note: the left board is a RaspberryPi. \$\endgroup\$
    – Basj
    Commented Mar 7, 2017 at 14:27
  • 1
    \$\begingroup\$ @Hayman why is it so? Can you give an example? Why is (1,2), (2,2), and (3,3) pressed at the same time a problem when there is no diode? Maybe would you have a small schematics? As this point is really crucial, maybe it's worth for a dedicated answer @Hayman? \$\endgroup\$
    – Basj
    Commented Mar 7, 2017 at 14:47
  • 8
    \$\begingroup\$ +1 for "the left board looks like it has a processor on it". Loved that. \$\endgroup\$ Commented Mar 7, 2017 at 14:54
  • 3
    \$\begingroup\$ @Basj it's obvious if you play with it. Whenever you press a button, you're connecting a row to a column. Whenever a row and a column are connected, the key at the intersection registers as pressed. But if at least 3 keys are pressed, a row and a column can be connected indirectly. \$\endgroup\$
    – hobbs
    Commented Mar 7, 2017 at 22:55
  • 2
    \$\begingroup\$ @Basj Have a look at this picture. The red lines indicate a logic high level. If you hold the 3 buttons indicated with an 'x' you can trace them and see the path in which the signal will flow. Firstly row 1 is selected and is set high, by pressing button 1,1 this makes the first column high. By pressing button 1,2 we have now made row 2 high. Now if we press any other button on row 2 we will make another column high. The problem with this is the μC is dumb, it knows it set row 1 high and it sees a high on column 3, therefore it thinks button 1,3 is high \$\endgroup\$
    – user103993
    Commented Mar 8, 2017 at 8:26
9
\$\begingroup\$

Without diodes... you'll get phantom rectangles.

For instance in your example (2,2) (2,3), (3,2), and (3,3); you chose an ironic example by choosing a rectangle. If you actually press all four, it will work. But if you press any three corners of the rectangle, the fourth corner will also appear to be pressed, even though it's not.

That keypad is clearly meant for keyboard data entry, where the user convention is one keypress at a time. You notice there are no "shift" keys on a gas station credit card entry keypad, for instance.

However, if you made S1 a shift key, and S3 an alt-shift key such that users might reasonably hold both while also pressing S13, then S15 would also appear to be pressed.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Indeed, most data entry keyboards are not intended to have more than 2 keys pressed at a time, so there is no problem. Musical keyboards are another story, as many keys may be pressed at a time. Most of them have diodes or independent wiring to each key. But I did find one musical keyboard in a second hand shop (priced at 9 euros) that did not have any appropriate adaptation for multiple keys pressed at a time, with unpredictable and annoying results! \$\endgroup\$ Commented Mar 7, 2017 at 20:28
  • \$\begingroup\$ The keyswitches could be of a type that has a builtin diode, or there could be diodes hidden underneath them. \$\endgroup\$ Commented Mar 8, 2017 at 15:46
1
\$\begingroup\$

Here's how to do it without continuous scan:

  • Set all drivers to high
  • Enable passive pulldowns on receiving lines
  • Set pin change interrupt to detect one of the lines going high (or changing in level)
  • When this happens, enable keypad scan, say every 10ms
  • Scan normally and process key presses
  • After a timeout without events, stop scan and restart at first bullet point
\$\endgroup\$
0
\$\begingroup\$

I have done this with Assembly Language on bare Atmel AVR microcontrollers.
For simplicity: Keypad Rows: use Arduino Pins 4,5,6 and 7 (AVR pins PD4, PD5, PD6 and PD7) Keypad Columns: use Arduino Pins 8, 9, 10 and 11 (AVR pins PB0, PB1, PB2 and PB3) Make Row pins inputs with pull-ups enabled. Make Column pins Output and output zeroes to them. Enable Pin Change Interrupts on all row and column pins. http://playground.arduino.cc/Main/PinChangeInterrupt Pressing a button on the keypad will pull a Row pin low. The interrupt routine needs to read the row pins and find which pin is low. The upper 4 bits should be three ones and one zero. If you use a uint8_t 8 bit variable you can divide it by 16 or (var >> 4) to put the 4 bits in the lower bits of the number. You can use a bitwise OR | operation with 240 to set the upper 4 bits to 1s and a bitwise NOT ~ operation to invert all the bits so you only have one bit set representing the row the button press was on. Store this number as 0, 1, 2 or 3.
Switch the pin configuration:
Make Column pins inputs with pull-ups enabled. Make Row pins Output and output zeroes to them. Read the column pins and find which pin is low. Do a similar manipulation with this value except you don't have to shift the number to the right. After the var ^ 240 and ^var you have a single bit to represent the column the key press was on. Remember to disable interrupts before reconfiguring ports as it will likely trigger unwanted interrupts. You may have to clear interrupt flags when leaving the interrupt routine to prevent duplicate interrupt handling.

\$\endgroup\$

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.