example of using one analog pin to read 5 switches

Thanks for the details-- just when I needed two extra inputs! Quite clever...:slight_smile:

Played around with this for a little while, and while I got consistent values when buttons were pressed, the value varied wildly when none was pressed.

Connecting the analog pin to ground via another resistor solved the problem-- the analog pin reads 0 when no button is down, and only varies by +/- 2 when a button is pressed! I'll use this for the four inputs for my current project, which give me /just/ enough pins not to have to resort to a shift register....:wink:

So, it seems this could be used for more than five buttons, though it would get tricky figuring out the values when multiple buttons are pressed.

In my circuit, these are the readings I get:
No buttons: 0
button 1: 693
button 2: 485
button 3: 326
button 4: 175

Schematic:

/*
*

  • analogPin +5 V
  • | |
  • | \
  • ---------------- /
  • | \ 1K
  • | /
  • | \
  • |____ ____|
  • | SW1 |
  • | \
  • | /
  • | \ 1K
  • | /
  • | \
  • |____ ____|
  • | SW2 |
  • | |
  • | \
  • | /
  • | \ 1K
  • | /
  • | \
  • |____ ____|
  • | SW3 |
  • | |
  • | \
  • | /
  • | \ 1K
  • | /
  • | \
  • |____ ____|
  • | SW4 |
  • | |
  • | \
  • | /
  • | \ 1K
  • | /
  • | \
  • | |
  • |__///__|
  • 4.7K |
  • |
  • |

  • ___ ground
  • _

*/

you shouldn't need that pulldown if you turn on the internal pull up resistor.

Make sure you have this line in your code as I did in the buttonPushed() method. With this, you should read full scale(1023) with no switches pushed.

digitalWrite((14+pinNum), HIGH); // enable the 20k internal pullup

Note: if this pull up resistor has been blown or failed, you'd have to do a pull down or pull up to keep it from floating.

Excellent-- will do! Thanks!!

Thanks for the info. I'm trying to get a rotary input for a project im working on and managed to get hold of a 4 wire (16 position, 0000 to 1111) rotary switch.

Obviously with this I will need to be able to read all 16 states. I have tried playing around with everything but I cannot get it to come out with 16 significantly unique values (there are 2 replications using 1k dividers and 4.7k down), but as I'm using a rotary switch i will only need to check the values to the left and right of the last known value.

Thanks for the help!

if you can't resolve the switch voltages over 16 positions and 5V, then one option might be to use 2 analog inputs instead of one. You'll have to test both pins but atleast there should be enough range between each switch position to get positive readings.

