If you run out of pins in your microcontroller, like 8 pin types, but you’re desperately in need for a way to allow the user to interact with your device, you can use an analog input instead of three to four digital inputs. The catch is you really need to watch possible tolerances and make sure that the codes you read from the ADC do still have enough distance to distingiush between them.
I prepared a spreadsheed (ADC button decoding) to get a feeling what kind of resistor tolerances are required (using 10 Bit ADC with 4 digit distance between to states):
- four buttons: ≦ 0.7%
- three buttons: ≦ 2.4%
- two buttons: ≦ 8,3%
Unless you want to piss away your money using 0.5% resistors trying to save controller pins, the only combinations making sense are 5% resistors for 2 Buttons or 1% for three buttons here. Of course this is only true if you want to be able to decode multiple buttonpresses at once. If this is not required one can easily connect 10 buttons per pin – you’ll have to take care of collisions that may and will happen. Multiple buttons held down at once could even be recognized as one and trigger unexpected actions.
Update: More thinking brought me to the conclusion that four buttons are possible with <1.2% resistors as well if some conditions are met:
- Use a lower reference voltage than voltage divider supply as possibility to „amplify“ readout values. Or use internal PGA where possible in single ended mode.
- Reduce the pulldown resistor to fit more the linear area of voltage steps into new measurement reference to increase distance between states greatly.
- Know your voltages or their relation well.
- Make sure both voltages in use drift accordingly. This is what most cost sensitive designs will fail to achieve (the reference would have to be generated from supply or the other way around). To compensate this shortcoming a bit, broaden the expected resistor tolerances and reduce the minimum distance value.
The spreadsheed (ADC button decoding, different Vref) has been adjusted and also „saturates“ if the ADC would be measuring out the reference voltage bounds.
Update: Added minimum level width as lower analog levels, using high value resistors, suffer from distortions like leakage currents and ADC input currents (without capacitor) (ADC button decoding, different Vref, min. width). It improves immunity without – at least to the extend of my testing – introducing errors.