To make my ESP32 ZX Spectrum touch keyboard work even better I needed to make every single key completely independent.
So I need 40 touch pads. The ESP32-S3 only has 14 touch pins. For the current version I’ve been using a matrix approach. Which only needs 13 touch pins - which we’ve used for 5 columns and 8 rows.
This actually works really well, but there is a problem. We detect some combinations of keys. And the ZX Spectrum relies on a lot of key combinations for BASIC - symbol shift being one of the most critical.
Also, a lot of games need to detect multiple key presses - if you can’t do this then you get some quite annoying behaviour.
So, let’s dig into how touch works.
If you hook up a touch pad to an oscilloscope you can see this pattern.
Zooming in on this, we can see this saw tooth pattern:
The way touch detection works is that the ESP32 times how long it takes to charge the pad up and down between two known voltages. The capacitance of the pad determines this. If we have a finger near or on the touch pad the capacitance increases - and thus the time increases.
So, it’s just an analog signal. This got me thinking, there are some analog multiplexer ICs that have been around forever - the 4051 series of chips. There’s a whole bunch of manufacturers of these chips, so they are dead cheap (one could say, they are cheap as chips!).
The only issue with this is that there is a quite high “on” resistance with these multiplexers.
Will touch still work when there’s a resistance in series with it? My quick initial test seems to indicate that it will - this is with a 270ohm resistor and touch seems to work perfectly.
So, I ordered some breadboard friendly versions and cooked up this contraption:
And it works! It works even better than I could possible imagine. It’s really cool.
With five of these ICs we can get 40 individual touch pads! And the BOM cost is only around $1! Amazing!
I sent this off to PCBWay - and the boards came back a week or so ago. And - it works! The new keyboard is really good. We can detect every single combination of keys and it’s really responsive. Scanning the whole keyboard takes around 20ms.
We’re pretty much ready for production now - this was the last big challenge to solve.