Hi Stewart,
Perhaps I should have summarised my proposal in #33. If you "plug" your keypad A/D value into the following formula (code) it should give a numerical (integer) value from 0 to 11 (or a larger number if no key is pressed) which you can use in
any ON GOxxx ... , LOOKUP ... , IF ... or CASE ... statement in your program :
keynumber = adcvalue + 6 / 12
As primarily a "hardware engineer" I've been considering what could be the "best" hardware arrangement to use with a 4 x 3 keyboard (since I haven't been impressed with any of the designs I've seen so far). I've even tinkered with a few values in a spreadsheet, not a "fully engineered" design, but I've now a fair idea what I'd breadboard if/when I need an analogue keypad:
Firstly, a "constant-current source" should
only be used if there is a regulated (5 volt) power supply rail. With an unregulated supply, the A/D reference could/should use the internal FVR (Fixed Voltage Reference) but that's probably a case of "Out of the Frying Pan into the Fire" for most users. Personally, I try to design my PICaxe hardware to work not only with 3 x fresh alkaline cells, but 3 x NiMH (or not-so-fresh alkalines) and ideally two cells (since many of my projects are to interface with devices which are powered by only 2 AA cells).
So, what resistor values to use across the keyboard columns and rows? Well, Microchip "recommend" that the A/D converter should be driven from a source impedance of less than 10 kohms. That "suggests" that each keyboard resistance step should be just under 1 kohm, let's assume 1 kohm for now; higher impedances can be used, e.g. if a capacitor is added to the A/D pin (not a bad idea anyway). That would make the "row" resistors 3k0, which
is a "preferred" (standard) value, but only from the "E24" series, not very common, so more on that later.
Now what about the pullup resistor? One issue is that the "higher" keypad numbers put a higher resistance load on the pullup, so the current (and thus voltage steps between adjacent keys) are smaller. A design linked earlier in this thread uses 10k (with 10k "row" resistors) which IMHO is far too low. At the other extreme, the text in the linked spreadsheet suggests 1 Mohms (rather high), so perhaps my "wet finger in the air" 100k value earlier wasn't too far out!
However, another factor helps to make a decision: Normally, it's necessary to repeatedly read the A/D conveter to see if a key has been pressed (or additional hardware could be added). But if we make the ratio of the pullup to keyboard resistors large enough then it can be used as a digital input. Thus it can be read directly in an
IF pin... statement, or even generate an interrupt! The base PIC datasheet says that the maximum logic "zero" level is 15% Vdd, so if the highest "keypressed" resistance is 11k then the pullup should be greater than (11 * 85 / 15 = 62) , say 68 kohms. Another advantage of the relatively high resistance ratio is that we can read the pin using READADC10 but only need to work with the low byte.
Therefore my "first cut" design was a 1k resistor between each adjacent pair of columns, 3k0 between each adjacent row and 68k pullup from the keyboard/PICaxe pin. The spreadsheet showed that the "rollover" (due to increasing resistance values at high keynumbers) gives a just about acceptable fit to a straight line, but can we do better (and get rid of those 3k0s)? My spreadsheet suggests that 2k7 from row 1 (key 1) to row 2 and 3k3 between each of the other two adjacent pairs of rows gives a better fit. For example see the Red line between the Blue and Yellow thresholds, below.
For an analogue design of this type it's important to use "exact" resistor values which can be inconvenient to obtain. However, a feature of the preferred (E6, E12, E24) resistor series is that the operation is very similar if
all the values are changed by the same number of steps. For example, the 68k pullup could be changed to (perhaps a more available) 100k, with keypad chains of 1k5 + 1k5 and 3k9 + 4k7 + 4k7. Note that 3k9 can be fabricated by connecting 4k7 and 22k (which should be in most spares boxes) in parallel. Another possible set of values is 47k (pullup) with 680R (ohms) + 680R and 1k8 + 2k2 + 2k2 (where the 1k8 could be 2k2 in parallel with 10k and/or the "47k" = 2 x 22k in series).
Even lower resistor values might be possible, but we need to consider the resistance of the keypad switches. Mine measures about 30 ohms, but nearer 60 ohms if only lightly pressed. It won't affect the resistor chain current much, but it would be wise to make the smallest chain "step" resistance at least ten times the "contact" resistance.
As mentioned before, it's not possible to guarantee that these designs will "work out of the box" using 5% resistors. It might be possible by improving just the pullup to 1% tolerance, because that primarily defines (or should) the current in the resistor chain. But the calculation is complex and it's easier (and success more likely) to include a "calibration" stage in the software. That could be as simple as reading/displaying the A/D voltage when the "0" key is pressed and then selecting the scale factor(s) in the program such that the value is equi-distant from the * and # "decision thresholds" (i.e. to produce a value of "10.5" after the final division). The "bias" (or sit-up) value may also help optimisation but can probably be preset at between 1/4 and 1/2 of the average keyboard voltage step.
Cheers, Alan.