Tutorial: Analog input for multiple buttons – Part Two
This is chapter forty-six of a series originally titled “Getting Started/Moving Forward with Arduino!” by John Boxall – A tutorial on the Arduino universe. The first chapter is here, the complete series is detailed here.
[Updated 19/01/2013]
A while back I described how to read multiple buttons using only one analogue input pin. However we could only read one button at a time. In this instalment we revisit this topic and examine an improved method of doing so which allows for detecting more than one button being pressed at the same time. This method is being demonstrated as it is inexpensive and very easy to configure.
(For a more exact and expensive method please consider the use of the Microchip MCP23017 which allows for sixteen inputs via the I2C bus).
As you know the analogue input pins of the Arduino can read a voltage of between zero and five volts DC and return this measurement as an integer between zero and 1023. Using a small external circuit called a “R-2R ladder”, we can alter the voltage being measured by the analogue pin by diverting the current through one or more resistors by our multiple buttons. Each combination of buttons theoretically will cause a unique voltage to be measured, which we can then interpret in our Arduino sketch and make decisions based on the button(s) pressed.
First the circuit containing four buttons:
Can you see why this is called an R-2R circuit? When building your circuit – use 1% tolerance resistors – and check them with a multimeter to be sure. As always, test and experiment before committing to anything permanent.
Now to determine a method for detecting each button pressed, and also combinations. When each button is closed, the voltage applied to analogue pin zero will be different. And if two buttons are pressed at once, the voltage again will be different. Therefore the value returned by the function analogRead() will vary for each button-press combination. To determine these, I connected a numeric display to my Arduino-compatible board, then simply sent the analogRead() value to the display. You can see some of the results of this in the following video:
The analogRead() results of pressing every combination of button can be found in the following table:
After this experiment we now have the values returned by analogRead() and can use them in a switch… case function or other decision-making functions in our sketches to read button(s) and make decisions based on the user input. Unfortunately there was some overlap with the returned values and therefore in some cases not every possible combination of press will be available.
However, we’re still doing well and you can get at least eleven or twelve combinations still with only one analog input pin. You can add delay() functions in your sketch if necessary to take care of switch debouncing or do it with hardware if you feel it is necessary.
So now you have a more useful method for receiving input via buttons without wasting many digital input pins. I hope you found this article useful or at least interesting. This series of tutorials has been going for almost two years now, and may soon start to wind down – it’s time to move forward to the next series of tutorials
So if you have any suggestions for further articles (and not thinly-veiled methods of asking me to do your work for you…) – email them to john at tronixstuff dot com.
Have fun and keep checking into tronixstuff.com. Why not follow things on twitter, Google+, subscribe for email updates or RSS using the links on the right-hand column, or join our Google Group – dedicated to the projects and related items on this website. Sign up – it’s free, helpful to each other – and we can all learn something.






Something similar was done years ago with the LEGO NXT – same issue – limited sensor ports but wanted to read multiple touch sensors on 1 port. In the case of this example, each sensor has a different resistor value to allow for all combinations of 3 sensors to be detected.
Anthony Good uses this technique to, um, good effect in his Arduino morse keyer project:
https://radioartisan.wordpress.com/arduino-cw-keyer/
An interesting article again, thank you !
You also should be aware that resistance can vary depending on the ambient temperature. I had to put wider values in my cases statement once I used my circuits outside.
You should switch the lines connected to 5V and A0. This will take care of having overlap as well as your floating input.
Thank you
If your resistor values increase instead of duplicate you will obtain more unique return values.
It is by no means important to have resistors of ABSOLUTELY exact values, it is just fine when they are all of the same value. This is generally the case if you buy them in a package. The R-2R network can be realized by e.g. parallel resistors. Resistor arrays are also fine….Alas, it seems to be quite difficult to get your hands on integrated R-2R chips…