STM32 Touch Sensors
Only some STM32 processors have touch sensor circuitry built in, most noticeable the STM32Lxx series.
Hardware Example
As part of another project I was using an STM32L432 MCU and while doing that design I decided to add 3 touch sensors.
The circuitry involved in the touch sensing is the C5 and the actual touch pads J2, J3 and J4 and their accompanying resistors.
Layout wise I did two different approaches:
The top and bottom touch pads are just big single sided SMD pads which is covered by soldermask. The center "hole" is a big through hole pad.
The gadget came out like this:
Software
STM32CubeMX Configuration
Messing around with this it turns out that the middle pad (the through hole one) is much to close to the neighbors, so in the software example I only deal with the two pads covered by soldermask.
Under Middleware/Touchsensing:
Code
The touchsensing middleware will do all the heavy lifting and only a few lines of code is needed to use the touch sensors.
First of all, in the main program loop:
/* Infinite loop */ /* USER CODE BEGIN WHILE */ uint32_t then = 0, now = 0; for (;;) { now = HAL_GetTick(); if (now % 50 == 0 && now != then) { tsl_user_Exec_IT(); if (now % 1000 == 0) { printf("Tick %5lu B0: %2d / %2d B1: %2d / %2d\n", now / 1000, MyTKeys[0].p_Data->StateId, MyTKeys[0].p_ChD->Meas, MyTKeys[1].p_Data->StateId, MyTKeys[1].p_ChD->Meas); } then = now; } /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ }
Essentially this will call the "tsl_user_Exec_IT()" function every 50 ms (20 times per second) and each second it will print out the status of the keys.
The interrupt handler callback is defined in tsl_user.c
void HAL_TSC_ConvCpltCallback(TSC_HandleTypeDef* htsc) { /* USER CODE BEGIN HAL_TSC_ConvCpltCallback start*/ /* USER CODE END HAL_TSC_ConvCpltCallback start*/ TSL_acq_BankGetResult(idx_bank_it, 0, 0); idx_bank_it++; if (idx_bank_it > TSLPRM_TOTAL_BANKS-1) { // End of all banks acquisition, restart bank 0 in while(1) loop (This is a choice) idx_bank_it=0; acq_done_it++; }else{ // We restart next bank acquisition TSL_acq_BankConfig(idx_bank_it); TSL_acq_BankStartAcq_IT(); } /* USER CODE BEGIN HAL_TSC_ConvCpltCallback*/ handle_touch(); /* USER CODE END HAL_TSC_ConvCpltCallback*/ }
All I do there is to call "handle_touch()" at the conclusion of each conversion.
The handle_touch() is defined like:
// Called after touch keys have been measured void handle_touch() { uint32_t t = HAL_GetTick(); for (int i = 0; i < 2; i++) { TSL_StateId_enum_T state = MyTKeys[i].p_Data->StateId; if (state != touch_state[i] && (state == TSL_STATEID_RELEASE || state == TSL_STATEID_DETECT)) { printf("At tick %d Key %d changed - now = %d\n", t, i, MyTKeys[i].p_Data->StateId); touch_state[i] = MyTKeys[i].p_Data->StateId; } } }
Touching each of the touchpads result in this output:
Resources
- Getting started with touch sensing control on STM32 microcontrollers
- Developing applications on STM32Cube with STMTouch touch sensing library
- Tuning a touch sensing application on MCUs
- Design with surface sensors for touch sensing applications on MCUs
- Improve conducted noise robustness for touch sensing applications on MCUs
- Sampling capacitor selection guide for touch sensing applications on MCUs
- ESD considerations for touch sensing applications on MCUs