ESP32 Touch Sensor using ESP-IDF

In this tutorial, we will discuss how to use ESP32 touch sensor pins using the touch pad driver library provided in ESP-IDF.

Before we move ahead, make sure you have the latest version of VS Code installed on your system with the ESP-IDF extension configured.

ESP32 Touch Sensor with ESP-IDF

ESP-WROOM-32 consists of 10 on-board capacitive touch sensors. These capacitive sensors can detect electrical changes on their respective GPIO pins. When any of the touch sensor pin is touched, it produces an output respective to the electrical charge present on ones finger.

You can view the touch sensor pins featured on ESP32 board:

  • TOUCH0 – GPIO4
  • TOUCH1 – GPIO0
  • TOUCH2 – GPIO2
  • TOUCH3 – GPIO15
  • TOUCH4 – GPIO13
  • TOUCH5 – GPIO12
  • TOUCH6 – GPIO14
  • TOUCH7 – GPIO27
  • TOUCH8 – GPIO33
  • TOUCH9 – GPIO32

These GPIOs present on ESP32 are helpful as they act as touch sensors which can cause a touchpad interrupt wakeup when they are touched, detecting any electrical/magnetic waves around them.

Let us create and build an ESP-IDF project where we will use driver/touch_pad.h APIs to demonstrate touch sensor functionality of ESP32 development board.

ESP32 ESP32-IDF Touch Sensor Code

Open your VS Code and head over to View > Command Palette. Type ESP-IDF: New Project in the search bar and press enter.

Specify the project name and directory. We have named our project ‘ESP_IDF_TOUCH_SENSOR.’ For the ESP-IDF board, we have chosen the custom board option. For ESP-IDF target, we have chosen ESP32 module. Click ‘Choose Template’ button to proceed forward.

ESP32 Touch Sensor using ESP-IDF Project

In the Extension, select ESP-IDF option:

ESP-IDF in VS Code New Project 2

We will click the ‘sample_project’ under the get-started tab. Now click ‘Create project using template sample_project.’

ESP-IDF in VS Code New Project 3

You will get a notification that the project has been created. To open the project in a new window, click ‘Yes.’

This opens our ESP_IDF_TOUCH_SENSOR project that we created inside the EXPLORER tab. There are several folders inside our project folder. This is the same for every project which you will create through ESP-IDF Explorer. The main folder contains the source code meaning the main.c file will be found here.

Go to main > main.c and open it. Copy the code given below in your main.c file. 

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/touch_pad.h"

#define TOUCH_PAD_GPIO13_CHANNEL TOUCH_PAD_NUM4

void app_main()
{
    touch_pad_init();
    touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_1V);
    touch_pad_config(TOUCH_PAD_GPIO13_CHANNEL, -1);
    touch_pad_filter_start(10);

    uint16_t val;
    uint16_t filtered_value = 0;
    uint16_t raw_value_touch = 0;

    while (true)
    {
        touch_pad_read_raw_data(TOUCH_PAD_GPIO13_CHANNEL, &raw_value_touch);
        touch_pad_read_filtered(TOUCH_PAD_GPIO13_CHANNEL, &filtered_value);
        touch_pad_read(TOUCH_PAD_GPIO13_CHANNEL, &val);
        printf("val_touch_gpio13 = %d raw_value = %d filtered_value = %d\n", val, raw_value_touch, filtered_value);
        vTaskDelay(1000 / portTICK_PERIOD_MS);
    }
}

How the Code Works?

Firstly, we will start by including the necessary libraries that includes the FreeRTOS libraries to generate delays and driver/touch_pad.h for the touch sensor functionality.

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/touch_pad.h"

We start off by defining the touch sensor pin of ESP32 that we will use. It is GPIO13 which corresponds to Touch pad channel 4.

#define TOUCH_PAD_GPIO13_CHANNEL TOUCH_PAD_NUM4

Initialization

Inside the app_main() function, we will first initialize the touch pad driver by calling touch_pad_init(). This function sets the different DEFAULT parameters of the driver and also disables interrupts and clear information about the touch pads if they were touched before.

