Thursday, March 16, 2017

Analog matrix keyboard

Keyboard using voltage dividers and analog inputs

This is a custom keyboard PCB that uses 12 analog channels on a Teensy LC. 4 switches are attached to each channel. Each switch when pressed connects to ground through a resistor. Each of the 4 switches has a different value resistor. Through parallel resistance the voltage divider produces a different voltage for each of the 16 possible combinations of the 4 keys being pressed. This voltage is sampled by the Teensy LC input pin and converted to a decimal value. These values are compared to an array and translated into keypresses.

The schematic shows the 12 channels and the resistors in the parallel resistor/voltage dividers. A Pro Micro was used to control the LEDs in the same way that the GNAP does.

An Arduino sketch was used to sample the analog inputs and output to serial monitor. The data was compiled and the values corresponding to the 16 different switch combinations identified. In the chart you can see the distribution of the 16 values. As more keys are pressed there is less separation of the values.

These are the 16 different analogread ranges for each of the 16 switch combinations. Resistor values must be selected so that the ranges never overlap.

The resistor values used were 1k, 2k, 3.9k, 8.1k. The pullup resistor is also 3.9k. Mathematically they should produce distinct voltages when combined in parallel in any combination in a voltage divider.

The matrix works, and my prototype can detect all 48 switches being pressed in any pattern. Currently there is no keyboard code, it is just a large board of switches that light up the corresponding LED when pressed.

There is a problem in that resistors are temperature sensitive, their resistance changes with temperature. The ones I used are metal film 1% tolerance with a 50ppm/C temperature coefficient. These were relatively inexpensive at 5 cents a piece. The problem is that there is sufficient drift with temperature that the readings on the lower end start to drift with temperature extremes. There are better resistors, 0.1% 15ppm/C, but they cost 7 times as much. Instead of $3 of resistors it would be $21.

Other possible solutions are to use a temperature sensor, switch to a Teensy 3.2, or add a better power supply. With a temperature sensor the readings can be adjusted to compensate for thermal drift. The Teensy 3.2 has an ADC with 1 more bit of resolution, which may or may not help. A better more stable power supply may remove some of the jitter in the readings. It is currently using the 3v regulator built into the Teensy LC.

I probably won't pursue this any further. Since I can't get 100% accurate output without modifications which may not help and it is cheaper and more reliable to use a conventional matrix. This uses 12 pins at 4 switches per pin for a total of 48 switches. A conventional matrix for the same number of switches can be made of a 8x6 grid, only 2 more pins.

Some pictures of the assembled prototype:

Keycaps are the X-Keys relegendable ones. I glued them shut since the tops pop off with the slightest pressure from the side. Probably fine when used with the X-Keys boards since they have very high bezels.

A second PCB was used as the bottom.

 You can see the Teensy LC and the Pro Micro between the two PCBs.