Hi, not sure if this is the right section for this. Sorry if it's not, I had a hard time selecting what section would be most appropriate.
Firstly, this is a thought project. I've not built it, probably never will, it's just something that intrigued me so I went ahead and tried to solve it. The objective is to construct a 12 digit keypad (0-9, * and #) keeping the interfacing and component count as minimal as possible. Problem here is if you reduce the amount of data lines you generally increase the amount of components and vice versa. A simple matrix with no components uses a lot of data lines, if you reduce the data lines you start needing logic gates, go down to 1 or 2 data lines and you're in the realm of dedicated micro controllers for I²C etc...
I thought, could each switch be used to complete a voltage divider circuit using a resistor for each row and column? That way the whole pad could be read with a single ADC input and it would only need 8 resistors. Although pressing of multiple buttons would mess it up, but I can live with that issue. The problem here was which 8 resistors? I quickly realized the selection of the resistors was not a trifling matter. So, I wrote a bit of a number cruncher selecting each resistor at random (not duplicating the same resistor on different rows/columns although the same value resistor was allows to be in a row and in a column), using standard value resistors from 1K to 820k. I've had the program crunching for hours and the best it's come up with is this.
This gives me a minimum difference between the closest 2 switches of 0.211V which I guess is feasible, correlates to a difference of about 44 on the ADC reading. That's a tad too close for comfort though. Can anyone do better than this? Or suggest some method of calculating what resistors to use other than random crunching?
In the project I'm just finishing I'm using an Atmega8 with 7 buttons on one analog pin. Pin is pulled up internally. Each button has its own resistor. They are:
2K2, 5K6, 12K, 22K, 33K, 47K and 68K
Analogue values I'm getting are:
75, 150, 260, 400, 500, 580 and 660
Debounce is done in software and I have not seen any problems such as wrong button being recognized.
How do you debounce? Are you making sure the ADC reading is constant (say within 20) for a period of time (say 5ms)?
I could put a resistor for each switch like you have, but that increases the resistor count to 13 (12 if I use internal pull-up but the internal pullup is not at all accurate).
AvidVestRepair:
Thanks Paul but that's more data lines and more components. The idea is to reduce it not increase it.
....but does not use the potentially limited resource of analog inputs, all components are identical, no critical tolerance components required, much more tolerant to noise... and, yes, this is your "thought experiement" and I will now shut up.
I'm checking if the button is pressed (<800), wait a bit, then check again and compare with intervals to determine which button is pressed. The interval for each button is eyeballed to extend roughly halfway to the next button value. I don't care if the value is dead constant, as long as it is not fluctuating too far from the sweetspot into the neighboring button's area, but like I said, so far it appears to be good enough and I haven't seen any wrong button recognition.
Yes, this method needs more resistors than with your array idea, but consider the complexity of your PCB, too.
I'm using 0806 resistors. They take up almost no space and are cheap. You method requires either a two layer PCB with vias (not particularly fun doing in a DIY fashion) or quite a few jumpers.
That's awesome HazardsMind and it uses even fewer resistors. Thanks, nice one. Can't believe I didn't come across your library because I did a bit of searching on the subject. Brilliant stuff.
There isn't much separation between the low end values though, on the order of 0.02V shaving it pretty close.
@Shpaget, yes you are right. I can trace it all out on a single layer using a single resistor for each button. Plus I can get much better separation on the voltages. I think yours is the best suggestion. 12 (or 13 with no internal pullup) resistors and 1 data line. Resistors are also far cheaper than diodes
OK HazardsMind I'll have a play with it, I have built your circuit ina simulator so I can tinker with it. The same value resistors is also an important factor because for production you try to keep to using the same parts where possible to cut down the number of passes through the pick and placer. All of these factors count to me scoring points