Using this method, I'll show you how you can access 5 (or even more) inputs through 1 Arduino pin. These buttons will only be read correctly if only one is pushed at any time though.

As we go through it I'll explain whatever background info you need to know, so as long as you can blink a button, read a switch and read an analog input, you'll be fine. If you can't do any of these, I'll point you in the right direction in the relevant steps as well.

Step 1: Parts List

This is pretty simple:

1 x Arduino (Obviously)
1 x 100K Resistor (Brown Black Yellow)
1 x 1K Resistor (Brown Black Red)
1 x 10K Resistor (Brown Black Orange)
1 x 33K Resistor (Orange Orange Orange)
1 x 68K Resistor (Blue Gray Orange)
4 x Push button switches
Some wires to connect it all

You can use any push buttons you might have lying around, and the resistor values are not critical. More on this later.


<p>I want to thank you for such a well documented instructable!</p><p>It was very easy to read and understand, if only more people would put the time and effort like you have. </p><p>I look forward to reading more of your instructables.</p>
<p>This is amazing. Thank you so much! You've just saved me a lot of time and headaches :)</p>
<p>Calculate the resistor:</p><p>it&lt;= 40mA </p><p>vt= 5v</p><p>.</p><p>It = (i1+i2+i3+i4+i5+i6+...+in) &lt;= 40mA</p><p>.</p><p>i1 &gt;= (i2+...+in) </p><p>i1 &gt;= it/2; </p><p>i1 &gt;= 20mA R1= 5v/20mA = 0,25*10^3 = 250; </p><p>.</p><p>i2 &gt;= (i3+...+in)</p><p>i2 &gt;= i1/2</p><p>i2 &gt;= 10mA R2= 5v/10mA = 0,5.10^3 = 500; (R1*2)</p><p>.</p><p>i3 &gt;= (i4+...+in)</p><p>i3 &gt;= i2/2</p><p>i3 &gt;= 5mA R3 = 5v/5mA = 1*10^3 = 1k; (R2*2) =&gt; (R1*4)</p><p>. </p><p>i4 &gt;= (i5+...+in)</p><p>i4 &gt;= i3/2</p><p>i4 &gt;= 2,5mA R4 = 5v/2,5mA = 2*10^3 = 2k; (R3*2) =&gt; (R1*8)</p><p>.</p><p>i5 &gt;= (i4+...+in)</p><p>i5 &gt;= i4/2</p><p>i5 &gt;= 1,25mA R5 = 5v/1,25mA = 4*10^3 = 4k; (R4*2) =&gt;(R1*16) </p>
<p>Thanks for the info.</p><p>Had some trouble with the normal buttons. This saves me some digital I/0 and it works great. Making an stable Alarm. Some sick basterds are trying to hurt the horses for fun. I&aacute;m using the switch through the analog port and make it call the owner with a SMS.Works great because it always measures the analog port.</p><p>Great help, thanks!</p>
<p>One thing I think needs to be mentioned is that this article is using a Pull-Down resistor instead of a Pull-Up resistor. When nothing is pressed the pin is in a low state (0v), this can all be reversed by simply switching where the resistors are on the polarity.</p>
<p>works perfectly for my little robot - thanks! I used it for two buttons with resistors 10k and 1k - and two times 10k at the end. I get the values 0 for off, 18 for first 155 for only second and around 168 for both.</p>
<p>Hi<br>Can anybody help me.<br>I want 8 buttons an i want to be able to make multiply button push.<br>but i dont know how to caltulate it.<br><br>I am going for the parelell solution like used in this tuturial.</p>
I don't think this would work so well in industry, due to the fact that resistor values can change over long periods of time, but this is an excellent and cheap technique for personal projects. Thanks for sharing how you simplified the process. I know math can be really tedious for some, and your process cuts all that out. Good instructable!<br />
<p>This is certainly the method used in a lot of domestic and office equipment - printer controls, DVD, TV etc. where the cost is shaved by less-than-pennies where possible.</p>
Thanks :)&nbsp;<br /> <br /> I&nbsp;guess you could deal with that in code. If you had button 1 tied to the supply voltage with no resistor, you know its value would be constant. So use button one to start a calibration process where you press each button in turn and the software records the new values for each button. <br /> <br /> Of course then you need some form of memory to store the new values and it all starts getting more complicated again. Still, you could make it work if you were desperate enough :)<br /> <br /> Of course, for a commercial venture, I&nbsp;would just use a micro-controller with more IO&nbsp;lines.<br />
<p>By connecting the analog input to the centre of a series chain of equal value resistors, and by shorting varying numbers resistors upward and downward, it is <strong><em>theoretically</em></strong> possible to multiplex 1023 buttons on an Arduino.<br><br>In practice, a dozen or so could be managed even with 5% resistors.<br></p>
<p>What about taking averages when the button is pressed?</p><p>for(int i=0;i&lt;150;i++)</p><p> {</p><p> sample+=analogRead(A1); //read the value</p><p> delay(2);</p><p> }</p><p>sample=sample/150;</p>
I have a project that I am working on where I am monitoring about 25 magnetic contact switches. Your wiring and code represents almost exactly what I am trying to do. I am trying to figure out though, what the upper limit is of switches that can be monitored on one input channel. Basically I have other functions that will require as many open inputs and outputs as possible. I'm thinking maybe I can double up and maybe even triple the resistors at a certain point so that I can get the differentiation in voltage values. Any help is appreciated, thanks!
<p>Thanks for posting this. It was a help, as I was thinking down the same lines. I've had this arduino sitting on my desk for a few weeks, but had not done anything with it until tonight. I made the LED blink some, but needed to actually have a physical interface into it. </p><p>I ended up going a different way, and used the same value resistor for all 3, I went with a 4-button config, so each button would flow through a different number of resistors, from 0 to 3. Instead of using a breadboard, I used a perfboard and soldered it up. Here's some photos I took of the diagram, and the finished component.</p><p>Red is V+</p><p>Black is GND</p><p>Green is Signal (A0)</p>
<p>Oh, I forgot to mention, I'm using ~5.7K resistors. The output values are all +/- 2</p><p>SW1 (closest to the wiring harness) = 1023</p><p>SW2 = 969</p><p>SW3 = 919</p><p>SW4 = 873</p><p>Now the next trick, is I need to make another one that all the sensors will plug into, and my whole project will need 1 pin for controls, 1 pin for jam sensors, and I have pins left over for alert lights and an LCD.</p><p>Thanks again!</p>
<p>In high school, before the Sound Blaster came out, I built an 8-bit Digital to Analog converter using such a circuit to listen to 8bit music (Amiga .MOD files) through my stereo. This is called a &quot;resistor ladder&quot;, though the circuit I followed had one resistor per line PLUS a resistor in-between making it an &quot;R-2R&quot; ladder.</p><p>An R-2R ladder would allow for semi-unique analog read values for up to 5 inputs with relatively easy to get high-accuracy resistors (1%), meaning that each combination of pressed switches would have a unique value, for 31 possible input readings (and &quot;none&quot; for 32). More buttons would require higher accuracy (higher cost) resistors (at which point the cost could be higher than just getting another Atmel 328 and using it for a standard matrix key reader and sending results via serial connection).</p><p>Another thought is that if you do have an additional resistor for each switch, you'll know the lowest &quot;valid&quot; value, and multiple presses would dip lower than that allowing for detection of this &quot;error&quot; condition if all you want are single key presses.</p><p>Thanks for posting! My idle daydreams of using a single analog pin for a full keyboard are now fully researched and laid to rest. :-)</p>
<p>Sorry if I'm filling up the thread with after-thoughts. </p><p>If you know the tolerance of your output (in my case +/-2) you can also divide your output by a slightly larger number, which allows you to treat your button output as an over-sample. This prevents having to use a more complex double if statement that covers your tolerance, and allows you to use a case statement.</p><p>I also took 32 reads and averaged them together and then divided by 10, which flattened the dataset. Here's my code:</p><p>//Definitions<br>int ledPin = 9;<br>int ButtonPin = 0;<br>int count = 0;<br>int average = 0;<br><br><br>void setup() {<br> // put your setup code here, to run once:<br> Serial.begin(9600);<br> Serial.print(F(&quot;Welcome to Setup... Setting Pin IO\n&quot;));<br> pinMode(ledPin, OUTPUT);<br> pinMode(ButtonPin, INPUT);<br> //pinMode(TestPin, OUTPUT);<br>}<br><br>void loop() {<br> //Serial.print(F(&quot;Running code loop, setting LEDpin low\n&quot;));<br> //digitalWrite(ledPin, LOW);<br> int volt = analogRead(ButtonPin);<br> count++;<br> average = (average + volt)/2;<br><br> if (count == 32) <br> { <br> Serial.println(average/32); <br> int lightval = (average - 800)/2;<br> if (lightval &lt; 0) { lightval = 0; }<br> analogWrite(ledPin,lightval);<br> count = 0; <br> average = 0; <br> }<br>}</p>
<p>I used my setup with an ATTiny85 and it is very forgivable with ranges. From there you can take advantage of the hardware saving and extend that software-wise with a bit of higher-level logic (saves space + aesthetics.) I'm a beginner but after noticing the keypad formation on my Velleman DIY Oscilloscope I gave it another try and VOILA it worked! Like the previous poster said, you notice corporations taking advantage of such circuitry-logic.</p>
<p>That's a cool little chip, I'll have to read up on it a bit more. There's a more complicated project I'm working on at the moment that requires quite a bit of data processing (it's a data-acquisition device from a load cell) This might be a good processor for the task.</p>
<p>Had great success wiring 6 buttons to an analog pin. Four buttons are great to serve as directional buttons and the other two for options. Resistors I'm using are 2.4k, 10k, 5k, 1k, 560, and 220. The 2.4k is not connected to any button but ends the circuit to ground. The first button closest to the 2.4k therefore has no resistor. I have attached a photo of my setup.</p>
&nbsp;If you kept the resistor values increase by the power of two you could do binary addition and subtraction to get what buttons are pressed. &nbsp;This is done in computer programing all the time
I&nbsp;thought so too, and initially chose my resistor values that way, but the fact that the resistors are in parallel means that the binary doesn't hold when you connect multiples. For example, if I&nbsp;had 10K, 20K, 40K and 80K&nbsp;resistors on buttons 1, 2, 3 and 4 (To make the maths simpler), I&nbsp;get the following resistances when pressing multiple buttons:<br /> 1+2: 6.66K<br /> 1+3: 8K<br /> 1+4: 8.88K<br /> 1+2+3:&nbsp;5.7K<br /> <br /> As you can see, the multiple button presses result in resistances that are all very close together (and close to the button 1 resistance). <br /> <br /> I'm wondering if there wouldn't be some way of rewiring the circuit to get the resistors in series when multiple buttons are pressed... Off the top of my head, I&nbsp;don't see an easy way, but it is after midnight here.<br />
Your buttons are double-throw switches, right? You should be able to put them in series just fine. All you have to do is short the &quot;off&quot; contact of one switch to the common of the next one, so that there's no resistance when it's not being pressed. Not sure how best to debounce it, though. Anyway, sorry for replying to such an old comment. I have a similar project where this could be verrry useful, though...
It looks something like this...maybe the resistor values have to be tweaked to make it easier to distinguish the voltage readings, but you get the idea.
<p>Very clever! I gave this approach a go, but in my case, the error in the larger resistors swamped the ability to read the smaller ones.</p><p>Further googling turned up the R/2R DAC, which has a similar idea, but is much more robust in terms of accuracy and ease of converting the Analog values on the Arduino to reliable resistor readings. The best description I saw was here: http://www.tek.com/blog/tutorial-digital-analog-conversion-%E2%80%93-r-2r-dac. It works so well, it almost seems magic.</p>
now if you calculated everything with conductances (conductance=1/resistance) they add in parallel.&nbsp; That would help to do some simple addition calculations.
It would make the maths simpler, but I don't see how that helps practically?&nbsp;<br /> <br /> I&nbsp;have to admit, I&nbsp;haven't worked with any electronics for a while, so maybe I'm missing something obvious, but I&nbsp;don't see an easy way to convert conductance into a voltage that the Arduino would be able to measure.<br />
<p>Many thanks. I've recently brought a tiny 'joystick' </p><p><a href="https://www.sparkfun.com/products/10063" rel="nofollow">https://www.sparkfun.com/products/10063</a></p><p>And I can now use 6 SMD resistors to create and very tiny control package.</p>
<p>isn't possible to put a 2.2k resistor between GND and each button and 220Ohm resistors in series going to 5v?</p><p>i've tried it and the values where all in a range of 10 to the next button AND if i press two buttons the value is of the button before and not between two values </p><p>if am i wrong please tell me I'm not an engineer and i can make mistakes...</p>
<p>With 2^N-1 identical resistors in a tree, shouldn't you be able to distinguish multiple switch presses for up to N switches? Just parallel them up for X Ohms (1 resistor), X/2 Ohms (2 resistors), X/4 Ohms (4 Resistors) etc. So if you press the switch for 1 resistor at the same time as the switch for 4 resistors, you get the resistance of 5 resistors in parallel (X+X/4 Ohms)and you cannot get that value from any other combination...</p>
<p>This is what I'm thinking of...</p>
Thanks for posting this. I had the same idea of using resistors in series before getting here and was glad to see your diagram. I'm wiring an old-school (think industrial arcade game) joystick. In its guts, when you push the lever one way, it causes physical closure of a switch (push up joins two metal contacts on the right; push down and it closes contacts on the left). So really it's just four switches, and physically it's capable of having one or two switches closed at once, but no more. <br> <br>I'm currently supplying the Arduino's 5V to it, and taking meter readings (disconnected from Arduino) and actual analogRead values (connected to Arduino) to correlate and get an idea of what I'll see. So far it looks logarithmic, suggesting a good spread of resistor values would be 1k, 10k, 37k, and 100k. <br> <br>At the same time, I have to look up the combined parallel resistances to see what kind of spread they give... Rtotal = (R1*R2)/(R1+R2). <br> <br>The logarithmic scale, if borne out, suggests higher resistances will give me less variance in analogRead values. Example: choosing R1=220 ohms, and R2=470 ohms, my parallel resistance is 149.86 ohms. But, at that point in the log scale, I expect my analogRead values to be around 220ohms=1002, 470ohms=978, 150ohms=1009. So that split between 1002 and 1009 isn't comfortable enough to account for resistor quality differences. <br> <br>Instead, if I choose larger values, I hope to get a wider spread of analogRead values to work with.
The all time best use of this trick is on RC controllers (Car, plane, boat). They take one channel and on the TX side, they disconnect it from the stick (which is a potentiometer). They then add 5 or 6 buttons with varying resistors like you did. On the RX side, they plug it into a micro controller that can read PWM (i've done it with a Basic Stamp 2, but an Arduino would work). Now they have taken that 1 channel on the transmitter, and made it into a bunch of buttons that can control anything you want with an arduino. <br> <br>Sometimes its nice to have the responsiveness of direct PWM on some channels, and 1 or 2 channels of other &quot;actions&quot; at the receiver.
Hi, <br> <br>I was just trying to implement your instructable in my project. I connenced the buttons according to your sketch. I used 22K, 33K and 47K resistors and 100K as a pull down resistor. <br> <br>Now the buttons are working and like whn I press them, I can see the values change in the serial monitor. However, when it comes to calculating the range, the value doesnt fluctuate. Its the same value repeating. Like for button 1, the range is 1023. for button 2 the range is, 838-839, for button 3 it is, 658-659 and for button 4 it is, 503-504. <br> <br>So, I am confused now. Like should I put down these ranges in my sketch or what? <br> <br>Can you please help me out :/
Thanks a lot for this, helped me a great deal.
Wouldnt it be possible to do something like this with a shift register or similar and eliminate the possible conflicts of the resistor values? (not to mention give you more buttons i think)
Nice tutorial and good method! I'm a bit new to resistance and the like, i need to run eight buttons, does anyone have any idea what resistors to use and what the output values would be. Cheers!
Yes, please post the rest of your project plans! Multiplexing LEDS isn't that easy and you demonstrated teaching skills with this project :-).<br /> <br /> Thanx a lot,<br /> <br /> Alex<br />
Thanks Alex. I'm working on the charlieplexed LED's now. Bit of a headache so far... Finally have it wired up properly, now I&nbsp;just need to figure out the code...<br />
pretty clever that :)<br />
Thanks. You know what they say about necessity :)<br />

About This Instructable




More by riaancornelius:Controlling 20 Led's from 5 Arduino pins using Charlieplexing Accessing 5 buttons through 1 Arduino pin - Revisited How to access 5 buttons through 1 Arduino input 
Add instructable to: