In this tutorial, we’ll discuss how to implement STM32 Capacitive Touch Sensing Without TSC Peripheral. Many different techniques can be used to implement capacitive touch sensing with STM32 microcontrollers that don’t have a TSC (touch sensing controller) peripheral inside.
In this tutorial, we’ll explore a very basic technique that will help us add multiple CapTouch keys to our application that’s based on the STM32F103 blue pill board which doesn’t have TSC channels. The practical example we’ll implement in this tutorial will be a very good starting point for your touch-enabled STM32 project. Without further ado, let’s get right into it!
Table of Contents
- STM32 Capacitive Touch Sensing
- STM32 Capacitive Touch Without TSC Example
- STM32 Touch Sensing Without TSC Example Project
- Wrap Up
STM32 Capacitive Touch Sensing
As stated in the previous STM32 TSC Tutorial, all capacitive touch sensing techniques & peripherals are designed to solve the exact same problem. Which is measuring and quantifying the change in the capacitance value of an electrode (touch sensor). The TSC peripheral is a very complex and capable peripheral as we’ve seen in the previous tutorial but unfortunately, it’s not present in most of the STM32 microcontroller series.
Therefore, we’ll use a very basic technique that works as follows.
RC+Timer CapTouch Sensor Acquisition
As we’ve stated earlier in the TSC tutorial, a self-capacitance touchpad will have a stray capacitance with local ground. And when a grounded object gets into its electrostatic field’s range, it’ll couple to its magnetic field and the total sensor’s capacitance increases.
I did also mention that this capacitance increase is significant relative to the sensor’s self-capacitance. But generally speaking, it’s a very tiny amount of capacitance (in the order of 10-20pF). It depends on various parameters like the insulating layer thickness and material type, the touchpad shape and size on the PCB, and so on.
Given that we’re dealing with a very tiny capacitance value and it needs to be measured, we’ll have to make the charging process very slow in order to be able to monitor it. And here is how to do it:
We’ll use 2 GPIO pins, the first of which will be a driver pin. And the second one will be an input pin (a normal digital input pin) and will get hooked to our touchpad (electrode/sensor). We’ll also place a large value resistor (1.5MΩ) between both pins. Therefore, when we send a high signal (logic 1 or 3.3v), the other pin will read 1 but only after the capacitor charges to the level where it can be detected as a logic 1 input. This is basically how this technique works!
Using a timer module, we can now start charging the sensor capacitor and start the timer at the same time. And stop it when the digital input pin reads logic 1. Now, you’ve a reading for the charging time that is directly proportional to the sensor’s capacitance. The higher the capacitance is, the more time it takes the input pin to reach logic 1 threshold voltage.
In other words, when a human touches the electrode (sensor), the capacitance increases. Therefore, the time measurement should show an increase in the ticks count. The software will therefore register a “user touch” event and act correspondingly.
And that’s how it works! It’s easy to prototype on a breadboard and easy to implement in code. This technique requires 1x hardware timer peripheral + 2x GPIO (1 Drive & 1 Sense) pins.
This article will give you more in-depth information about the STM32 TSC (Touch Sensing Controller) hardware peripheral and how to use it with your custom designs of touch sensors (electrodes).
STM32 Capacitive Touch Without TSC Example
In this example project, we’ll set up the STM32 to sample (read) two capacitive touch buttons using the (RC+Timer) technique. The CapTouch buttons will be used to control 2x output LEDs each of which will be turned ON as long as the corresponding CapTouch button is “touched” by the end user.
Example Project Steps Summary:
- Set up a new project, system clock, and enable SWD (serial wire debug)
- Set up 2x GPIO pins: for the output LEDs
- Set up 2x GPIO pins: for the output driver pins
- Set up 2x GPIO pins: for the input sensor lines
- Enable the Timer2 peripheral: to measure the charging time of each sensor
Example Project Wiring Diagram
STM32 Touch Sensing Without TSC Example Project
And now, let’s build this system step-by-step
Step #1
Open STM32CubeMX, create a new project, and select the target microcontroller.
Step #2
Set the 2x GPIOs B0 & B1 as output pins (for the 2x LEDs)
Set the 2x GPIOs B10 & B11 as output pins (for the 2x output driver pins)
Set the 2x GPIOs A5 & A6 as input pins (for the 2x input touch sensors)
Step #3
Enable Timer2 by setting the internal clock as a clock source for it and set the prescaler to 24 (nothing magical about this value, we just want to slow down the timer so it doesn’t overflow when the CapTouch button is touched “high capacitance”).
Step #4
Go to the RCC clock configuration page and enable the HSE external crystal oscillator input.
Step #5
Go to the clock configurations page, select the HSE as a clock source, PLL output, and type in 72MHz for the desired output system frequency. Hit the “ Enter” key, and let the application solve for the required PLL dividers/multipliers to achieve the desired clock rate.
Step #6
Name & Generate The Project Initialization Code For CubeIDE or The IDE You’re Using.
STM32 Touch Sensor (Switch) Example Code
Here is The Application Code For This LAB (main.c)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
/* * LAB Name: STM32 Capacitive Touch Sensing Without TSC * Author: Khaled Magdy * For More Info Visit: www.DeepBlueMbedded.com */ #include "main.h" #define CAPTOUCH_SENSORS 2 #define TOUCH_THRESHOLD 3000 #define RAW_BUFFER_LEN 10 typedef struct { GPIO_TypeDef* DriveGPIO; uint16_t DrivePIN; GPIO_TypeDef* SenseGPIO; uint16_t SensePIN; uint32_t CapTouch_Raw[RAW_BUFFER_LEN]; } CapTouchSensor_s; TIM_HandleTypeDef htim2; CapTouchSensor_s MyTouchSensors[CAPTOUCH_SENSORS]; uint8_t CapTouch_Buffer_Index = 0; void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_TIM2_Init(void); static void CapTouch_Sample(); static void CapTouch_Handler(); static uint8_t CapTouch_Filtered_State(uint8_t); int main(void) { // CapTouch Sensor1 Pins MyTouchSensors[0].DriveGPIO = GPIOB; MyTouchSensors[0].DrivePIN = GPIO_PIN_10; MyTouchSensors[0].SenseGPIO = GPIOA; MyTouchSensors[0].SensePIN = GPIO_PIN_5; // CapTouch Sensor2 Pins MyTouchSensors[1].DriveGPIO = GPIOB; MyTouchSensors[1].DrivePIN = GPIO_PIN_11; MyTouchSensors[1].SenseGPIO = GPIOA; MyTouchSensors[1].SensePIN = GPIO_PIN_6; HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_TIM2_Init(); while (1) { CapTouch_Sample(); CapTouch_Handler(); HAL_Delay(1); } } static void CapTouch_Sample() { // Sample All CapTouch Sensors for(uint8_t i=0; i<CAPTOUCH_SENSORS; i++) { TIM2->CNT = 0; HAL_GPIO_WritePin(MyTouchSensors[i].DriveGPIO, MyTouchSensors[i].DrivePIN, GPIO_PIN_SET); HAL_TIM_Base_Start(&htim2); while(!HAL_GPIO_ReadPin(MyTouchSensors[i].SenseGPIO, MyTouchSensors[i].SensePIN)); MyTouchSensors[i].CapTouch_Raw[CapTouch_Buffer_Index] = TIM2->CNT; HAL_TIM_Base_Stop(&htim2); HAL_GPIO_WritePin(MyTouchSensors[i].DriveGPIO, MyTouchSensors[i].DrivePIN, GPIO_PIN_RESET); } // Update The Buffer Index CapTouch_Buffer_Index++; if(CapTouch_Buffer_Index == RAW_BUFFER_LEN){ CapTouch_Buffer_Index = 0; } } static uint8_t CapTouch_Filtered_State(uint8_t CapTouch_SensorIndex) { for(uint8_t i=0; i<RAW_BUFFER_LEN; i++) { if(MyTouchSensors[CapTouch_SensorIndex].CapTouch_Raw[i] >= TOUCH_THRESHOLD){ return 1; } } return 0; } static void CapTouch_Handler() { if(CapTouch_Filtered_State(0)){ HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_SET); // LED1 ON } else{ HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET); // LED1 OFF } if(CapTouch_Filtered_State(1)){ HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET); // LED2 ON } else{ HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET); // LED2 OFF } } |
STM32 Capacitive Touch Without TSC Example Testing
Note That you may need to change the threshold value in the code to tune the application to work properly on your setup. If you’ve noticed that the timer is overflowing during the sampling process, you’ll need to increase the prescaler value to prevent such an issue.
Modifying the provided code example should be easy as I’ve kept everything as generic as possible. You may also consider optimizing it a little bit by using only 1 driver output pin instead of 1 pin per sensor which is not efficient if your system requires so many input CapTouch buttons.
Required Parts For STM32 Examples
All the example Code/LABs/Projects in this STM32 Series of Tutorials are done using the Dev boards & Electronic Parts Below:
QTY. | Component Name | Amazon.com | AliExpress | eBay |
1 | Capacitive Touch Sensor (Button / Switch) | Amazon | AliExpress | eBay |
1 | STM32-F103 BluePill Board (ARM Cortex-M3 @ 72MHz) | Amazon | AliExpress | eBay |
1 | Nucleo-L432KC (ARM Cortex-M4 @ 80MHz) | Amazon | AliExpress | eBay |
1 | ST-Link V2 Debugger | Amazon | AliExpress | eBay |
2 | BreadBoard | Amazon | AliExpress | eBay |
1 | LEDs Kit | Amazon & Amazon | AliExpress | eBay |
1 | Resistors Kit | Amazon & Amazon | AliExpress | eBay |
1 | Capacitors Kit | Amazon & Amazon | AliExpress & AliExpress | eBay & eBay |
1 | Jumper Wires Pack | Amazon & Amazon | AliExpress & AliExpress | eBay & eBay |
1 | Push Buttons | Amazon & Amazon | AliExpress | eBay |
1 | Potentiometers | Amazon | AliExpress | eBay |
1 | Micro USB Cable | Amazon | AliExpress | eBay |
★ Check The Links Below For The Full Course Kit List & LAB Test Equipment Required For Debugging ★
Download Attachments
You can download all attachment files for this Article/Tutorial (project files, schematics, code, etc..) using the link below. Please consider supporting our work through the various support options listed in the link down below. Every small donation helps to keep this website up and running and ultimately supports the whole community.
Wrap Up
In conclusion, we’ve explored how to implement capacitive touch sensing with any STM32 microcontroller that doesn’t have an internal TSC (touch sensing controller) peripheral. The given method in this tutorial is very simplistic and may not be as robust as you need but it’s definitely worth trying and tuning for your applications’ needs.
You can build on top of the example provided in this tutorial and/or explore the other parts of the STM32 capacitive touch sensing tutorials series for more information about the other STM32 capacitive touch sensing techniques.