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.

Have fun and keep checking into tronixstuff.com. Why not follow things on twitterGoogle+, 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.

Use multiple buttons with one analog input in chapter twenty-five of a series originally titled “Getting Started/Moving Forward with Arduino!” by John Boxall – A tutorial on the Arduino universe.

[Updated 14/03/2013]

To recap, an analog input pin is connected to an analog to digital (ADC) converter in our Arduino’s microcontroller. It has a ten bit resolution, and can return a numerical value between 0 and 1023 which relates to an analog voltage being read of between 0 and 5 volts DC. With the following sketch:

and in the following short video, we have demonstrated the possible values returned by measuring the voltage from the centre pin of a 10k ohm potentiometer, which is connected between 5V and GND:

As the potentiometer’s resistance decreases, the value returned by analogRead() increases. Therefore at certain resistance values, analogRead() will return certain numerical values. So, if we created a circuit with (for example) five buttons that allowed various voltages to be read by an analog pin, each voltage read would cause analogRead() to return a particular value. And thus we can read the status of a number of buttons using one analog pin. The following circuit is an example of using five buttons on one analog input, using the sketch from example 25.1:

And here it is in action:

Where is the current coming from? Using pinMode(A5, INPUT_PULLUP); turns on the internal pull-up resistor in the microcontroller, which gives us ~4.8V to use. Some of you may have notice that when the right-most button is pressed, there is a direct short between A5 and GND. When that button is depressed, the current flow is less than one milliamp due to the pull-up resistor protecting us from a short circuit. Also note that you don’t have to use A5, any analog pin is fine.

As shown in the previous video clip, the values returned by analogRead() were:

• 1023 for nothing pressed (default state)
• 454 for button one
• 382 for button two
• 291 for button three
• 168 for button four
• 0 for button five

So for our sketches to react to the various button presses, they need to make decisions based on the value returned by analogRead(). Keeping all the resistors at the same value gives us a pretty fair spread between values, however the values can change slightly due to the tolerance of resistors and parasitic resistance in the circuit.

So after making a prototype circuit, you should determine the values for each button, and then have your sketch look at a range of values when reading the analog pin. Doing so becomes more important if you are producing more than one of your project, as resistors of the same value from the same batch can still vary slightly. Using the circuit from example 25.2, we will use a function to read the buttons and return the button number for the sketch to act upon:

And now our video demonstration:

So now you have a useful method for receiving input via buttons without wasting many digital input pins. I hope you found this article useful or at least interesting.

Have fun and keep checking into tronixstuff.com. Why not follow things on twitterGoogle+, 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.

### Australian Electronics!

Buy and support Silicon Chip - Australia's only Electronics Magazine.