The problem with the switch i was using is that it has a single common pole for all four switches (in one package). Of cause I overlooked the obvious, in that I only really needed to use the two least significant bits of the input to do what I was trying to do (it's a rotary switch that loops over from 1111 to 0000, so I can get everything I need from 0000 to 0011).

You need a different type of D/A converter than the one in the diagram above.
You can use a resistor off each switch output with the values R 2R 4R & 8R where R can be anything (say 1K). You can't actually get these exact values so you will have to make some of them up with two resistors. For example 4K can be two 2Ks in series and 8 K could be a 4K7 and a 3K3 all using 1% resistors.
Connect the common of the switch up to 5V and have a 1K pull down resistor.

I understand how this works BUT if 2 or more switches were pressed then the software would not operate correctly.

Microchip had a Design guide on this subject. If the resistor values are different then it is possible to detect the combination of keys pressed.

I have just arrived at the point in time when I need to do this (run out of digital I/P and can't afford a Mega) so I will try to get this working.

Matt ;D

So simple yet so useful, I love it!
I will definetly be using this for my next project that involves buttons. No need for multiplexing or any shift registers and stuff like that.

EDIT:
One noob question:
What resistor values should i use for 9 buttons?

Nicely presented, cheers - it helped me to see how you had done what I wanted to do.

I just built a 14 step ladder using 1k resistors connected to a stylophone-like keyboard. Decoding the input is dead easy and with 13 'keys' (one octave) there's still plenty of margin.

Decoding the input is dead easy and with 13 'keys' (one octave) there's still plenty of margin.

Remember that you will only be able to detect if one button is pressed with a ladder set up. If two or more are pressed then the results will be ambiguous.

That's certainly true, multiple presses won't work with same-valued resistors. This is not a problem with a stylophone where you can only 'press' one key at a time.

The solution should otherwise be to use power-of-two values, right, such as:
500R, 1k, 2k, 4k, 8k...
so that they can be added up in any combination -
is that right, and does it work? I guess with a bit of breadboarding I could find out...

is that right, and does it work?

Yes that will work but you can't do as many bits. There is only a 10 bit A/D on the arduino so you might think you could do it for 10 switches, but resistor tolerances and noise will limit you to about five or six switches only.

This is really great, simple but very useful, I can use this for a digital joystick switch.
To read the value, can we then use arduino "map(analogRead(pinNum), 0, 1023, 0, 4)" function, instead of testing the range value one by one?
Tks.

If you'd like to learn more about this technique, Google the Microchip AN234 application note.

slight mod to a more conforming traditional r/2r ladder:

Question: How can you mod this to use transistor switches for input?

I have Hall effect sensors that need to be amplified and inverted before they can be added to the ladder... but the transistors always play with the analog voltage measured.

/*
 *                                                 _
 *     +5 V                                       ___
 *      |                                        _____  ground
 *      |                                          \
 *      ----------------                           /
 *                     |                           \    330
 *                     |                           /
 *                     |                           \
 *                     |____ \____/\/\/\ 330 /\/\/\|
 *                     |   SW1                     |
 *                     |                           \
 *                     |                           /  
 *                     |                           \    150
 *                     |                           /
 *                     |                           \
 *                     |____ \____/\/\/\ 330 /\/\/\|
 *                     |   SW2                     |
 *                     |                           \
 *                     |                           /  
 *                     |                           \    150
 *                     |                           /
 *                     |                           \
 *                     |____ \____/\/\/\ 330 /\/\/\|
 *                     |   SW3                     |
 *                     |                           \
 *                     |                           /  
 *                     |                           \    150
 *                     |                           /
 *                     |                           \
 *                     |____ \____/\/\/\ 330 /\/\/\|
 *                     |   SW4                     |
 *                     |                           \
 *                     |                           /  
 *                     |                           \    150
 *                     |                           /
 *                     |                           \
 *                     |                           |
 *                     |____ \____/\/\/\ 330 /\/\/\|
 *                     |   SW5                     |
 *                     |                           \
 *                     |                           /  
 *                     |                           \    150
 *                     |                           /
 *                     |                           \
 *                     |                           |
 *                     |____ \____/\/\/\ 330 /\/\/\|
 *                     |   SW6                     |
 *                     |                           \
 *                     |                           /  
 *                     |                           \    150
 *                     |                           /
 *                     |                           \
 *                     |                           |
 *                     |____ \____/\/\/\ 330 /\/\/\|
 *                         SW7                     |
 *                                                 \
 *                                                 /  
 *                                                 \    150
 *                                                 /
 *                                                 \
 *                                                 |
 *                          |-----/\/\/\ 330 /\/\/\|
 *                        _____                    | 
 *                         ___   ground            | analog pin or LM358
 *                          _
 */

Ok simple mod to get transistors to work as the switch without a resistive influence... Stick a 2n2222 in the middle of the switch apply the external source (5v) to the Base and attach the emitter to the R2R ladder and then supply an additional 5v source to all Collectors.

I now have a 7 input DAC that accepts discrete multiple inputs. Any ideas on the math function to use to decode. I know the basic formula would be (r1 * r2 * r3...)/(r1 + r2 + r3...) = multi input value

But what can be the most effective method of taking an analog input and decoding back to the closest digital inputs given? Binary operation?

Any help would be great.
Thanks.

  • _
  • +5 V ___
  • | _____ ground
  • | \
  • ---------------- /
  • | \ 330
  • +5 V /C /
  • input ---B| \
  • \E---------///\ 330 ///|
  • | SW1 |
  • | \
  • | /
  • | \ 150
  • +5 V /C /
  • input ---B| \
  • \E---------///\ 330 ///|
  • | SW2 |
  • | \
  • | /
  • | \ 150
  • +5 V /C /
  • input ---B| \
  • \E---------///\ 330 ///|
  • | SW3 |
  • | \
  • | /
  • | \ 150
  • +5 V /C /
  • input ---B| \
  • \E---------///\ 330 ///|
  • | SW4 |
  • | \
  • | /
  • | \ 150
  • +5 V /C /
  • input ---B| \
  • \E---------///\ 330 ///|
  • | SW5 |
  • | \
  • | /
  • | \ 150
  • +5 V /C /
  • input ---B| \
  • \E---------///\ 330 ///|
  • | SW6 |
  • | \
  • | /
  • | \ 150
  • +5 V /C /
  • input ---B| \
  • \E---------///\ 330 ///|
  • SW7 |
  • \
  • /
  • \ 150
  • /
  • \
  • |
  • |-----///\ 330 ///|
  • _____ |
  • ___ ground | analog pin or LM358 OpAmp Follower
  • _

Just barging in as i'm playing with a robot that has 6 buttons as bumper. The way they implemented those results in;

button analog reading
pressed value
1 1
2 2
3 4
4 8
5 16
6 32

This way even multiple buttons pressed isn't a problem anymore.
( example; buttons 1 and 2 pressed gives an analog reading of 3.)

Schematic; http://www.arexx.com/downloads/asuro/asuro_manual_en.pdf page 74. Asuro Diagram.

Lower resolution picture of schematic. http://img29.mediafire.com/c5dcf2f463c2d7755f5a330f17a8fb8a5g.jpg

Hope this helps a little. Otherwise just ignore.

Jeroen