# Multiplex dip switch input to microcontroller

I have 3 DIP switch packages with 8 switches each, and not enough inputs on my microcontroller. This article (you have to download the pdf to see the schematic) gives an example of what I want to do.

In the comments section, many people say the circuit won't work. I disagree; It looks like those commentators missed the fact that one of the lines is drawn as an 8 pin bus, and the fact that unused RA pins will be set as high impedance inputs. Still, I wanted to get a second opinion from the experts here!

Edit: After reading the many good answers to this question it seems my initial impression was wrong. This circuit will only work for momentary push buttons, not dip switches.

• The problem with the article you cite is that each of the 32 DIP switches needs a diode in series with it. Otherwise, if certain combinations of switches are closed (any three corners of any rectangle, if you draw the switches in a rectangular array), it will appear that the switch at the fourth corner is closed as well, even if it isn't. – Dave Tweed Oct 19 '12 at 19:35
• @DaveTweed, Perhaps I'm just missing it -- each input can be modeled independently with a pull up resistor and 4 NO switches that can be closed to connect to one of 4 outputs, which is either Hi-Z or L. The outputs are strobed L such that each switch can be read discretely. I can't visualize a scenario where any combination of the 4 switches on an input would cause a false read, provided that the strobing is done correctly. Can you help me understand the issue that you're describing? – HikeOnPast Oct 19 '12 at 19:42
• For simplicity, let's say you have two rows and two columns -- four switches. If any three of the switches are closed, all of the rows and columns are shorted together, and there's no way to detect whether the fourth switch is open or closed. – Dave Tweed Oct 19 '12 at 19:58
• Got it. Good catch. Now to tidy up my bad answer... – HikeOnPast Oct 19 '12 at 20:44
• I don't know what the issue is with the circuit, except not drawing the bus line thicker (but it is implied by the angle at which wires connect to it). The n'th uC input is connected to the n'th switch of each of the 4 dip switches, 3 of which are at high impedance at any given time, so they don't affect the one being measured whether they are open or closed. In my opinion it works just fine. – apalopohapa Oct 20 '12 at 2:40

The schematic in the article is poorly drawn. I think he probably meant to imply an 8-bit bus, but the dots imply discrete connections. On top of that, there isn't a bus width called out (which would disambiguate things).

As DaveTweed points out, there is a risk of false switch closure detection in certain switch combinations unless a diode is used in series with each switch. Note that if the design requirement only requires reading one closed switch at a time, the circuit will work just fine.

• I agree it could be drawn more clearly. He does specify that there are 8 data lines in one (SWITCH_INPUT (7 to 0)), but instead of a dot he should have indicated that each line was connected to a bus, and not drawn a line between the switches and the RB inputs. Thanks for double checking this. – Marlon Smith Oct 19 '12 at 18:59

You could also use an I2C (or SPI) input multiplexer to read as many DIP switches as you want with only 2 (or 3) wires. They'll add less than a buck to your BOM, and can be useful for other pin expansion needs, too. I'm using this DIP package (also available in SOT and QFN) There are others.

• Yes, I like these chips as well. I have an existing Blackfin board that needed some additional GPIO, but only had a SPI interface exposed. I built a tiny little daughtercard with two MCP23S17s on it that gives it 32 more lines of additional I/O ... and you could stack of four of them up to get a total of 128 lines! – Dave Tweed Oct 19 '12 at 20:06
• Yes, my approach too. Simple and cheap. – kenny Oct 19 '12 at 20:39

Instead of using the circuit from the article, you could try this:

If you have a free ADC input, you can use the switches to produce a voltage, then use the ADC to convert to digital. You could connect the switches to some DACs, or make a DAC from an R-2R ladder of resistors. There's a decent explanation of R-2R ladders here.

As long as the resolution of the ADC is greater than the resolution of the DAC, you can measure combinations of input switches. For example, with a 12-bit DAC, you could easily determine the states of 10 switches.

Pay attention to buffering the input to the ADC (an opamp is a good idea, but a cap could be enough). Also, make sure that the DAC output for any combination doesn't fall exactly on the expected ADC switching threshold (ie, if the ADC's most significant bit switches between 0 and 1 at 0.5V, make sure the DAC output is a little more than 0.5V when the most significant switch is turned on).

• This works for a fairly small number of switches, but not 32. Even at 10 bits, you'd need 0.1% resistors to build an R-2R network that is accurate enough. – Dave Tweed Oct 19 '12 at 21:43

Yeah so long as you only drive one of those 4 row pins at a time and then read the 8 inputs it looks like you are right. I only looked at it for about a minute though :)