Touch Sensor

[中文]

Introduction

A touch sensor system is built on a substrate which carries electrodes and relevant connections under a protective flat surface. When a user touches the surface, the capacitance variation is used to evaluate if the touch was valid.

ESP32 can handle up to 10 capacitive touch pads / GPIOs. The sensing pads can be arranged in different combinations (e.g., matrix, slider), so that a larger area or more points can be detected. The touch pad sensing process is under the control of a hardware-implemented finite-state machine (FSM) which is initiated by software or a dedicated hardware timer.

Design, operation, and control registers of a touch sensor are discussed in ESP32 Technical Reference Manual (PDF). Please refer to this manual for additional details on how this subsystem works.

In-depth design details of touch sensors and firmware development guidelines for ESP32 are available in Touch Sensor Application Note. If you want to test touch sensors in various configurations without building them on your own, check the Guide for ESP32-Sense Development Kit.

Functionality Overview

Description of API is broken down into groups of functions to provide a quick overview of the following features:

  • Initialization of touch pad driver
  • Configuration of touch pad GPIO pins
  • Taking measurements
  • Adjusting parameters of measurements
  • Filtering measurements
  • Touch detection methods
  • Setting up interrupts to report touch detection
  • Waking up from Sleep mode on interrupt

For detailed description of a particular function, please go to Section API Reference. Practical implementation of this API is covered in Section Application Examples.

Initialization

Before using a touch pad, you need to initialize the touch pad driver by calling the function touch_pad_init(). This function sets several .._DEFAULT driver parameters listed in API Reference under Macros. It also removes the information about which pads have been touched before, if any, and disables interrupts.

If the driver is not required anymore, deinitialize it by calling touch_pad_deinit().

Configuration

Enabling the touch sensor functionality for a particular GPIO is done with touch_pad_config().

Use the function touch_pad_set_fsm_mode() to select if touch pad measurement (operated by FSM) should be started automatically by a hardware timer, or by software. If software mode is selected, use touch_pad_sw_start() to start the FSM.

Touch State Measurements

The following two functions come in handy to read raw or filtered measurements from the sensor:

  • touch_pad_read()
  • touch_pad_read_filtered()

They can also be used, for example, to evaluate a particular touch pad design by checking the range of sensor readings when a pad is touched or released. This information can be then used to establish a touch threshold.

Note

Before using touch_pad_read_filtered(), you need to initialize and configure the filter by calling specific filter functions described in Section Filtering of Measurements.

For the demonstration of how to use both read functions, check the application example peripherals/touch_pad_read.

Optimization of Measurements

A touch sensor has several configurable parameters to match the characteristics of a particular touch pad design. For instance, to sense smaller capacity changes, it is possible to narrow down the reference voltage range within which the touch pads are charged / discharged. The high and low reference voltages are set using the function touch_pad_set_voltage().

Besides the ability to discern smaller capacity changes, a positive side effect is reduction of power consumption for low power applications. A likely negative effect is an increase in measurement noise. If the dynamic range of obtained readings is still satisfactory, then further reduction of power consumption might be done by reducing the measurement time with touch_pad_set_meas_time().

The following list summarizes available measurement parameters and corresponding ‘set’ functions:

  • Touch pad charge / discharge parameters:

    • voltage range: touch_pad_set_voltage()
    • speed (slope): touch_pad_set_cnt_mode()
  • Measurement time: touch_pad_set_meas_time()

Relationship between the voltage range (high / low reference voltages), speed (slope), and measurement time is shown in the figure below.

Touch Pad - relationship between measurement parameters

Touch pad - relationship between measurement parameters

The last chart Output represents the touch sensor reading, i.e., the count of pulses collected within the measurement time.

All functions are provided in pairs to set a specific parameter and to get the current parameter’s value, e.g., touch_pad_set_voltage() and touch_pad_get_voltage().

Filtering of Measurements

If measurements are noisy, you can filter them with provided API functions. Before using the filter, please start it by calling touch_pad_filter_start().

The filter type is IIR (infinite impulse response), and it has a configurable period that can be set with the function touch_pad_set_filter_period().

You can stop the filter with touch_pad_filter_stop(). If not required anymore, the filter can be deleted by invoking touch_pad_filter_delete().

Touch Detection

Touch detection is implemented in ESP32’s hardware based on the user-configured threshold and raw measurements executed by FSM. Use the functions touch_pad_get_status() to check which pads have been touched and touch_pad_clear_status() to clear the touch status information.

Hardware touch detection can also be wired to interrupts. This is described in the next section.

