Read Multiple Buttons with a Single Microcontroller Input (4 Methods)

By Jeremy S. Cook

Freelance Tech Journalist / Technical Writer, Engineering Consultant

Jeremy Cook Consulting

August 21, 2024

Blog

Image Credit: Jeremy Cook

While today’s microcontrollers have fantastic processing capabilities, they still have their limits, especially when it comes to available GPIO pins. There are many solutions to this problem, and one option is to use a resistor network to output different voltages for each button, allowing your microcontroller to read multiple buttons with a single analog-to-digital converter (ADC) input. One might call this button arrangement a sort of manually operated digital-to-analog converter (DAC), which then feeds into the microcontroller’s ADC. In this article, I’ll outline four methods for accomplishing this task, each with its own set of pros and cons.

Caption: 3-bit manual DAC setup outlined later. Code found here, using A0 pin / Image Credit: Jeremy Cook

Voltage-to-Ground Network

Image Credit: Technoblogy

As described in this Technoblogy writeup, you can use identical resistors in a stepped voltage-to-ground divider configuration to produce different voltages. While very simple to set up, it has the disadvantage of constantly drawing power. It also cannot properly interpret simultaneous button presses. This implementation could work well in some situations, but it wouldn’t generally be appropriate for always-on embedded devices.

Interrupted Voltage-to-Ground Network

Image Credit: Technoblogy

From the same Technology page, it’s possible to construct a similar setup that only uses power when buttons are depressed. However, this circuit requires distinct resistor values to tell the difference between which button is pushed. Like the previous writeup, it cannot deal with simultaneous button inputs.

R-2R Ladder for “Manual DAC”

An R-2R ladder is an effective method for digital-to-analog conversion, where digital signals switch resistor outputs that sum up to different voltage intensities. It’s also possible to perform this DAC process manually using a series of toggle switches. In the so-called R-2R configuration shown below, the voltage input of each switch decreases geometrically (1/2V, 1/4V, 1/8V…), and the combined voltage input can be interpreted by the processor’s ADC. This allows for a relatively straightforward programming process.

Caption: How to set up an R-2R ladder button input and how not to / Image Credit: Jeremy Cook

The big disadvantage is that the button/toggle input needs to be either high or low, not closed or open, meaning extra wiring and an indeterminate state during switching. A version implementing solid-state components could potentially perform much better but would add complication to the circuit.

No-Ladder Voltage Divider Circuit

Looking at the R-2R circuit above, you may consider that a voltage divider can be made with only the double-Rs, omitting the single-R components. While possible, this configuration uses different resistance values to output distinct voltages as shown in the circuit/charts below.

Caption: Theoretical results of R2 and R3 as implemented in 1-Inch MIDI project highlighted in green–Spreadsheet available here / Image Credit: Jeremy Cook

This setup can read multiple button presses, but the behavior is difficult to optimize. Consider the chart shown for just two buttons. Red and blue represent the voltages seen for each button press, while yellow represents the combination of both. This would quickly get problematic if three or more buttons were involved.

I used this type of setup successfully on my 1-Inch MIDI controller project to save IO pins, though as seen in the highlighted green row in the chart above, my choice of resistors was not optimized. I’d probably choose different values if I were doing it over again. One could work out a generalized optimization equation for this setup, but that, as you might have read in an engineering textbook, “is left as an exercise for the reader.”

Should You use a button DAC/ADC Input Setup?

While there are specific tradeoffs to each muti-input method, there are a few more general considerations… to consider:

  • Additional circuit complication, thus more potential errors during the design phase and/or in use.
  • More inputs typically mean less “room” between buttons and that more precision is needed. Consider spreading out analog inputs between multiple ADC pins.
  • As parts wear and age, resistance values can change, potentially inducing error over time.
  • Potential performance penalty versus using only digital inputs.
  • Wake-from-sleep behavior may not be possible using ADC inputs.
  • Analog button input may require current draw. However, resistors can typically be adjusted proportionally to each other to decrease power drain.

Given the choice, it is generally preferable to use available digital inputs for button presses and the like. On the other hand, when resources are limited it’s good to have a few out-of-the-box techniques ready for consideration. For even more Arduino tips and techniques, be sure to check out my Developing With Arduino online training series!

 

 

 

Jeremy Cook is a freelance tech journalist and engineering consultant with over 10 years of factory automation experience. An avid maker and experimenter, you can follow him on Twitter, or see his electromechanical exploits on the Jeremy S. Cook YouTube Channel!

More from Jeremy