2

I have 20 microswitches like this:

enter image description here

How would you wire them to the RaspberryPi's GPIO, using multiplexing techniques?

PS: here is a related discussion about multiplexing but it's theoritic and doesn't discuss precise GPIO wiring, etc.

  • You will have better results in electronics.stackexchange.com you need a piece of hardware. – fcm Feb 24 '17 at 4:26
  • "Which multiplexer chip.." is opinion-based or a shopping request (i.e., explicitly off-topic), so I have removed that (also, I think the answer here is as simple as basic arithmetic: Any combination of chips with a total of 20 inputs.). How to use any and all such chips (or everyone's individual favourite, etc.) is too broad/inappropriate to a non-discussion, Q&A format. If you have a multiplexer and aren't sure how to use it, or are wondering if a specific chip can be used with the Pi, questions like that are fine. – goldilocks Feb 24 '17 at 9:47
  • Any combination of chips with a total of 20 inputs. : not necessarily. By using a matrix (5 lines for rows / 4 for lines for columns, i.e. only 9 digital lines) it could be possible to address 20 inputs. That's why it was not a shopping request, but more "Which chip is known to work for this purpose?", such as the well known 74HC164, etc. – Basj Feb 24 '17 at 14:51
  • I just see it's the idea that you developed in your answer, making my comment useless ;) – Basj Feb 24 '17 at 14:55
4

I have a bank of 8 LEDs where I need to be able to tell which one of them a photoresistor is positioned over, and I think this is a version of the same problem.1 To determine which LED is lit, I don't need to be able to control them all individually. Instead I use 5 lines -- actually transistors toggling the return to ground, since one GPIO directly is not enough for multiple LEDs. Four of them control two LEDs each, call those pairs A, B, C, D, and one of them controls the final return from a cross-section bank of 4 LEDs, the second one from each pair. This way, I can turn each pair on until the photoresistor triggers, then I just turn off the cross-section of four. If the pair is A and the photoresistor then goes off, I know the LED is A2. If it stays on, it must be A1.

To apply this to buttons you need a slightly different strategy, providing power to "columns" that can be toggled and then testing the return "rows" with inputs. Shown below, the GPIO output columns are labeled A and B and the GPIO input rows are labelled IN1 and IN2. For simplicity I've used four buttons, which multiplexed this way is a bit pointless, but if there were 9 buttons you would only need 3 outputs + 3 inputs = 6 GPIOs. The numbers do not have to be the same, so with 20 buttons you could use 5 outputs and 4 inputs -- or 4 outputs + one non-toggle 3.3V connection as an output line or, as in my LED/photoresistor scenario, one ground line without an input (to save a GPIO), a total of 8 GPIOs. I'll explain why you can leave one GPIO output out in more detail.

schematic

simulate this circuit – Schematic created using CircuitLab

The inputs (IN1, IN2), are set as interrupts. Note they are pulled to ground through a resistor (this also limits the current from the GPIOs, and more importantly, the 3.3V rail if you use it as a source for one column). The outputs are both set high. When an input triggers, you then turn off all but one of the outputs and cycle through them (not necessary here since there are only 2).

  • IN1 triggers and stays high when B is turned off = SW1
  • IN2 triggers and stays high when B is turned off = SW2
  • IN1 triggers and goes low when B is turned off = SW3
  • IN2 triggers and goes low when B is turned off = SW4

Note you never have to toggle A -- this is why one of the inputs can just be the 3.3V rail, saving one gpio, so with a 5 x 4 grid you would only need 8 GPIOs. Again, alternately you could have one ground line without an input on it.

This only applies to the use of one button at a time. I do not think you can multiplex if you need to distinguish an arbitrary number; just get some bus based multiplexers or shift registers, they are cheap and simple anyway (along those lines, there are 8 channel I2C multiplexers than can be chained together and/or configured to use different address).

Also...

You need to implement a bounce time on the inputs. With buttons like that, it does not need to be more than 10-20 ms, but you must do it for both press down and release. Make sure you can do that consistently with just one button, or with a set of individually connected buttons, before you try this. Otherwise the bounce will create uncertainty for you ;)

I have a practical demo of how to implement bounce time here.


1. If you are are okay with allowing for a minimum hold time of say 50 milliseconds per GPIO output to toggle and test, so 200 ms with 20 buttons (which should be fine with human fingers). I think this is a highball estimate but it could end up requiring more.

  • Thanks for this answer @goldilocks ! Would you share a small schematics ? It would help me (and probably other users) a lot to understand... Can I use a 74HC164 with what you explain ? – Basj Feb 24 '17 at 22:33
  • Doing the schematic made me realize the idea needed a bit of tweaking for buttons ;) WRT the "well known 74HC164", I think you are slightly fuzzy: That's just a SIPO (serial in, parallel out) shift register. This means you can control multiple outputs with one input, i.e., you could use it for the outputs above. For the inputs you would need the reverse (parallel in, serial out = PISO). But these are cheap, so you might as well skip the complicated multiplexing and just get enough to read 20 buttons individually. – goldilocks Feb 26 '17 at 7:35
  • You can also get bidirectional I2C/SMBus based multiplexers such as the PCF8574, which has a linux kernel driver making it very easy to use. You just read a value from a sysfs node. You'll find discussions of that online; I have one and it and the driver work (there might now be a device tree thing to use, I'm away from home right now and can't check). I haven't actually used it much though, so I'm not sure if you can have 4 channels out and 4 in, but if you could, it would do for all 20 buttons. – goldilocks Feb 26 '17 at 7:56

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.