If measurements are noisy and capacity changes are small, hardware touch detection might be unreliable. To resolve this issue, instead of using hardware detection / provided interrupts, implement measurement filtering and perform touch detection in your own application. For sample implementation of both methods of touch detection, see peripherals/touch_pad_interrupt.

Touch Triggered Interrupts

Before enabling an interrupt on a touch detection, you should establish a touch detection threshold. Use the functions described in Touch State Measurements to read and display sensor measurements when a pad is touched and released. Apply a filter if measurements are noisy and relative capacity changes are small. Depending on your application and environment conditions, test the influence of temperature and power supply voltage changes on measured values.

Once a detection threshold is established, it can be set during initialization with touch_pad_config() or at the runtime with touch_pad_set_thresh().

In the next step, configure how interrupts are triggered. They can be triggered below or above the threshold, which is set with the function touch_pad_set_trigger_mode().

Finally, configure and manage interrupt calls using the following functions:

  • touch_pad_isr_register() / touch_pad_isr_deregister()
  • touch_pad_intr_enable() / touch_pad_intr_disable()

When interrupts are operational, you can obtain the information from which particular pad an interrupt came by invoking touch_pad_get_status() and clear the pad status with touch_pad_clear_status().

Note

Interrupts on touch detection operate on raw / unfiltered measurements checked against user established threshold and are implemented in hardware. Enabling the software filtering API (see Filtering of Measurements) does not affect this process.

Wakeup from Sleep Mode

If touch pad interrupts are used to wake up the chip from a sleep mode, you can select a certain configuration of pads (SET1 or both SET1 and SET2) that should be touched to trigger the interrupt and cause the subsequent wakeup. To do so, use the function touch_pad_set_trigger_source().

Configuration of required bit patterns of pads may be managed for each ‘SET’ with:

  • touch_pad_set_group_mask() / touch_pad_get_group_mask()
  • touch_pad_clear_group_mask()

Application Examples

API Reference

GPIO Lookup Macros

Some useful macros can be used to specified the GPIO number of a touch pad channel, or vice versa. e.g.

  1. TOUCH_PAD_NUM5_GPIO_NUM is the GPIO number of channel 5 (12);
  2. TOUCH_PAD_GPIO4_CHANNEL is the channel number of GPIO 4 (channel 0).

Macros

TOUCH_PAD_GPIO4_CHANNEL
TOUCH_PAD_NUM0_GPIO_NUM
TOUCH_PAD_GPIO0_CHANNEL
TOUCH_PAD_NUM1_GPIO_NUM
TOUCH_PAD_GPIO2_CHANNEL
TOUCH_PAD_NUM2_GPIO_NUM
TOUCH_PAD_GPIO15_CHANNEL
TOUCH_PAD_NUM3_GPIO_NUM
TOUCH_PAD_GPIO13_CHANNEL
TOUCH_PAD_NUM4_GPIO_NUM
TOUCH_PAD_GPIO12_CHANNEL
TOUCH_PAD_NUM5_GPIO_NUM
TOUCH_PAD_GPIO14_CHANNEL
TOUCH_PAD_NUM6_GPIO_NUM
TOUCH_PAD_GPIO27_CHANNEL
TOUCH_PAD_NUM7_GPIO_NUM
TOUCH_PAD_GPIO33_CHANNEL
TOUCH_PAD_NUM8_GPIO_NUM
TOUCH_PAD_GPIO32_CHANNEL
TOUCH_PAD_NUM9_GPIO_NUM

Macros

TOUCH_PAD_SLOPE_DEFAULT
TOUCH_PAD_TIE_OPT_DEFAULT
TOUCH_PAD_BIT_MASK_MAX
TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD
TOUCH_PAD_LOW_VOLTAGE_THRESHOLD
TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD
TOUCH_PAD_INACTIVE_CONNECT_DEFAULT
TOUCH_PAD_THRESHOLD_MAX

If set touch threshold max value, The touch sensor can’t be in touched status

Enumerations

enum touch_pad_t

Values:

TOUCH_PAD_NUM0 = 0

Touch pad channel 0 is GPIO4(ESP32)

TOUCH_PAD_NUM1

Touch pad channel 1 is GPIO0(ESP32) / GPIO1(ESP32-S2)

TOUCH_PAD_NUM2

Touch pad channel 2 is GPIO2(ESP32) / GPIO2(ESP32-S2)

TOUCH_PAD_NUM3

Touch pad channel 3 is GPIO15(ESP32) / GPIO3(ESP32-S2)

TOUCH_PAD_NUM4

Touch pad channel 4 is GPIO13(ESP32) / GPIO4(ESP32-S2)

