Capacitive touch is “rad”. By utilizing one of the simplest physical characteristics of an object – charge storage, one is able to measure the presence of a grounded object including touch and pressure. There are a couple of capacitive touch libraries that I’ve seen around but many require dedicated hardware, for example the TSC peripheral on other STM32 series microcontrollers, or don’t include very good noise rejection and/or require external hardware.
I’ve alleviated this and somewhat simple library that can be used for up to 16 touch sensors on any STM32 with a single timer and EXTI (which turns out to be… oh, all of them!).
The method of acquisition is the RC acquisition method and can be implemented with one resistor per channel (though this doesn’t have any ESD/EMI protection – an extra resistor will be required for this). By discharging all channels, in a timer interrupt and enabling an EXTI input for each channel, plus a touch of signal processing, one can have capacitive touch sensors. Once each line has been discharged (signalled by the value on the output going low), the lines are set to input and the node connecting all pull up resistors is set high. All that remains from there is waiting for an external interrupt to trigger. This may seem “dodgy” due to slow crossing signals but thanks to the inherent Schmitt triggers on the inputs of all STM32 GPIOs, this problem is some what alleviated, leading to reasonably clean edges and only single firing interrupts. Inside of the EXTI interrupt, the current value of the timer is captured and stored. Upon the next timer interrupt, these stored values are low pass filtered using a two pole IIR design for reduced memory requirements vs FIR filtering. A slow moving low pass filter is then subtracted from these filtered values to give the touch value without the DC norm – essentially high pass filtering for positive values only. This low pass filter moves fast enough to track environmental changes though reduces the maximum time a button can be held. The DC removal filter does however reset to the filtered values if it is ever larger than these values. This is to ensure the DC removal filter doesn’t produce negative values and is proven successful. The main reason for this filter is to remove conducted 50Hz/60Hz noise and general RF induced within the circuit. To ensure the filters work correctly, they are executed at a constant time rate within the timer interrupt. This isn’t vital though it improves performance. This DC removed filtered touch value is then compared to a threshold with hysteresis and converted into a binary 0 or 1 that can be used to actuate LEDs or used within code.
With two touch sensors connected to PA1 and PA2, the total program usage reported by CooCox is 5336 words. I’ve not yet measured efficiency and time consumption though I can’t imagine it being TOO high.
Using two simple touch sensors – copper tape on perspex to turn on and off the on board LEDs
The performance and SNR can also be tracked using STMStudio – my new favourite toy for parameter monitoring!
Measuring the touch values live through STMStudio
Having read up a touch on capacitive touch sensors, it turns out that SNR is a poor measurement metric for these sensors though peak deviation from non touch to touch is ~220 counts – equivalent to just under 8 bits of precision. With a very slow DC filter, the raw press value could be used as an indication of touch pressure leading to a capacitive pressure sensitive switch.
The library isn’t particularly portable yet but I’ll github it in case it helps anyone with their own designs!