I'm still relearning KiCad, so one of the first things I did while entering bits of schematic is the keypad. It's basically a 5 row, 8 column, matrix with a few contacts missing where there are larger keys.
A resilient rubber sheet formed with bumps covers the PCB, each of the bumps under a key on the keypad. On the inside of each bump is a flexible conductive pad. Pressing the key pushes the conductive pad against a pair of bare conductors in close proximity on the PCB. These conductors meander in a pattern intended to maximize the area of contact, which minimizes the chance of missing a keypress.
Since these conductors are exposed to air, they must be corrosion-resistant. This board appears to use carbon rather than copper on the top of this board, which makes it quite resistant to corrosion. However, it also has a measurable amount of resistance to it. I believe the reason the traces visible in the photo here are so wide is to minimize that resistance.
This I knew from when I first disassembled and examined the board. I'd also measured the resistance of the conductive pad itself, which is quite low. What I'd never gotten around to measuring was how much resistance there was when the pad was pressed against the PCB, nor had I calculated acceptable values for the pull-up resistors on the rows and possibly columns. So tonight I made an attempt.
If you look closely at the photo (click on it to enlarge it) you'll find a key contact labeled "COST". Measuring from that to the via below the key contact area marked "GT" I see over 400 ohms. Measuring to the via above the "COST" key contact I see over 100 ohms. That's what I mean by "measurable resistance". Pressing the pad against the contact area gives a resistance of about 1.0K to 1.5K, depending on how hard the pad is pressed. If the carbon PCB traces account for 500 to 600 ohms I'd believe that the contact resistance accounts for the other 500 to 1K ohms.
I won't be making a PCB with a carbon layer on the top side, even if I knew where to get such a thing. On the other hand this is an experiment and I don't need that level of wear and corrosion resistance. My plan is to use normal copper with an ENIG (Electroless Nickel Immersion Gold) plating, which is easily available. This should give me reasonable corrosion protection while offering a flat surface. While I expect that will eliminate much of the contact resistance (and all but an insignificant amount of trace resistance), I'm still planning for 1K to 2K of resistance when a key is pressed.
Here's the schematic for the keypad as it stands now:
The 74LVC14 Schmitt trigger inverters I'm going to use to buffer these contacts wants to see a voltage below 0.7V before it considers an input to be low. The datasheet for the Spartan-6 family says the highest voltage on an output driven low is 0.4V, so the maximum voltage that I can allow to develop across the keypad contacts is 0.3V. If I hedge my bets and assume 2K through the keypad, Ohm's Law says 0.3V across a 2K resistor means there is 150µA flowing. Dropping the remaining 2.6V at 150µA requires my pull-up resistor to be 18K ohms or higher.
Looking at it the other way, an input of the 74LVC14 needs to reach as high as 2.0V before it sees the input as high. The datasheet says an input pin could leak as much as 5µA, so the upper limit on the pull-up resistor is 260K ohms.
There's also timing to consider. An input to the 74LVC14 presents a capacitance of only 5pF, but the contact patterns look a lot like tiny capacitors and the PCB traces are long. if I assume a bloated 50pF on each row, pulled up by a single 260K resistor, the RC time constant is 13µs. (In fact, it'll rise from 0.0V to 2.0V in 12.1µs, but who's counting?) This is far shorter than the 250µs I plan to assert the column output lines, so 260K would work.
As can be seen on the schematic, I'm planning to use 100K pull-up resistors on both rows
and columns. This is the equivalent of one 50K ohm pull-up resistor when one
switch contact is closed. There is also a 470 ohm resistor in series between the FPGA and the column of switch contacts.
Why the 470 ohm series resistors on the column drivers? My Verilog test code drives all the columns high, except for the one I want to probe which is driven low. If two switches on the same row are pressed at the same time, the low output of the column being probed and the high output of the other column are connected through the switches. That could damage the FPGA's driver circuitry. Digilent addressed this on their PmodKYPD keypad by placing 470 ohm resistors in series with the columns. If all seven keys in a row were pressed simultaneously, there would be seven 470 ohm resistors in parallel (equivalent to one 67 ohm resistor) in series with one 470 ohm resistor, for a total resistance of 537 ohms. With 3.3V across 537 ohms there would be a current of about 6mA. That's not ideal but it's insufficient to damage the FPGA.
Why the 100K ohm pull-ups on the columns? To avoid the issue of connecting two opposing drivers together, and thus avoiding the need for the series resistors, I could set the column drivers for the inactive columns to a high-impedance state. After all, the pull-up resistor on the row would pull the column high when a switch is pressed. However, digital logic really doesn't like inputs that float, and the columns that aren't being driven are essentially floating inputs. The column pull-ups keep these inactive columns in a known (high) state, as well as avoiding glitches on the rows when switches are pressed.
Laying out the PCB for both series resistors and pull-ups allows me to defer the decision on how to drive the columns until long after the board is fabricated. It's easy to leave the pull-up resistors off if I drive the columns high, and almost as easy to install 0-ohm "resistors" if I use the pull-ups. Or install both sets of resistors, which would permit either mode of scanning.
Isn't this fun?