[sdiy] Reading two buttons with a single IO pin

John Speth jspeth at avnera.com
Sat Feb 21 00:33:17 CET 2015


In extremely cost sensitive apps, the cost of a resistor is frequently
less than the cost of a microcontroller pin.

Word to the wise: Make a very in depth study of tolerance to voltage
divider ref voltage variations and resistor variations.  Then add a fudge
factor for unforeseen variations.

JJS

> -----Original Message-----
> From: synth-diy-bounces at dropmix.xs4all.nl [mailto:synth-diy-
> bounces at dropmix.xs4all.nl] On Behalf Of Jack Jackson
> Sent: Friday, February 20, 2015 3:05 PM
> To: jays at aracnet.com; Sdiy
> Subject: Re: [sdiy] Reading two buttons with a single IO pin
>
> Is there a particular reason you want to use only one pin Tom? Why not
mux in
> using a shift register?
>
> Best Regards,
> Jack
>
> ----------------------------------------
> > Date: Fri, 20 Feb 2015 14:04:00 -0800
> > From: jays at aracnet.com
> > To: synth-diy at dropmix.xs4all.nl
> > Subject: Re: [sdiy] Reading two buttons with a single IO pin
> >
> > 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
> > _______________________________________________
> > Synth-diy mailing list
> > Synth-diy at dropmix.xs4all.nl
> > http://dropmix.xs4all.nl/mailman/listinfo/synth-diy
>
> _______________________________________________
> 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