# Detect how many push buttons are being pressed using a maximum of two Arduino pins

Imagine you have a varying number of push buttons that you need to connect to a microcontroller such as Arduino, of which you can only use a maximum of two pins (not counting 5v and gnd). Each button must be wired to the next one, and the total number of wires between them must not exceed 4, with 2 being 5v and gnd. The objective is to know how many push buttons are connected and determine when a push button is pressed, and which one. The push buttons don't have a fixed order; you must be able to change their positions if necessary.

I managed to make it work to a certain degree by using 2k resistors along with the buttons and measuring the resistance in the end. When I press a button, I read the resistance up to that point, adding an extra 1k resistor before the Arduino pin. So if I get an even value, I divide it by two and I get the total number of push buttons. If I get an odd value, it's because some button is being pressed, so I divide it by two and round it down, getting the position of the button being pressed.

The problem is that I can't have both the information of the total number of buttons and the button being pressed at the same time. While I'm pressing the button, I can remove a button to the right and I have no way of knowing. Also, if I press two or more buttons simultaneously, only the leftmost button being pressed will be detected.

Is there a way of doing this in a somewhat inexpensive way, being able to know at any given time how many buttons there are, how many are being pressed and which ones, using only a maximum of two pins?

• Can you use additional active circuitry or ICs, or are you constrained to just using passive components and 2 pins on your Arduino? Commented Jun 5, 2022 at 19:08
• I can use additional active components and ICs, as long as I don't use more than two pins.
– mnib
Commented Jun 5, 2022 at 19:10
• Well, you could use 2 pins for an I2C interface and use something like an I2C I/O expander (or multiple ones) to connect to the buttons. You can bit-bang the I2C interface if all you have is regular GPIO pins on the Arduino. You'd have to continually poll the parts to see if a button was pressed, not sure what your minimum "press" time is or if that's practical for your system Commented Jun 5, 2022 at 19:12
• @jsotola it's just a small device I'm making, but with the constraints I mentioned
– mnib
Commented Jun 5, 2022 at 19:17
• what is the maximum number of buttons? Commented Jun 5, 2022 at 19:20

With 8 buttons there are 255 possible combinations of presses. Consider an R-2R ladder.

If the uC has a 10 bit A/D, you should have enough resolution to determine the input voltage to a 1-in-255 precision. Continuously polling the A/D converter and logging the results will capture any button status change no matter how many buttons change status at the same time. This gets you 255 buttons on one pin.

0.1% resistors are cheap, and you need only two values for the entire span. You will need a very stable voltage reference. The initial value tolerance is not so critical, because the no-button-pressed reading sets the voltage scale. The temperature coefficient is more important. National used to make a voltage reference with a temperature-controlled oven on the same chip. It takes a minute to warm up, and then sits there like a stone.

All of that was for 255 buttons on one uC pin. Because you have 2 uC pins available, there is a better way to go.

With two pins, you can split (electrically) the 8 buttons into two groups of four, one group for each uC pin. Now you have two 4-bit R-2R ladders. Each produces 16 times the voltage range per button. You can use 1% resistors and a much less expensive reference, and any basic onboard 8-bit A/D has more than enough precision for this.

Two 5-bit ladders get you 10 buttons, etc.

• You dont need stable voltage reference if you use same voltage reference for ADC and R-2R ladder. Commented Jun 6, 2022 at 6:48
• Instead of building a R-2R ladder, why not using an 8 bit DAC? An integrated resistor ladder reduces problems with temperature differences.
– Uwe
Commented Jun 6, 2022 at 10:14
• Not using an external voltage reference depends on many of the uC's A/D characteristics, which we know nothing about. Commented Jun 6, 2022 at 11:07
• The R-2R ladder is a DAC, and two 4-bit ones cost pennies. There are very few parallel-input DACs without a uC interface. The DAC-01 is obsolete and costs over $6.00. Commented Jun 6, 2022 at 15:20 You can use an I2C IO expander powered by 5V. Connect the two IO pins of the Arduino to the I2C SDA and SCK lines. Use the 5V power to power the expander chip. Something like the MCP23008-E/P costs like$1.55 at Digikey.

1. Each chip features 8 digital IO pins that can each connect to one switch.
2. The chip features three address pins, so you can put up to 8 chips on the same I2C bus. This lets you sense up to a total of 64 switches.
3. The chip can be powered directly from a 5V supply.