TOUCH_PAD_NUM5

Touch pad channel 5 is GPIO12(ESP32) / GPIO5(ESP32-S2)

TOUCH_PAD_NUM6

Touch pad channel 6 is GPIO14(ESP32) / GPIO6(ESP32-S2)

TOUCH_PAD_NUM7

Touch pad channel 7 is GPIO27(ESP32) / GPIO7(ESP32-S2)

TOUCH_PAD_NUM8

Touch pad channel 8 is GPIO33(ESP32) / GPIO8(ESP32-S2)

TOUCH_PAD_NUM9

Touch pad channel 9 is GPIO32(ESP32) / GPIO9(ESP32-S2)

TOUCH_PAD_MAX
enum touch_high_volt_t

Values:

TOUCH_HVOLT_KEEP = -1

Touch sensor high reference voltage, no change

TOUCH_HVOLT_2V4 = 0

Touch sensor high reference voltage, 2.4V

TOUCH_HVOLT_2V5

Touch sensor high reference voltage, 2.5V

TOUCH_HVOLT_2V6

Touch sensor high reference voltage, 2.6V

TOUCH_HVOLT_2V7

Touch sensor high reference voltage, 2.7V

TOUCH_HVOLT_MAX
enum touch_low_volt_t

Values:

TOUCH_LVOLT_KEEP = -1

Touch sensor low reference voltage, no change

TOUCH_LVOLT_0V5 = 0

Touch sensor low reference voltage, 0.5V

TOUCH_LVOLT_0V6

Touch sensor low reference voltage, 0.6V

TOUCH_LVOLT_0V7

Touch sensor low reference voltage, 0.7V

TOUCH_LVOLT_0V8

Touch sensor low reference voltage, 0.8V

TOUCH_LVOLT_MAX
enum touch_volt_atten_t

Values:

TOUCH_HVOLT_ATTEN_KEEP = -1

Touch sensor high reference voltage attenuation, no change

TOUCH_HVOLT_ATTEN_1V5 = 0

Touch sensor high reference voltage attenuation, 1.5V attenuation

TOUCH_HVOLT_ATTEN_1V

Touch sensor high reference voltage attenuation, 1.0V attenuation

TOUCH_HVOLT_ATTEN_0V5

Touch sensor high reference voltage attenuation, 0.5V attenuation

TOUCH_HVOLT_ATTEN_0V

Touch sensor high reference voltage attenuation, 0V attenuation

TOUCH_HVOLT_ATTEN_MAX
enum touch_cnt_slope_t

Values:

TOUCH_PAD_SLOPE_0 = 0

Touch sensor charge / discharge speed, always zero

TOUCH_PAD_SLOPE_1 = 1

Touch sensor charge / discharge speed, slowest

TOUCH_PAD_SLOPE_2 = 2

Touch sensor charge / discharge speed

TOUCH_PAD_SLOPE_3 = 3

Touch sensor charge / discharge speed

TOUCH_PAD_SLOPE_4 = 4

Touch sensor charge / discharge speed

TOUCH_PAD_SLOPE_5 = 5

Touch sensor charge / discharge speed

TOUCH_PAD_SLOPE_6 = 6

Touch sensor charge / discharge speed

TOUCH_PAD_SLOPE_7 = 7

Touch sensor charge / discharge speed, fast

TOUCH_PAD_SLOPE_MAX
enum touch_tie_opt_t

Values:

TOUCH_PAD_TIE_OPT_LOW = 0

Initial level of charging voltage, low level

TOUCH_PAD_TIE_OPT_HIGH = 1

Initial level of charging voltage, high level

TOUCH_PAD_TIE_OPT_MAX
enum touch_fsm_mode_t

Values:

TOUCH_FSM_MODE_TIMER = 0

To start touch FSM by timer

TOUCH_FSM_MODE_SW

To start touch FSM by software trigger

TOUCH_FSM_MODE_MAX
enum touch_trigger_mode_t

Values:

TOUCH_TRIGGER_BELOW = 0

Touch interrupt will happen if counter value is less than threshold.

TOUCH_TRIGGER_ABOVE = 1

Touch interrupt will happen if counter value is larger than threshold.

TOUCH_TRIGGER_MAX
enum touch_trigger_src_t

Values:

TOUCH_TRIGGER_SOURCE_BOTH = 0

wakeup interrupt is generated if both SET1 and SET2 are “touched”

TOUCH_TRIGGER_SOURCE_SET1 = 1

wakeup interrupt is generated if SET1 is “touched”

TOUCH_TRIGGER_SOURCE_MAX