[sdiy] Reading two buttons with a single IO pin

jays at aracnet.com jays at aracnet.com
Fri Feb 20 23:04:00 CET 2015


Using an ADC pin I think you can do it with 2 resistors and 2 switches.

Put a pull up resistor on the input pin.

Put a switch between the input pin and ground.

Add a resistor to ground and take the other end and put a switch between 
it and the input pin.

With both switches open the pin is at what you have the pull up tied 
too.

With the switch connected to the top end of the other resistor a you get 
a voltage divider set by the value of the resistors.

With the switch connected to ground is closed you get ground.

Here's a crude ascii schematic, hopefully it will make sense.

Jay S.

+V - Don't go over cpu ADC voltage!
|
|
/
/ R pull up
/
|
---+----- \----+
|           |
|           V
|
+-----\-----+
|
/
/
/
|
V

On 2015-02-20 13:16, Tom Wiltshire wrote:
> Hi All,
> 
> I've been considering the question of how to read two buttons with a
> single microcontroller IO pin. There are various ways to do this. One
> I've seen is to charge a capacitor via some resistors with switches
> around them. You then measure how fast the capacitor charges and you
> can work out which buttons are pressed. There are other techniques.
> Another way is to read an ADC value from some kind of potential
> divider, and by checking where the voltage falls, determine which
> switches are pressed. All the versions of this I saw used a *lot* of
> conditional statements ( if ((x>y) && (x<z)) { do summut } type of
> thing ).
> It seemed to me it should be possible to arrange the incoming voltages
> so that the bits of the ADC reflected the switch states directly.
> 
> E.g. Do it a simpler way: Just read an ADC value, reduce the ADC value
> to the top two bits (00, 01, 10, 11) and arrange the resistor values
> such that the bits reflected the switch states. This was what I had in
> mind:
> 
> http://www.electricdruid.net/images/TwoButtonsV2.png
> 
> Having messed about with calculations and experiments for a while, I
> determined that this arrangement isn't possible. The 00 case is easy,
> since both switches are open and R3 acts as a pulldown, so we get 0V
> and read 00. The R1 and R2 values that give good stable ADC readings
> for the 01 and 10 cases are easy enough to determine, but
> unfortunately, they don't give the right value when used in parallel.
> Since the "ideal" value would be in the middle of the range, I did
> some experiments to see if I could make it work by pushing the R and
> R2 values closer to the limits, further from the ideal values. It
> turns out you can't.
> 
> Finally, I had a brainwave. What if I inverted the state of one of the
> switch bits? Let's say I invert S2, so that instead of reading 1 for
> pressed, it reads 1 for not-pressed. In this case, my required ADC
> sequence would be 10, 11, 00, 01. Given that for code it doesn't much
> matter whether a switch reads 1 pressed or 1 unpressed, this isn't a
> big deal. It turns out that this *is* possible to arrange:
> 
> http://www.electricdruid.net/images/TwoButtonsV3.png
> 
> I produced this with a PHP script, so I can enter a R4 value, and the
> code derives the other necessary values, finds the nearest actual
> resistor values, and checks what potential divider ratios they give to
> make sure they're in range. The given values are therefore a
> demonstration, and could be adjusted to taste.
> 
> I was quite pleased with this, since it'll allow me to double the
> number of switches for only a couple of resistors per switch.
> 
> Presumably I'm not the first person in seven billion to have come up
> with this idea, but I thought I'd share it, since I haven't been able
> to find it somewhere else.
> 
> HTH,
> Tom
> 
> 
> 
> 
> _______________________________________________
> Synth-diy mailing list
> Synth-diy at dropmix.xs4all.nl
> http://dropmix.xs4all.nl/mailman/listinfo/synth-diy



More information about the Synth-diy mailing list