touch_pad_init();

Optimization

Then, we will call touch_pad_set_voltage() function to set the reference voltage range for the touch pads. This function takes in three parameters where we have specified the max voltage as 2.7V and the minimum voltage as 0.5V. The attenuation for the maximum voltage is set as 1V. This reference voltage will set a range within which the touch pads will be charged or discharged.

touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_1V);

Configuration

To configure the touch pad for a particular GPIO, we will call touch_pad_config() function and specify the channel number of the GPIO that we are using as the first parameter and the interrupt threshold as the second parameter. This will therefore enable the functionality of the touch pad on GPIO13.

touch_pad_config(TOUCH_PAD_GPIO13_CHANNEL, -1);

Filtering

Moreover, we will also call touch_pad_filter_start() function to start the touch pad filter. This causes un-necessary noise to be filtered out so that very small changes in capacitance doesn’t cause false triggers. This function takes in a single parameter which is the filter calibration period in milliseconds. We have set it as ’10.’

touch_pad_filter_start(10);

Touch Sensor Measurements

Next we define three variables val, filtered_val and raw_value_touch which we will access in the infinite while loop.

   uint16_t val;
    uint16_t filtered_value = 0;
    uint16_t raw_value_touch = 0;

Inside the loop, we first read the touch pad raw data or the touch pad’s counter value from IIR filter process by calling the function, touch_pad_read_raw_data(). The counter value denotes the number of charge/discharge cycles. When a touch pad is touched by the user, the counter value decreases than when it was un-touched. This is because of a greater amount of equivalent capacitance.This function takes in two parameters. The first parameter is the touch pad index which is TOUCH_PAD_GPIO13 in our case. The second parameter is the pointer that holds the touch pad’s value. We previously defined it as ‘raw_touch_value’ which initially held the value 0.

touch_pad_read_raw_data(TOUCH_PAD_GPIO13_CHANNEL, &raw_value_touch);

Afterwards, we will call the function, touch_pad_read_filtered() to read the filtered value of the touch pad counter value by IIR filter. This function also takes in two parameters. The first parameter is the touch pad index which is TOUCH_PAD_GPIO13 in our case. The second parameter is the pointer that holds the touch pad’s value. We previously defined it as ‘filtered_value’ which initially held the value 0.

touch_pad_read_filtered(TOUCH_PAD_GPIO13_CHANNEL, &filtered_value);

Finally, we will call touch_pad_read() function to obtain the touch pad’s counter value. This function also takes in two parameters. The first parameter is the touch pad index which is TOUCH_PAD_GPIO13 in our case. The second parameter is the pointer that holds the touch pad’s value. We previously defined it as ‘val.’

touch_pad_read(TOUCH_PAD_GPIO13_CHANNEL, &val);

The ESP-IDF terminal prints the touch pad’s value, raw value and filtered value after a delay of every second.

printf("val_touch_gpio13 = %d raw_value = %d filtered_value = %d\n", val, raw_value_touch, filtered_value);
vTaskDelay(1000 / portTICK_PERIOD_MS);

Hardware Setup

Assemble the circuit as shown in the schematic diagram below:

ESP32 Touch Sensor at GPIO13 schematic diagram

We are using GPIO13 as the touch sensor pin, hence attach a wire at GPIO13 and touch the other end. Use an aluminum foil to create better connectivity while touching it.

ESP32 Touch Pad at GPIO13 hardware 1

Compiling the Sketch

To flash your chip, type the following command in the serial terminal. Remember to replace the COM port with the one through which your board is connected.

idf.py -p COMX flash monitor

After the code flashes successfully, touch the aluminum foil.

ESP32 Touch Pad at GPIO13 hardware demo

You may note that the touch sensor counter values decreases when you touch it. Without touching the touch GPIO, the values are significantly larger.

ESP32 Touch Sensor using ESP-IDF Project Terminal

If you are using Arduino IDE instead of ESP-IDF:

You may also like to read:

1 thought on “ESP32 Touch Sensor using ESP-IDF”

Leave a Comment