# What resistors to use to read several buttons with a single analog pin

EDIT: Thanks, all of you helped a lot! Ricardo summed everything up nicely so I'll mark his answer as the best, but all of the answers helped me understand. Thanks again :).

I have an Arduino Uno R3 and I want to connect a circuit that will allow me to read several buttons using a single analog input pin. Basically I want the circuit to mimic a discrete potentiometer, but I want to use buttons instead of a knob. How can I do that? And how do I know which resistors to use in my circuit?

Here's a picture of the circuit I have in mind: What values should I give the resistors? And why?

How can I connect such a circuit so my arduino won't fry?

• If that's the entire circuit, then the arduino will always read 5V on the ADC pin. On the plus side, it's safe with any resistor values there. Feb 11 '14 at 15:43
• Oh. So what do I need to do to make it get the values it would get if it were to use the current? Feb 11 '14 at 15:46
• The arduino board has 10bit resolution, is that enough for 15 buttons? and how do I calculate the things you said? Feb 11 '14 at 16:15
• en.wikipedia.org/wiki/Voltage_divider Feb 11 '14 at 16:26

What you are looking for is called a voltage ladder.

Below is some schematics that show an example of a voltage ladder. In this case, the voltage ladder is used to get input from 5 buttons using only one analog input in the Arduino. The buttons are arranged as 4 cursor arrows and a select button as in the picture below: Back to your question, the resistor values are picked so that each one causes a voltage drop on the analog pin that can be distinguished from the other buttons presses. Normally I see cases in which the resistor values go up exponentially (330R, 620R, 1K and 3K3 in this case), but I think you could use similar values (all of them as 330R). Also, R2 is there to avoid a short circuit between 5V and GND when the first button is pressed.

If you had, say, 15 buttons to lay out, you'd have to have 15 resistors, and you'd have to make sure that the voltage drop between adjacent resistors is high enough to be distinguished by the reads on the analog pin. You need to consider that the ATmega328P has a 10 bit ADC (i.e. will give you values between 0 and 1023) but only shows 4 bit accuracy (ie. will show an error of about 10 in each read). So you should look for resistor values that causes a voltage drop that gives you more than 10 in each analogRead() call. This will limit the maximum number of buttons you can read this way.

There are mainly 3 ways to get the resistor values:

1. You can calculate the voltage reading for each button by considering that button as pressed, removing the parts of the voltage latter circuit that are open and applying Ohm's Law. So, pick one button, replace it by a wire and remove all the other buttons. Then you can calculate the voltage for that button.

2. You can also simulate the circuit. Did you notice that you can simulate the circuit kimliv posted? By clicking his schematics you'll be taken to CircuitLabs, which is a website that lets you simulate circuits. There you will be able to change resistor values, press buttons and see the results. You can also use other circuit simulation packages that are available.

3. Building it. Layout the circuit in a breadboard then try different resistor values and measure the voltage drop with Arduino and Serial.println(). You can also use a digital multmeter (DMM) for that.

Note that the voltage ladder only registers one button press at a time. If you press more than one button, only the one closer to the top of the schematics gets selected.

• Why did you choose those specific resistor values? and what if I had 15 buttons? Feb 11 '14 at 16:07
• The resistor values are picked so that each gets a voltage drop that can be distinguished from when other buttons are pressed. Normally I see cases in which the resistor values go up exponentially (330R, 620R, 1K and 3K3 in this case), but I think you could use similar values (all of them as 330R). Feb 11 '14 at 16:21
• If you had 15 of them, you need to make sure that the voltage drop between adjacent resistors is high enough to be distinguished by the reads on the analog pin. You need to consider that the ATmega328P has a 10 bit ADC (i.e. will give you values between 0 and 1023) but only shows 4 bit accuracy (ie. will show an error of about 10 in each read). So you should look for resistor values that voltage drops that gives you more than 10 in each analogRead() call. Feb 11 '14 at 16:25
• Is there a good way to test that? I mean other than buying 100 resistors of diffrent values and trying them out? Feb 11 '14 at 16:27
• You can calculate the voltage reading for each button press by removing the parts of the voltage latter circuit that are open and applying Ohm's Law. So, pick one button, replace it by a wire and remove all the other buttons. Then you will find the voltage for that button. Notice that the voltage ladder only registers one button press at a time. Feb 11 '14 at 16:27

1. Note that one end must go to VCC and the other to ground, and your measurement point must be somewhere in the middle.

Your original circuit has no path to ground in it and therefore no current will flow. The Arduino's input can be considered as an extremely large resistor, not a good path to ground.

2. Minimum sensible values for resistors.

Given that one end of the ladder goes to power and the other to ground, you must ensure that (a) if you press all the buttons it doesn't bypass all the resistors and short out your power supply, and (b) at the minimum resistance of the ladder, the current flowing in the smallest resistor is not going to dissipate too much power in it.

Given a 5V supply and the 2k resistor of kimliv, that would have (by ohm's law) 2.5ma flowing in it, dissipating (by P=VI) 12.5mW of power. Even little tiny surface mount resistors are rated at 63mW, so that will be fine.

Your original 100R resistor would have 50ma current and 250mW dissipated, which will burn out the tiny resistors and make normal-sized ones noticably warm.

3. Maximum sensible values for resistors.

Large resistors are more noisy. You also need to allow a small amount of current to flow into the ADC to take readings. Values over 100k (or trying to do very fast readings )you might need to start considering these effects.

This circuit doesn't depend on specific, absolute values, so arbitrarily picking 1k or 2k as a sensible minimum and choosing the others based on that value works fine.

Try this circuit: simulate this circuit – Schematic created using CircuitLab

Now you get different values for different button combination. I think you are looking for this.

• Ok, but why did you choose those values for the resistors? and what if I had 15 buttons in a similar setup? Feb 11 '14 at 16:03
• imoprtant is, that if you add any value together you don't get an other as result Feb 11 '14 at 16:16
• you need the 2k on top between 5V and GND to prevent a short-circuit. the rest has to follow my upper statement Feb 11 '14 at 16:18
• Is the 2k for sure? how did you decide on 2k? Feb 11 '14 at 16:20
• if you like to detect multiple button inputs at one time use this circuit: i2.wp.com/tronixstuff.com/wp-content/uploads/2012/02/… Feb 11 '14 at 16:59

Besides picking sane resistance values w.r.t current consumption, you actually want different buttons in the ladder to produce even voltage steps on the ADC, which makes the conversion easier and increases noise immunity. Consider the following voltage ladder: simulate this circuit – Schematic created using CircuitLab

Ideally, you would like buttons to produce voltages with 0.25·VCC increments: 0, 0.25, 0.5, 0.75. The fifth voltage level, VCC, will be detected when no buttons are pressed.

You can pick the R0 value freely, and then calculate the remaining values to produce the desired voltage steps. Suppose R0 = 1 kOhm:

• R1 should drop 1/4 VCC, so R1/(R1+R0) = 1/4, R1 = R0/3 = 330 Ohm
• R1+R2 should drop 1/2 VCC, so (R1+R2)/(R0+R1+R2) = 1/2, R2 = 660 Ohm
• R1+R2+R3 should drop 3/4 VCC, so (R1+R2+R3)/(R0+R1+R2+R3) = 3/4, R3 = 2 kOhm

This can be easily generalized to more buttons.