refactor(touch): update touch related examples to use new API

This commit is contained in:
laokaiyao
2025-01-08 12:59:03 +08:00
parent 32d23f9761
commit 09b15b479a
32 changed files with 411 additions and 846 deletions

View File

@@ -461,16 +461,9 @@ examples/peripherals/touch_sensor/touch_element:
examples/peripherals/touch_sensor/touch_sens_basic:
disable:
- if: SOC_TOUCH_SENSOR_SUPPORTED != 1
- if: SOC_TOUCH_SENSOR_VERSION == 1
temporary: true
reason: not supported yet
depends_components:
- esp_driver_touch_sens
examples/peripherals/touch_sensor/touch_sensor_v1:
disable:
- if: SOC_TOUCH_SENSOR_VERSION != 1
examples/peripherals/twai/twai_alert_and_recovery:
disable:
- if: SOC_TWAI_SUPPORTED != 1

View File

@@ -1,7 +1,7 @@
| Supported Targets | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- |
# Capacity Touch Sensor Example (for hardware version 3)
# Capacity Touch Sensor Example
(See the README.md file in the upper level 'examples' directory for more information about examples.)
@@ -34,42 +34,44 @@ See the Getting Started Guide for full steps to configure and use ESP-IDF to bui
## Example Output
You can see the following output in the monitor if the example runs successfully:
You can see the following output in the monitor if the example runs successfully (take ESP32-P4 for example):
```
W (461) touch: [sample_cfg_id 0] clock precision loss, expect 4000000 hz, got 4006725 hz
W (461) touch: [sample_cfg_id 1] clock precision loss, expect 8000000 hz, got 8013450 hz
W (461) touch: [sample_cfg_id 2] clock precision loss, expect 16000000 hz, got 16026900 hz
Touch [CH 0] enabled on GPIO2
Touch [CH 1] enabled on GPIO3
Touch [CH 2] enabled on GPIO4
Touch [CH 3] enabled on GPIO5
=================================
Initial benchmark and new threshold are:
[CH 0] 0: 4114, 411 1: 2057, 205 2: 1028, 102
[CH 1] 0: 4643, 464 1: 2322, 232 2: 1160, 116
[CH 2] 0: 4848, 484 1: 2424, 242 2: 1211, 121
[CH 3] 0: 4340, 434 1: 2170, 217 2: 1085, 108
Touch [CH 0] 0: 5161, 77 1: 5121, 76 2: 2533, 37
Touch [CH 1] 0: 5007, 75 1: 5036, 75 2: 2464, 36
Touch [CH 2] 0: 5086, 76 1: 5056, 75 2: 2487, 37
Touch [CH 3] 0: 4965, 74 1: 4989, 74 2: 2433, 36
=================================
benchmark [CH 0]: 4115 2056 1028
chan_data [CH 0]: 4115 2056 1028
benchmark [CH 0]: 5160 5121 2533
smooth [CH 0]: 5160 5122 2533
benchmark [CH 1]: 4644 2322 1160
chan_data [CH 1]: 4644 2322 1160
benchmark [CH 1]: 5007 5036 2464
smooth [CH 1]: 5007 5036 2464
benchmark [CH 2]: 4848 2423 1211
chan_data [CH 2]: 4848 2423 1211
benchmark [CH 2]: 5086 5056 2487
smooth [CH 2]: 5086 5056 2487
benchmark [CH 3]: 4337 2168 1084
chan_data [CH 3]: 4337 2168 1084
benchmark [CH 3]: 4964 4989 2433
smooth [CH 3]: 4964 4990 2433
=================================
benchmark [CH 0]: 4109 2054 1027
chan_data [CH 0]: 4109 2054 1027
benchmark [CH 0]: 5159 5121 2533
smooth [CH 0]: 5160 5121 2533
benchmark [CH 1]: 4638 2318 1158
chan_data [CH 1]: 4638 2318 1158
benchmark [CH 1]: 5005 5036 2464
smooth [CH 1]: 5006 5035 2464
benchmark [CH 2]: 4843 2421 1210
chan_data [CH 2]: 4845 2421 1210
benchmark [CH 2]: 5085 5056 2487
smooth [CH 2]: 5086 5056 2488
benchmark [CH 3]: 4334 2167 1084
chan_data [CH 3]: 4334 2167 1083
benchmark [CH 3]: 4964 4990 2433
smooth [CH 3]: 4964 4990 2433
...
```
@@ -77,46 +79,33 @@ And if you touch and release a button, you will see the following output:
```
...
I (1321) touch_callback: [CH 1] active
I (2861) touch_callback: [CH 0] active
=================================
benchmark [CH 0]: 4111 2055 1027
chan_data [CH 0]: 4111 2055 1027
benchmark [CH 0]: 5755 5425 2762
smooth [CH 0]: 5997 5666 2841
benchmark [CH 1]: 4676 2339 1168
chan_data [CH 1]: 17701 8798 4399
benchmark [CH 1]: 5025 5049 2473
smooth [CH 1]: 5025 5050 2473
benchmark [CH 2]: 4870 2434 1217
chan_data [CH 2]: 4867 2433 1217
benchmark [CH 2]: 5104 5066 2495
smooth [CH 2]: 5105 5066 2495
benchmark [CH 3]: 4333 2165 1082
chan_data [CH 3]: 4333 2165 1082
benchmark [CH 3]: 4982 5002 2441
smooth [CH 3]: 4982 5001 2441
I (3021) touch_callback: [CH 0] inactive
=================================
benchmark [CH 0]: 4109 2053 1027
chan_data [CH 0]: 4108 2053 1027
benchmark [CH 0]: 5756 5428 2763
smooth [CH 0]: 5756 5428 2764
benchmark [CH 1]: 4676 2339 1168
chan_data [CH 1]: 11256 8817 4363
benchmark [CH 1]: 5025 5048 2473
smooth [CH 1]: 5026 5048 2474
benchmark [CH 2]: 4868 2434 1217
chan_data [CH 2]: 4862 2429 1214
benchmark [CH 2]: 5104 5066 2495
smooth [CH 2]: 5104 5066 2495
benchmark [CH 3]: 4332 2165 1082
chan_data [CH 3]: 4330 2164 1081
I (1931) touch_callback: [CH 1] inactive
=================================
benchmark [CH 0]: 4106 2052 1026
chan_data [CH 0]: 4106 2052 1026
benchmark [CH 1]: 4649 2323 1161
chan_data [CH 1]: 4650 2323 1161
benchmark [CH 2]: 4847 2422 1211
chan_data [CH 2]: 4846 2422 1211
benchmark [CH 3]: 4329 2163 1082
chan_data [CH 3]: 4329 2164 1082
benchmark [CH 3]: 4981 5002 2441
smooth [CH 3]: 4981 5002 2441
...
```

View File

@@ -1,3 +1,2 @@
idf_component_register(SRCS "touch_sens_basic_example_main.c"
REQUIRES esp_driver_touch_sens
INCLUDE_DIRS ".")
REQUIRES esp_driver_touch_sens)

View File

@@ -0,0 +1,3 @@
dependencies:
touch_sens_examples_common:
path: ${IDF_PATH}/examples/peripherals/touch_sensor/touch_sens_examples_common

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: CC0-1.0
*/
@@ -12,13 +12,21 @@
#include "esp_check.h"
#include "touch_sens_example_config.h"
static touch_sensor_handle_t s_sens_handle = NULL;
static touch_channel_handle_t s_chan_handle[EXAMPLE_TOUCH_CHANNEL_NUM] = {};
// Touch version 3 supports multiple sample configurations (i.e. supports frequency hopping),
// others only have one set of sample configurations.
#define EXAMPLE_TOUCH_SAMPLE_CFG_NUM TOUCH_SAMPLE_CFG_NUM // Up to 'TOUCH_SAMPLE_CFG_NUM'
#define EXAMPLE_TOUCH_CHANNEL_NUM 4
#define EXAMPLE_TOUCH_CHAN_INIT_SCAN_TIMES 3
ESP_STATIC_ASSERT(EXAMPLE_TOUCH_SAMPLE_CFG_NUM <= TOUCH_SAMPLE_CFG_NUM, "sample configuration number exceed the supported number");
ESP_STATIC_ASSERT(EXAMPLE_TOUCH_CHANNEL_NUM <= (TOUCH_MAX_CHAN_ID - TOUCH_MIN_CHAN_ID + 1), "touch channel number exceed the max supported number ");
// Active threshold to benchmark ratio. (i.e., touch will be activated when data >= benchmark * (1 + ratio))
static float s_thresh2bm_ratio[EXAMPLE_TOUCH_CHANNEL_NUM] = {
[0 ... EXAMPLE_TOUCH_CHANNEL_NUM - 1] = 0.015f, // 1.5%
};
// The touch channel IDs that used in this example
// For the corresponding GPIOs of these channel, please refer to 'touch_sensor_channel.h'
static int s_channel_id[EXAMPLE_TOUCH_CHANNEL_NUM] = {
TOUCH_MIN_CHAN_ID,
TOUCH_MIN_CHAN_ID + 1,
@@ -38,50 +46,62 @@ bool example_touch_on_inactive_callback(touch_sensor_handle_t sens_handle, const
return false;
}
static void example_touch_do_initial_scanning(void)
static void example_touch_do_initial_scanning(touch_sensor_handle_t sens_handle, touch_channel_handle_t chan_handle[])
{
/* Enable the touch sensor to do the initial scanning, so that to initialize the channel data */
ESP_ERROR_CHECK(touch_sensor_enable(s_sens_handle));
ESP_ERROR_CHECK(touch_sensor_enable(sens_handle));
/* Scan the enabled touch channels for several times, to make sure the initial channel data is stable */
for (int i = 0; i < EXAMPLE_TOUCH_CHAN_INIT_SCAN_TIMES; i++) {
ESP_ERROR_CHECK(touch_sensor_trigger_oneshot_scanning(s_sens_handle, 2000));
ESP_ERROR_CHECK(touch_sensor_trigger_oneshot_scanning(sens_handle, 2000));
}
/* Disable the touch channel to rollback the state */
ESP_ERROR_CHECK(touch_sensor_disable(s_sens_handle));
ESP_ERROR_CHECK(touch_sensor_disable(sens_handle));
/* (Optional) Read the initial channel benchmark and reconfig the channel active threshold accordingly */
printf("Initial benchmark and new threshold are:\n");
for (int i = 0; i < EXAMPLE_TOUCH_CHANNEL_NUM; i++) {
/* Read the initial benchmark of the touch channel */
uint32_t benchmark[EXAMPLE_TOUCH_SAMPLE_CFG_NUM] = {};
ESP_ERROR_CHECK(touch_channel_read_data(s_chan_handle[i], TOUCH_CHAN_DATA_TYPE_BENCHMARK, benchmark));
#if SOC_TOUCH_SUPPORT_BENCHMARK
ESP_ERROR_CHECK(touch_channel_read_data(chan_handle[i], TOUCH_CHAN_DATA_TYPE_BENCHMARK, benchmark));
#else
/* Read smooth data instead if the touch V1 hardware does not support benchmark */
ESP_ERROR_CHECK(touch_channel_read_data(chan_handle[i], TOUCH_CHAN_DATA_TYPE_SMOOTH, benchmark));
#endif // SOC_TOUCH_SUPPORT_BENCHMARK
/* Calculate the proper active thresholds regarding the initial benchmark */
printf("[CH %d]", i);
printf("Touch [CH %d]", s_channel_id[i]);
/* Generate the default channel configuration and then update the active threshold based on the real benchmark */
touch_channel_config_t chan_cfg = EXAMPLE_TOUCH_CHAN_CFG_DEFAULT();
for (int j = 0; j < EXAMPLE_TOUCH_SAMPLE_CFG_NUM; j++) {
#if SOC_TOUCH_SENSOR_VERSION == 1
// Touch V1 (ESP32) uses absolute threshold.
chan_cfg.abs_active_thresh[j] = (uint32_t)(benchmark[j] * (1 - s_thresh2bm_ratio[i]));
printf(" %d: %"PRIu32", %"PRIu32"\t", j, benchmark[j], chan_cfg.abs_active_thresh[j]);
#else
chan_cfg.active_thresh[j] = (uint32_t)(benchmark[j] * s_thresh2bm_ratio[i]);
printf(" %d: %"PRIu32", %"PRIu32"\t", j, benchmark[j], chan_cfg.active_thresh[j]);
#endif // SOC_TOUCH_SENSOR_VERSION == 1
}
printf("\n");
/* Update the channel configuration */
ESP_ERROR_CHECK(touch_sensor_reconfig_channel(s_chan_handle[i], &chan_cfg));
ESP_ERROR_CHECK(touch_sensor_reconfig_channel(chan_handle[i], &chan_cfg));
}
}
void app_main(void)
{
/* Use the default sample configurations */
touch_sensor_sample_config_t sample_cfg[EXAMPLE_TOUCH_SAMPLE_CFG_NUM] = EXAMPLE_TOUCH_SAMPLE_CFG_DEFAULT();
/* Allocate new touch controller handle */
/* Handles of touch sensor */
touch_sensor_handle_t sens_handle = NULL;
touch_channel_handle_t chan_handle[EXAMPLE_TOUCH_CHANNEL_NUM];
/* Step 1: Create a new touch sensor controller handle with default sample configuration */
touch_sensor_sample_config_t sample_cfg[TOUCH_SAMPLE_CFG_NUM] = EXAMPLE_TOUCH_SAMPLE_CFG_DEFAULT();
touch_sensor_config_t sens_cfg = TOUCH_SENSOR_DEFAULT_BASIC_CONFIG(EXAMPLE_TOUCH_SAMPLE_CFG_NUM, sample_cfg);
ESP_ERROR_CHECK(touch_sensor_new_controller(&sens_cfg, &s_sens_handle));
/* Configure the touch sensor filter */
touch_sensor_filter_config_t filter_cfg = TOUCH_SENSOR_DEFAULT_FILTER_CONFIG();
ESP_ERROR_CHECK(touch_sensor_config_filter(s_sens_handle, &filter_cfg));
ESP_ERROR_CHECK(touch_sensor_new_controller(&sens_cfg, &sens_handle));
/* Step 2: Create and enable the new touch channel handles with default configurations */
/** Following is about setting the touch channel active threshold of each sample configuration.
*
* @How to Determine:
@@ -89,7 +109,10 @@ void app_main(void)
* we need to run the touch app first to get the `benchmark` and the `smooth_data` that being touched.
*
* @Formula:
* threshold = benchmark * coeff, (coeff for example, 0.1%~20%)
* Touch V1 uses absolute threshold, and it has no benchmark, so you can use untouched smooth data instead:
* abs_active_thresh = benchmark * (1 - coeff), (coeff for example, 0.1%~20%)
* Touch V2/V3 uses relative threshold:
* active_thresh = benchmark * coeff, (coeff for example, 0.1%~20%)
* Please adjust the coeff to guarantee the threshold < smooth_data - benchmark
*
* @Typical Practice:
@@ -102,48 +125,55 @@ void app_main(void)
touch_channel_config_t chan_cfg = EXAMPLE_TOUCH_CHAN_CFG_DEFAULT();
/* Allocate new touch channel on the touch controller */
for (int i = 0; i < EXAMPLE_TOUCH_CHANNEL_NUM; i++) {
ESP_ERROR_CHECK(touch_sensor_new_channel(s_sens_handle, s_channel_id[i], &chan_cfg, &s_chan_handle[i]));
ESP_ERROR_CHECK(touch_sensor_new_channel(sens_handle, s_channel_id[i], &chan_cfg, &chan_handle[i]));
/* Display the touch channel corresponding GPIO number, you can also know from `touch_sensor_channel.h` */
touch_chan_info_t chan_info = {};
ESP_ERROR_CHECK(touch_sensor_get_channel_info(chan_handle[i], &chan_info));
printf("Touch [CH %d] enabled on GPIO%d\n", s_channel_id[i], chan_info.chan_gpio);
}
printf("=================================\n");
/* Do the initial scanning to initialize the touch channel data
/* Step 3: Confiture the default filter for the touch sensor (Note: Touch V1 uses software filter) */
touch_sensor_filter_config_t filter_cfg = TOUCH_SENSOR_DEFAULT_FILTER_CONFIG();
ESP_ERROR_CHECK(touch_sensor_config_filter(sens_handle, &filter_cfg));
/* Step 4: Do the initial scanning to initialize the touch channel data
* Without this step, the channel data in the first read will be invalid
*/
example_touch_do_initial_scanning();
example_touch_do_initial_scanning(sens_handle, chan_handle);
/* Register the touch sensor callbacks, here only take `active` and `deactivate` event for example */
/* Step 5: Register the touch sensor callbacks, here only take `active` and `inactive` event for example */
touch_event_callbacks_t callbacks = {
.on_active = example_touch_on_active_callback,
.on_inactive = example_touch_on_inactive_callback,
.on_measure_done = NULL,
.on_scan_done = NULL,
.on_timeout = NULL,
.on_proximity_meas_done = NULL,
};
ESP_ERROR_CHECK(touch_sensor_register_callbacks(s_sens_handle, &callbacks, NULL));
ESP_ERROR_CHECK(touch_sensor_register_callbacks(sens_handle, &callbacks, NULL));
/* Enable the touch sensor */
ESP_ERROR_CHECK(touch_sensor_enable(s_sens_handle));
/* Step 6: Enable the touch sensor */
ESP_ERROR_CHECK(touch_sensor_enable(sens_handle));
/* Start continuous scanning, you can also trigger oneshot scanning manually */
ESP_ERROR_CHECK(touch_sensor_start_continuous_scanning(s_sens_handle));
/* Step 7: Start continuous scanning, you can also trigger oneshot scanning manually */
ESP_ERROR_CHECK(touch_sensor_start_continuous_scanning(sens_handle));
uint32_t benchmark[EXAMPLE_TOUCH_SAMPLE_CFG_NUM] = {};
uint32_t chan_data[EXAMPLE_TOUCH_SAMPLE_CFG_NUM] = {};
/* Step8: Print the sampled data of each enabled touch channel */
uint32_t data[EXAMPLE_TOUCH_SAMPLE_CFG_NUM] = {};
while (1) {
printf("=================================\n");
for (int i = 0; i < EXAMPLE_TOUCH_CHANNEL_NUM; i++) {
#if SOC_TOUCH_SUPPORT_BENCHMARK
/* Read and print the benchmark of each sample configuration */
ESP_ERROR_CHECK(touch_channel_read_data(s_chan_handle[i], TOUCH_CHAN_DATA_TYPE_BENCHMARK, benchmark));
ESP_ERROR_CHECK(touch_channel_read_data(chan_handle[i], TOUCH_CHAN_DATA_TYPE_BENCHMARK, data));
printf("benchmark [CH %d]:", s_channel_id[i]);
for (int j = 0; j < EXAMPLE_TOUCH_SAMPLE_CFG_NUM; j++) {
printf(" %"PRIu32, benchmark[j]);
printf(" %"PRIu32, data[j]);
}
printf("\n");
#endif
/* Read and print the channel data of each sample configuration */
ESP_ERROR_CHECK(touch_channel_read_data(s_chan_handle[i], TOUCH_CHAN_DATA_TYPE_SMOOTH, chan_data));
printf("chan_data [CH %d]:", s_channel_id[i]);
ESP_ERROR_CHECK(touch_channel_read_data(chan_handle[i], TOUCH_CHAN_DATA_TYPE_SMOOTH, data));
printf("smooth [CH %d]:", s_channel_id[i]);
for (int j = 0; j < EXAMPLE_TOUCH_SAMPLE_CFG_NUM; j++) {
printf(" %"PRIu32, chan_data[j]);
printf(" %"PRIu32, data[j]);
}
printf("\n\n");
}

View File

@@ -1,54 +0,0 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: CC0-1.0
*/
#pragma once
#include "driver/touch_sens.h"
#include "esp_assert.h"
#ifdef __cplusplus
extern "C" {
#endif
// Touch version 3 supports multiple sample configurations
#define EXAMPLE_TOUCH_SAMPLE_CFG_NUM TOUCH_SAMPLE_CFG_NUM // Up to 'TOUCH_SAMPLE_CFG_NUM'
#define EXAMPLE_TOUCH_CHANNEL_NUM 4
#define EXAMPLE_TOUCH_CHAN_INIT_SCAN_TIMES 3
ESP_STATIC_ASSERT(EXAMPLE_TOUCH_SAMPLE_CFG_NUM <= TOUCH_SAMPLE_CFG_NUM, "sample configuration number exceed the supported number");
ESP_STATIC_ASSERT(EXAMPLE_TOUCH_CHANNEL_NUM <= (TOUCH_MAX_CHAN_ID - TOUCH_MIN_CHAN_ID + 1), "touch channel number exceed the max supported number ");
#if SOC_TOUCH_SENSOR_VERSION == 2
#define EXAMPLE_TOUCH_SAMPLE_CFG_DEFAULT() {TOUCH_SENSOR_V2_DEFAULT_SAMPLE_CONFIG(500, TOUCH_VOLT_LIM_L_0V5, TOUCH_VOLT_LIM_H_2V2)}
#define EXAMPLE_TOUCH_CHAN_CFG_DEFAULT() { \
.active_thresh = {2000}, \
.charge_speed = TOUCH_CHARGE_SPEED_7, \
.init_charge_volt = TOUCH_INIT_CHARGE_VOLT_LOW, \
}
#elif SOC_TOUCH_SENSOR_VERSION == 3
#define EXAMPLE_TOUCH_SAMPLE_CFG(res, cap, coarse_freq_tune, fine_freq_tune) { \
.div_num = 8, \
.charge_times = 500, \
.rc_filter_res = res, \
.rc_filter_cap = cap, \
.low_drv = fine_freq_tune, \
.high_drv = coarse_freq_tune, \
.bias_volt = 5, \
.bypass_shield_output = false, \
}
#define EXAMPLE_TOUCH_SAMPLE_CFG_DEFAULT() {EXAMPLE_TOUCH_SAMPLE_CFG(3, 29, 8, 3),\
EXAMPLE_TOUCH_SAMPLE_CFG(2, 88, 31, 7), \
EXAMPLE_TOUCH_SAMPLE_CFG(3, 10, 31, 7)}
#define EXAMPLE_TOUCH_CHAN_CFG_DEFAULT() { \
.active_thresh = {1000, 2500, 5000}, \
}
#else
#error "Target not supported"
#endif
#ifdef __cplusplus
}
#endif

View File

@@ -1,15 +1,16 @@
# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Unlicense OR CC0-1.0
import pytest
from pytest_embedded import Dut
@pytest.mark.esp32
@pytest.mark.esp32s2
@pytest.mark.esp32s3
@pytest.mark.esp32p4
@pytest.mark.generic
def test_touch_sens_v3(dut: Dut) -> None:
def test_touch_sens(dut: Dut) -> None:
dut.expect(r'Touch \[CH [0-9]+\] enabled on GPIO[0-9]+')
dut.expect_exact('Initial benchmark and new threshold are:')
dut.expect(r'\[CH [0-9]+\] 0: [0-9]+, [0-9]+')
dut.expect(r'benchmark \[CH [0-9]+\]: [0-9]+')
dut.expect(r'chan_data \[CH [0-9]+\]: [0-9]+')
dut.expect(r'Touch \[CH [0-9]+\] 0: [0-9]+, [0-9]+')
dut.expect(r'smooth \[CH [0-9]+\]: [0-9]+')

View File

@@ -0,0 +1,2 @@
# register I2S common dependencies as a component
idf_component_register(INCLUDE_DIRS ".")

View File

@@ -0,0 +1,43 @@
/*
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: CC0-1.0
*/
#pragma once
#include "driver/touch_sens.h"
#ifdef __cplusplus
extern "C" {
#endif
#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32
#define EXAMPLE_TOUCH_SAMPLE_CFG_DEFAULT() {TOUCH_SENSOR_V1_DEFAULT_SAMPLE_CONFIG(5.0, TOUCH_VOLT_LIM_L_0V5, TOUCH_VOLT_LIM_H_1V7)}
#define EXAMPLE_TOUCH_CHAN_CFG_DEFAULT() { \
.abs_active_thresh = {1000}, \
.charge_speed = TOUCH_CHARGE_SPEED_7, \
.init_charge_volt = TOUCH_INIT_CHARGE_VOLT_LOW, \
.group = TOUCH_CHAN_TRIG_GROUP_BOTH, \
}
#elif SOC_TOUCH_SENSOR_VERSION == 2 // ESP32-S2 & ESP32-S3
#define EXAMPLE_TOUCH_SAMPLE_CFG_DEFAULT() {TOUCH_SENSOR_V2_DEFAULT_SAMPLE_CONFIG(500, TOUCH_VOLT_LIM_L_0V5, TOUCH_VOLT_LIM_H_2V2)}
#define EXAMPLE_TOUCH_CHAN_CFG_DEFAULT() { \
.active_thresh = {2000}, \
.charge_speed = TOUCH_CHARGE_SPEED_7, \
.init_charge_volt = TOUCH_INIT_CHARGE_VOLT_LOW, \
}
#elif SOC_TOUCH_SENSOR_VERSION == 3 // ESP32-P4
#define EXAMPLE_TOUCH_SAMPLE_CFG_DEFAULT() {TOUCH_SENSOR_V3_DEFAULT_SAMPLE_CONFIG2(3, 29, 8, 3),\
TOUCH_SENSOR_V3_DEFAULT_SAMPLE_CONFIG2(2, 88, 31, 7), \
TOUCH_SENSOR_V3_DEFAULT_SAMPLE_CONFIG2(3, 10, 31, 7)}
#define EXAMPLE_TOUCH_CHAN_CFG_DEFAULT() { \
.active_thresh = {1000, 2500, 5000}, \
}
#else
#error "Target not supported"
#endif
#ifdef __cplusplus
}
#endif

View File

@@ -1,8 +0,0 @@
# The following lines of boilerplate have to be in your project's CMakeLists
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
# "Trim" the build. Include the minimal set of components, main, and anything it depends on.
idf_build_set_property(MINIMAL_BUILD ON)
project(touch_pad_interrupt)

View File

@@ -1,65 +0,0 @@
| Supported Targets | ESP32 |
| ----------------- | ----- |
# Touch Pad Interrupt Example
(See the README.md file in the upper level 'examples' directory for more information about examples.)
This example demonstrates how to set up ESP32's capacitive touch pad peripheral to trigger interrupt when a pad is touched. It also shows how to detect the touch event by software for sensor designs where greater touch detection sensitivity is required.
- The hardware interrupt mode occupies less CPU resources, but we can only apply fixed threshold and software algorithms are also impossibile.
- The polling mode is flexible and supports various software algorithms. However, it comsumes more CPU.
ESP32 supports touch detection by configuring hardware registers. The hardware periodically detects the pulse counts. If the number of pulse counts exceeds the set threshold, a hardware interrupt will be generated to notify the application layer that a certain touch sensor channel may be triggered.
For the sensors covered with glass or plastic, the capacitance difference caused by a touch action could be very small. In such cases, software polling is used so software algorithms can be applied to reduce noise and catch small changes of the pulse counts. In certain cases, we may need to add additional routines to adjust the threshold level dynamically as it may change depending on environment conditions.
For a simpler example how to configure and read capacitive touch pads, please refer to [touch_pad_read](../touch_pad_read).
## How to use example
### Hardware Required
* A development board with ESP32 chip
* Proper touch sensor system
For hardware and firmware design guidelines on ESP32 touch sensor system, please refer to [Touch Sensor Application Note](https://github.com/espressif/esp-iot-solution/blob/release/v1.1/documents/touch_pad_solution/touch_sensor_design_en.md), where you may find comprehensive information on how to design and implement touch sensing applications, such as linear slider, wheel slider, matrix buttons and spring buttons.
### Build and Flash
Build the project and flash it to the board, then run monitor tool to view serial output:
```
idf.py -p PORT flash monitor
```
(Replace PORT with the name of the serial port to use.)
(To exit the serial monitor, type ``Ctrl-]``.)
See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
## Example Output
The application cycles between the interrupt mode and the pooling mode with a filter, to compare performance of the touch sensor system between both scenarios:
```
I (6303) Touch pad: Waiting for any pad being touched...
I (6733) Touch pad: T6 activated!
I (7333) Touch pad: T5 activated!
I (7723) Touch pad: T3 activated!
I (8043) Touch pad: T2 activated!
I (8883) Touch pad: T4 activated!
I (9523) Touch pad: T7 activated!
I (12503) Touch pad: Waiting for any pad being touched...
I (15483) Touch pad: T6 activated!
I (16253) Touch pad: T5 activated!
I (17903) Touch pad: Waiting for any pad being touched...
I (22903) Touch pad: Waiting for any pad being touched...
```
## Troubleshooting
Sensing threshold is set up automatically at start up by performing simple calibration. Application is reading current value for each pad and assuming two thirds of this value as the sensing threshold. Do not touch pads on application start up, otherwise sensing may not work correctly.
For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon.

View File

@@ -1,3 +0,0 @@
idf_component_register(SRCS "tp_interrupt_main.c"
PRIV_REQUIRES driver
INCLUDE_DIRS ".")

View File

@@ -1,169 +0,0 @@
/*
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: CC0-1.0
*/
#include <stdio.h>
#include <inttypes.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "esp_log.h"
#include "driver/touch_pad.h"
#include "soc/rtc_periph.h"
static const char *TAG = "Touch pad";
#define TOUCH_THRESH_NO_USE (0)
#define TOUCH_THRESH_PERCENT (80)
#define TOUCHPAD_FILTER_TOUCH_PERIOD (10)
static bool s_pad_activated[TOUCH_PAD_MAX];
static uint32_t s_pad_init_val[TOUCH_PAD_MAX];
/*
Read values sensed at all available touch pads.
Use 2 / 3 of read value as the threshold
to trigger interrupt when the pad is touched.
Note: this routine demonstrates a simple way
to configure activation threshold for the touch pads.
Do not touch any pads when this routine
is running (on application start).
*/
static void tp_example_set_thresholds(void)
{
uint16_t touch_value;
for (int i = 0; i < TOUCH_PAD_MAX; i++) {
//read filtered value
touch_pad_read_filtered(i, &touch_value);
s_pad_init_val[i] = touch_value;
ESP_LOGI(TAG, "test init: touch pad [%d] val is %d", i, touch_value);
//set interrupt threshold.
ESP_ERROR_CHECK(touch_pad_set_thresh(i, touch_value * 2 / 3));
}
}
/*
Check if any of touch pads has been activated
by reading a table updated by rtc_intr()
If so, then print it out on a serial monitor.
Clear related entry in the table afterwards
In interrupt mode, the table is updated in touch ISR.
In filter mode, we will compare the current filtered value with the initial one.
If the current filtered value is less than 80% of the initial value, we can
regard it as a 'touched' event.
When calling touch_pad_init, a timer will be started to run the filter.
This mode is designed for the situation that the pad is covered
by a 2-or-3-mm-thick medium, usually glass or plastic.
The difference caused by a 'touch' action could be very small, but we can still use
filter mode to detect a 'touch' event.
*/
static void tp_example_read_task(void *pvParameter)
{
static int show_message;
int change_mode = 0;
int filter_mode = 0;
while (1) {
if (filter_mode == 0) {
//interrupt mode, enable touch interrupt
touch_pad_intr_enable();
for (int i = 0; i < TOUCH_PAD_MAX; i++) {
if (s_pad_activated[i] == true) {
ESP_LOGI(TAG, "T%d activated!", i);
// Wait a while for the pad being released
vTaskDelay(200 / portTICK_PERIOD_MS);
// Clear information on pad activation
s_pad_activated[i] = false;
// Reset the counter triggering a message
// that application is running
show_message = 1;
}
}
} else {
//filter mode, disable touch interrupt
touch_pad_intr_disable();
touch_pad_clear_status();
for (int i = 0; i < TOUCH_PAD_MAX; i++) {
uint16_t value = 0;
touch_pad_read_filtered(i, &value);
if (value < s_pad_init_val[i] * TOUCH_THRESH_PERCENT / 100) {
ESP_LOGI(TAG, "T%d activated!", i);
ESP_LOGI(TAG, "value: %"PRIu16"; init val: %"PRIu32, value, s_pad_init_val[i]);
vTaskDelay(200 / portTICK_PERIOD_MS);
// Reset the counter to stop changing mode.
change_mode = 1;
show_message = 1;
}
}
}
vTaskDelay(10 / portTICK_PERIOD_MS);
// If no pad is touched, every couple of seconds, show a message
// that application is running
if (show_message++ % 500 == 0) {
ESP_LOGI(TAG, "Waiting for any pad being touched...");
}
// Change mode if no pad is touched for a long time.
// We can compare the two different mode.
if (change_mode++ % 2000 == 0) {
filter_mode = !filter_mode;
ESP_LOGW(TAG, "Change mode...%s", filter_mode == 0 ? "interrupt mode" : "filter mode");
}
}
}
/*
Handle an interrupt triggered when a pad is touched.
Recognize what pad has been touched and save it in a table.
*/
static void tp_example_rtc_intr(void *arg)
{
uint32_t pad_intr = touch_pad_get_status();
//clear interrupt
touch_pad_clear_status();
for (int i = 0; i < TOUCH_PAD_MAX; i++) {
if ((pad_intr >> i) & 0x01) {
s_pad_activated[i] = true;
}
}
}
/*
* Before reading touch pad, we need to initialize the RTC IO.
*/
static void tp_example_touch_pad_init(void)
{
for (int i = 0; i < TOUCH_PAD_MAX; i++) {
//init RTC IO and mode for touch pad.
touch_pad_config(i, TOUCH_THRESH_NO_USE);
}
}
void app_main(void)
{
// Initialize touch pad peripheral, it will start a timer to run a filter
ESP_LOGI(TAG, "Initializing touch pad");
ESP_ERROR_CHECK(touch_pad_init());
// If use interrupt trigger mode, should set touch sensor FSM mode at 'TOUCH_FSM_MODE_TIMER'.
touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER);
// Set reference voltage for charging/discharging
// For most usage scenarios, we recommend using the following combination:
// the high reference valtage will be 2.7V - 1V = 1.7V, The low reference voltage will be 0.5V.
touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_1V);
// Init touch pad IO
tp_example_touch_pad_init();
// Initialize and start a software filter to detect slight change of capacitance.
touch_pad_filter_start(TOUCHPAD_FILTER_TOUCH_PERIOD);
// Set thresh hold
tp_example_set_thresholds();
// Register touch interrupt ISR
touch_pad_isr_register(tp_example_rtc_intr, NULL);
// Start a task to show what pads have been touched
xTaskCreate(&tp_example_read_task, "touch_pad_read_task", 4096, NULL, 5, NULL);
}

View File

@@ -1,14 +0,0 @@
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Unlicense OR CC0-1.0
import pytest
from pytest_embedded import Dut
@pytest.mark.esp32
@pytest.mark.generic
def test_touch_pad_interrupt_v1(dut: Dut) -> None:
dut.expect_exact('Touch pad: Initializing touch pad')
dut.expect(r'test init: touch pad \[\d+\] val is \d+')
dut.expect_exact('Touch pad: Waiting for any pad being touched...')
dut.expect_exact('Touch pad: Change mode...filter mode')
dut.expect_exact('Touch pad: Waiting for any pad being touched...')

View File

@@ -1,8 +0,0 @@
# The following lines of boilerplate have to be in your project's CMakeLists
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
# "Trim" the build. Include the minimal set of components, main, and anything it depends on.
idf_build_set_property(MINIMAL_BUILD ON)
project(touch_pad_read)

View File

@@ -1,55 +0,0 @@
| Supported Targets | ESP32 |
| ----------------- | ----- |
# Touch Pad Read Example
(See the README.md file in the upper level 'examples' directory for more information about examples.)
Read and print raw values or IIR filtered values from capacitive touch sensors.
Once configured, ESP32 will continuously measure capacitance of touch pad sensors. Measurement is reflected as numeric value inversely related to sensor's capacitance. With a finger touched on a pad, its capacitance will get larger meanwhile the measured value gets smaller, and vice versa.
To detect if a sensor is touched or not, each particular design should be calibrated by obtaining both measurements for each individual sensor. Then a threshold between both values can be established. With specific threshold, API is then able to distinguish whether specific sensor is touched or released.
There is another similar example that demonstrates how to perform simple calibration and trigger an interrupt when a pad is touched - see [touch_pad_interrupt](../touch_pad_interrupt).
## How to use example
### Hardware Required
* A development board with ESP32 chip
* Proper touch sensor system
For hardware and firmware design guidelines on ESP32 touch sensor system, please refer to [Touch Sensor Application Note](https://github.com/espressif/esp-iot-solution/blob/release/v1.1/documents/touch_pad_solution/touch_sensor_design_en.md), where you may find comprehensive information on how to design and implement touch sensing applications, such as linear slider, wheel slider, matrix buttons and spring buttons.
### Build and Flash
Build the project and flash it to the board, then run monitor tool to view serial output:
```
idf.py -p PORT flash monitor
```
(Replace PORT with the name of the serial port to use.)
(To exit the serial monitor, type ``Ctrl-]``.)
See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
## Example Output
ESP32 supports up to ten capacitive touch pad sensors, T0 - T9, which are connected to specific GPIO pins. For the information about touch sensor capable pins, please refer to [Technical Reference Manual](https://espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf). This example will initialize all the 10 touch pads, and print the measured values to serial terminal:
```
Touch Sensor filter mode read, the output format is:
Touchpad num:[raw data, filtered data]
T0:[1072,1071] T1:[ 475, 475] T2:[1004,1003] T3:[1232,1231] T4:[1675,1676] T5:[1146,1146] T6:[1607,1607] T7:[1118,1118] T8:[1695,1695] T9:[1223,1222]
T0:[1072,1071] T1:[ 475, 475] T2:[1003,1003] T3:[1231,1231] T4:[1676,1676] T5:[1146,1146] T6:[1607,1607] T7:[1118,1118] T8:[1694,1694] T9:[1222,1221]
T0:[1071,1071] T1:[ 475, 475] T2:[1004,1004] T3:[1231,1231] T4:[1678,1677] T5:[1147,1146] T6:[1607,1607] T7:[1118,1118] T8:[1694,1694] T9:[1222,1221]
```
## Troubleshooting
For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon.

View File

@@ -1,3 +0,0 @@
idf_component_register(SRCS "tp_read_main.c"
PRIV_REQUIRES driver
INCLUDE_DIRS ".")

View File

@@ -1,71 +0,0 @@
/*
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: CC0-1.0
*/
#include <stdio.h>
#include <inttypes.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/touch_pad.h"
#include "esp_log.h"
#define TOUCH_PAD_NO_CHANGE (-1)
#define TOUCH_THRESH_NO_USE (0)
#define TOUCH_FILTER_MODE_EN (1)
#define TOUCHPAD_FILTER_TOUCH_PERIOD (10)
/*
Read values sensed at all available touch pads.
Print out values in a loop on a serial monitor.
*/
static void tp_example_read_task(void *pvParameter)
{
uint16_t touch_value;
uint16_t touch_filter_value;
#if TOUCH_FILTER_MODE_EN
printf("Touch Sensor filter mode read, the output format is: \nTouchpad num:[raw data, filtered data]\n\n");
#else
printf("Touch Sensor normal mode read, the output format is: \nTouchpad num:[raw data]\n\n");
#endif
while (1) {
for (int i = 0; i < TOUCH_PAD_MAX; i++) {
#if TOUCH_FILTER_MODE_EN
// If open the filter mode, please use this API to get the touch pad count.
touch_pad_read_raw_data(i, &touch_value);
touch_pad_read_filtered(i, &touch_filter_value);
printf("T%d:[%4"PRIu16",%4"PRIu16"] ", i, touch_value, touch_filter_value);
#else
touch_pad_read(i, &touch_value);
printf("T%d:[%4"PRIu16"] ", i, touch_value);
#endif
}
printf("\n");
vTaskDelay(200 / portTICK_PERIOD_MS);
}
}
static void tp_example_touch_pad_init(void)
{
for (int i = 0; i < TOUCH_PAD_MAX; i++) {
touch_pad_config(i, TOUCH_THRESH_NO_USE);
}
}
void app_main(void)
{
// Initialize touch pad peripheral.
// The default fsm mode is software trigger mode.
ESP_ERROR_CHECK(touch_pad_init());
// Set reference voltage for charging/discharging
// In this case, the high reference valtage will be 2.7V - 1V = 1.7V
// The low reference voltage will be 0.5
// The larger the range, the larger the pulse count value.
touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_1V);
tp_example_touch_pad_init();
#if TOUCH_FILTER_MODE_EN
touch_pad_filter_start(TOUCHPAD_FILTER_TOUCH_PERIOD);
#endif
// Start task to read values sensed by pads
xTaskCreate(&tp_example_read_task, "touch_pad_read_task", 4096, NULL, 5, NULL);
}

View File

@@ -1,12 +0,0 @@
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Unlicense OR CC0-1.0
import pytest
from pytest_embedded import Dut
@pytest.mark.esp32
@pytest.mark.generic
def test_touch_pad_read_v1(dut: Dut) -> None:
dut.expect_exact('Touch Sensor filter mode read, the output format is:')
dut.expect(r'T0:\[\s*\d+,\s*\d+\] T1:\[\s*\d+,\s*\d+\] T2:\[\s*\d+,\s*\d+\] T3:\[\s*\d+,\s*\d+\] T4:\[\s*\d+,\s*\d+\]'
r' T5:\[\s*\d+,\s*\d+\] T6:\[\s*\d+,\s*\d+\] T7:\[\s*\d+,\s*\d+\] T8:\[\s*\d+,\s*\d+\] T9:\[\s*\d+,\s*\d+\]')

View File

@@ -1,6 +1,12 @@
idf_component_register(SRCS "deep_sleep_example_main.c"
set(srcs "deep_sleep_example_main.c"
"gpio_wakeup.c"
"ext_wakeup.c"
"touch_wakeup.c"
PRIV_REQUIRES driver nvs_flash ulp
INCLUDE_DIRS ".")
"ext_wakeup.c")
set(includes ".")
if(CONFIG_SOC_TOUCH_SENSOR_SUPPORTED AND CONFIG_SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP)
list(APPEND srcs "touch_sens_wakeup.c")
endif()
idf_component_register(SRCS ${srcs}
PRIV_REQUIRES nvs_flash ulp esp_driver_gpio esp_driver_touch_sens
INCLUDE_DIRS ${includes})

View File

@@ -3,11 +3,12 @@ menu "Example Configuration"
config EXAMPLE_TOUCH_WAKEUP
bool "Enable touch wake up"
default y
depends on SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP && !IDF_TARGET_ESP32P4
depends on SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP && SOC_TOUCH_SENSOR_SUPPORTED
help
This option enables wake up from deep sleep using touch pads.
ESP32 - TOUCH8 and TOUCH9, which correspond to GPIO33 and GPIO32.
ESP32S2/S3 - TOUCH9, which corresponds to GPIO9.
ESP32P4 - TOUCH2, which corresponds to GPIO4.
Note: On ESP32, touch wakeup source can not be used together with ext0 wakeup source.
@@ -284,4 +285,18 @@ menu "Example Configuration"
supported. If this option is enabled, it is a high level wake up, otherwise it is a low level wake up.
endmenu
menu "Touch wakeup configuration"
visible if EXAMPLE_TOUCH_WAKEUP
config EXAMPLE_TOUCH_ALLOW_DSLP_PD
bool "Allow RTC_PERIPH power domain to be powered down during deep sleep"
depends on !IDF_TARGET_ESP32
default y
help
Enable this option if allow the RTC_PERIPH power domain (contain touch sensor) to be powered down
during deep sleep. It can help to save more power, but only one specified touch channel can wakeup
from the deep sleep. If this option is disabled, the RTC_PERIPH power domain will be powered up
during deep sleep, and all enabled touch channels can wakeup from the deep sleep.
endmenu
endmenu

View File

@@ -100,7 +100,7 @@ static void deep_sleep_task(void *args)
#ifdef CONFIG_EXAMPLE_TOUCH_WAKEUP
case ESP_SLEEP_WAKEUP_TOUCHPAD: {
printf("Wake up from touch on pad %d\n", esp_sleep_get_touchpad_wakeup_status());
printf("Wake up from touch\n");
break;
}
#endif // CONFIG_EXAMPLE_TOUCH_WAKEUP

View File

@@ -0,0 +1,3 @@
dependencies:
touch_sens_examples_common:
path: ${IDF_PATH}/examples/peripherals/touch_sensor/touch_sens_examples_common

View File

@@ -0,0 +1,148 @@
/*
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "esp_log.h"
#include "driver/touch_sens.h"
#include "touch_sens_example_config.h"
static const char *TAG = "touch_wakeup";
#define EXAMPLE_TOUCH_SAMPLE_CFG_NUM 1
#define EXAMPLE_TOUCH_CHANNEL_NUM 3
#define EXAMPLE_TOUCH_CHAN_INIT_SCAN_TIMES 3
// The touch channel IDs that used in this example
// If you want to change the wake-up channels, please make sure the channel GPIOs won't conflict to the EXT wakeup GPIOs
static int s_channel_id[EXAMPLE_TOUCH_CHANNEL_NUM] = {7, 8, 9};
// Active threshold to benchmark ratio. (i.e., touch will be activated when data >= benchmark * (1 + ratio))
static float s_thresh2bm_ratio[EXAMPLE_TOUCH_CHANNEL_NUM] = {
[0 ... EXAMPLE_TOUCH_CHANNEL_NUM - 1] = 0.02f, // 2%
};
static bool example_touch_on_active_cb(touch_sensor_handle_t sens_handle, const touch_active_event_data_t *event, void *user_ctx)
{
ESP_EARLY_LOGW("touch callback", "ch %d active", (int)event->chan_id);
return false;
}
static bool example_touch_on_inactive_cb(touch_sensor_handle_t sens_handle, const touch_inactive_event_data_t *event, void *user_ctx)
{
ESP_EARLY_LOGW("touch callback", "ch %d inactive", (int)event->chan_id);
return false;
}
static void example_touch_do_initial_scanning(touch_sensor_handle_t sens_handle, touch_channel_handle_t chan_handle[])
{
/* Enable the touch sensor to do the initial scanning, so that to initialize the channel data */
ESP_ERROR_CHECK(touch_sensor_enable(sens_handle));
/* Scan the enabled touch channels for several times, to make sure the initial channel data is stable */
for (int i = 0; i < EXAMPLE_TOUCH_CHAN_INIT_SCAN_TIMES; i++) {
ESP_ERROR_CHECK(touch_sensor_trigger_oneshot_scanning(sens_handle, 2000));
}
/* Disable the touch channel to rollback the state */
ESP_ERROR_CHECK(touch_sensor_disable(sens_handle));
/* (Optional) Read the initial channel benchmark and reconfig the channel active threshold accordingly */
printf("Initial benchmark and new threshold are:\n");
for (int i = 0; i < EXAMPLE_TOUCH_CHANNEL_NUM; i++) {
/* Read the initial benchmark of the touch channel */
uint32_t benchmark[EXAMPLE_TOUCH_SAMPLE_CFG_NUM] = {};
#if SOC_TOUCH_SUPPORT_BENCHMARK
ESP_ERROR_CHECK(touch_channel_read_data(chan_handle[i], TOUCH_CHAN_DATA_TYPE_BENCHMARK, benchmark));
#else
/* Read smooth data instead if the hardware does not support benchmark */
ESP_ERROR_CHECK(touch_channel_read_data(chan_handle[i], TOUCH_CHAN_DATA_TYPE_SMOOTH, benchmark));
#endif // SOC_TOUCH_SUPPORT_BENCHMARK
/* Calculate the proper active thresholds regarding the initial benchmark */
printf("Touch [CH %d]", s_channel_id[i]);
/* Generate the default channel configuration and then update the active threshold based on the real benchmark */
touch_channel_config_t chan_cfg = EXAMPLE_TOUCH_CHAN_CFG_DEFAULT();
for (int j = 0; j < EXAMPLE_TOUCH_SAMPLE_CFG_NUM; j++) {
#if SOC_TOUCH_SENSOR_VERSION == 1
// Touch V1 (ESP32) uses absolute threshold.
chan_cfg.abs_active_thresh[j] = (uint32_t)(benchmark[j] * (1 - s_thresh2bm_ratio[i]));
printf(" %d: %"PRIu32", %"PRIu32"\t", j, benchmark[j], chan_cfg.abs_active_thresh[j]);
#else
chan_cfg.active_thresh[j] = (uint32_t)(benchmark[j] * s_thresh2bm_ratio[i]);
printf(" %d: %"PRIu32", %"PRIu32"\t", j, benchmark[j], chan_cfg.active_thresh[j]);
#endif // SOC_TOUCH_SENSOR_VERSION == 1
}
printf("\n");
/* Update the channel configuration */
ESP_ERROR_CHECK(touch_sensor_reconfig_channel(chan_handle[i], &chan_cfg));
}
}
esp_err_t example_deep_sleep_register_touch_wakeup(void)
{
printf("Enabling touch wakeup\n");
/* Handles of touch sensor */
touch_sensor_handle_t sens_handle = NULL;
touch_channel_handle_t chan_handle[EXAMPLE_TOUCH_CHANNEL_NUM];
/* Step 1: Create a new touch sensor controller handle with default sample configuration */
touch_sensor_sample_config_t sample_cfg[TOUCH_SAMPLE_CFG_NUM] = EXAMPLE_TOUCH_SAMPLE_CFG_DEFAULT();
touch_sensor_config_t sens_cfg = TOUCH_SENSOR_DEFAULT_BASIC_CONFIG(EXAMPLE_TOUCH_SAMPLE_CFG_NUM, sample_cfg);
ESP_ERROR_CHECK(touch_sensor_new_controller(&sens_cfg, &sens_handle));
/* Step 2: Create and enable the new touch channel handles with default configurations */
touch_channel_config_t chan_cfg = EXAMPLE_TOUCH_CHAN_CFG_DEFAULT();
for (int i = 0; i < EXAMPLE_TOUCH_CHANNEL_NUM; i++) {
ESP_ERROR_CHECK(touch_sensor_new_channel(sens_handle, s_channel_id[i], &chan_cfg, &chan_handle[i]));
/* Display the touch channel corresponding GPIO number, you can also know from `touch_sensor_channel.h` */
touch_chan_info_t chan_info = {};
ESP_ERROR_CHECK(touch_sensor_get_channel_info(chan_handle[i], &chan_info));
printf("Touch [CH %d] enabled on GPIO%d\n", s_channel_id[i], chan_info.chan_gpio);
}
/* Step 3: Confiture the default filter for the touch sensor (Note: Touch V1 uses software filter) */
touch_sensor_filter_config_t filter_cfg = TOUCH_SENSOR_DEFAULT_FILTER_CONFIG();
ESP_ERROR_CHECK(touch_sensor_config_filter(sens_handle, &filter_cfg));
/* (Optional) Do the initial scanning to initialize the touch channel data
* Without this step, the channel data in the first read will be invalid
*/
example_touch_do_initial_scanning(sens_handle, chan_handle);
/* (Optional) Register the callbacks, optional for deep sleep wakeup */
touch_event_callbacks_t callbacks = {
.on_active = example_touch_on_active_cb,
.on_inactive = example_touch_on_inactive_cb,
};
ESP_ERROR_CHECK(touch_sensor_register_callbacks(sens_handle, &callbacks, NULL));
/* Step 4: Enable the deep sleep wake-up with the basic configuration */
#if CONFIG_EXAMPLE_TOUCH_ALLOW_DSLP_PD
/* Get the channel information to use same active threshold for the sleep channel */
touch_chan_info_t chan_info = {};
ESP_ERROR_CHECK(touch_sensor_get_channel_info(chan_handle[0], &chan_info));
touch_sleep_config_t deep_slp_cfg = TOUCH_SENSOR_DEFAULT_DSLP_PD_CONFIG(chan_handle[0],
chan_info.active_thresh[0],
#if SOC_TOUCH_SENSOR_VERSION == 3
chan_info.active_thresh[1],
chan_info.active_thresh[2],
#endif
);
printf("Touch channel %d (GPIO%d) is selected as deep sleep wakeup channel\n", chan_info.chan_id, chan_info.chan_gpio);
#else
touch_sleep_config_t deep_slp_cfg = TOUCH_SENSOR_DEFAULT_DSLP_CONFIG();
#endif
/* Enable deep sleep wake up for touch sensor */
ESP_ERROR_CHECK(touch_sensor_config_sleep_wakeup(sens_handle, &deep_slp_cfg));
/* Step 5: Enable touch sensor controller and start continuous scanning before entering deep sleep */
ESP_ERROR_CHECK(touch_sensor_enable(sens_handle));
ESP_ERROR_CHECK(touch_sensor_start_continuous_scanning(sens_handle));
ESP_LOGI(TAG, "touch wakeup source is ready");
return ESP_OK;
}

View File

@@ -1,111 +0,0 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include <stdio.h>
#include <inttypes.h>
#include "esp_sleep.h"
#include "sdkconfig.h"
#include "driver/rtc_io.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#ifdef CONFIG_EXAMPLE_TOUCH_WAKEUP
#include "driver/touch_pad.h"
#if CONFIG_IDF_TARGET_ESP32
#define TOUCH_THRESH_NO_USE 0
static void calibrate_touch_pad(touch_pad_t pad)
{
int avg = 0;
const size_t calibration_count = 128;
for (int i = 0; i < calibration_count; ++i) {
uint16_t val;
touch_pad_read(pad, &val);
avg += val;
}
avg /= calibration_count;
const int min_reading = 300;
if (avg < min_reading) {
printf("Touch pad #%d average reading is too low: %d (expecting at least %d). "
"Not using for deep sleep wakeup.\n", pad, avg, min_reading);
touch_pad_config(pad, 0);
} else {
int threshold = avg - 100;
printf("Touch pad #%d average: %d, wakeup threshold set to %d.\n", pad, avg, threshold);
touch_pad_config(pad, threshold);
}
}
#endif
void example_deep_sleep_register_touch_wakeup(void)
{
#if CONFIG_IDF_TARGET_ESP32
// Initialize touch pad peripheral.
// The default fsm mode is software trigger mode.
ESP_ERROR_CHECK(touch_pad_init());
// If use touch pad wake up, should set touch sensor FSM mode at 'TOUCH_FSM_MODE_TIMER'.
touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER);
// Set reference voltage for charging/discharging
// In this case, the high reference voltage will be 2.4V - 1V = 1.4V
// The low reference voltage will be 0.5
// The larger the range, the larger the pulse count value.
touch_pad_set_voltage(TOUCH_HVOLT_2V4, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_1V);
//init RTC IO and mode for touch pad.
touch_pad_config(TOUCH_PAD_NUM8, TOUCH_THRESH_NO_USE);
touch_pad_config(TOUCH_PAD_NUM9, TOUCH_THRESH_NO_USE);
calibrate_touch_pad(TOUCH_PAD_NUM8);
calibrate_touch_pad(TOUCH_PAD_NUM9);
#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
/* Initialize touch pad peripheral. */
touch_pad_init();
/* Only support one touch channel in sleep mode. */
touch_pad_config(TOUCH_PAD_NUM9);
/* Denoise setting at TouchSensor 0. */
touch_pad_denoise_t denoise = {
/* The bits to be cancelled are determined according to the noise level. */
.grade = TOUCH_PAD_DENOISE_BIT4,
.cap_level = TOUCH_PAD_DENOISE_CAP_L4,
};
touch_pad_denoise_set_config(&denoise);
touch_pad_denoise_enable();
printf("Denoise function init\n");
/* Filter setting */
touch_filter_config_t filter_info = {
.mode = TOUCH_PAD_FILTER_IIR_16,
.debounce_cnt = 1, // 1 time count.
.noise_thr = 0, // 50%
.jitter_step = 4, // use for jitter mode.
.smh_lvl = TOUCH_PAD_SMOOTH_IIR_2,
};
touch_pad_filter_set_config(&filter_info);
touch_pad_filter_enable();
printf("touch pad filter init %d\n", TOUCH_PAD_FILTER_IIR_8);
/* Set sleep touch pad. */
touch_pad_sleep_channel_enable(TOUCH_PAD_NUM9, true);
touch_pad_sleep_channel_enable_proximity(TOUCH_PAD_NUM9, false);
/* Reducing the operating frequency can effectively reduce power consumption. */
touch_pad_sleep_channel_set_work_time(1000, TOUCH_PAD_MEASURE_CYCLE_DEFAULT);
/* Enable touch sensor clock. Work mode is "timer trigger". */
touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER);
touch_pad_fsm_start();
vTaskDelay(100 / portTICK_PERIOD_MS);
/* set touchpad wakeup threshold */
uint32_t touch_value, wake_threshold;
touch_pad_sleep_channel_read_smooth(TOUCH_PAD_NUM9, &touch_value);
wake_threshold = touch_value * 0.1; // wakeup when touch sensor crosses 10% of background level
touch_pad_sleep_set_threshold(TOUCH_PAD_NUM9, wake_threshold);
printf("Touch pad #%d average: %"PRIu32", wakeup threshold set to %"PRIu32"\n",
TOUCH_PAD_NUM9, touch_value, (uint32_t)(touch_value * 0.1));
#endif
printf("Enabling touch pad wakeup\n");
ESP_ERROR_CHECK(esp_sleep_enable_touchpad_wakeup());
#if SOC_PM_SUPPORT_RTC_PERIPH_PD
ESP_ERROR_CHECK(esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON));
#endif
}
#endif // CONFIG_EXAMPLE_TOUCH_WAKEUP

View File

@@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: CC0-1.0
import logging
import time
@@ -6,9 +6,6 @@ import time
import pytest
from pytest_embedded import Dut
touch_wake_up_support = ['esp32', 'esp32s2']
CONFIGS = [
pytest.param('esp32_singlecore', marks=[pytest.mark.esp32]),
pytest.param(
@@ -33,18 +30,12 @@ CONFIGS = [
@pytest.mark.generic
def test_deep_sleep(dut: Dut) -> None:
def expect_enable_deep_sleep_touch() -> None:
# different targets configure different wake pin(s)
wake_pads = {
'esp32': [8, 9],
'esp32s2': [9],
}[dut.target]
logging.info('Expecting to see wakeup configured on pad(s): {}'.format(wake_pads))
expect_items = ['Enabling timer wakeup, 20s']
for pad in wake_pads:
expect_items += [r'Touch pad #{} average: \d+, wakeup threshold set to \d+.'.format(pad)]
expect_items += ['Enabling touch pad wakeup']
expect_items += ['Enabling touch wakeup']
expect_items += [r'Touch \[CH [0-9]+\] enabled on GPIO[0-9]+']
if dut.target != 'esp32':
expect_items += [r'Touch channel [0-9]+ \(GPIO[0-9]+\) is selected as deep sleep wakeup channel']
expect_items += ['touch wakeup source is ready']
for exp in expect_items:
dut.expect(exp, timeout=10)
@@ -52,7 +43,7 @@ def test_deep_sleep(dut: Dut) -> None:
def expect_enable_deep_sleep_no_touch() -> None:
dut.expect_exact('Enabling timer wakeup, 20s', timeout=10)
if dut.target in touch_wake_up_support:
if dut.app.sdkconfig.get('SOC_TOUCH_SUPPORT_SLEEP_WAKEUP'):
expect_enable_deep_sleep = expect_enable_deep_sleep_touch
else:
expect_enable_deep_sleep = expect_enable_deep_sleep_no_touch

View File

@@ -4,21 +4,12 @@ set(srcs "light_sleep_example_main.c"
"gpio_wakeup.c"
"timer_wakeup.c"
"uart_wakeup.c")
set(includes ".")
set(priv_reqs esp_driver_uart esp_driver_gpio esp_timer)
set(TOUCH_ELEMENT_COMPATIBLE_TARGETS "esp32s2" "esp32s3")
if(${target} IN_LIST TOUCH_ELEMENT_COMPATIBLE_TARGETS)
list(APPEND srcs "touch_wakeup.c")
list(APPEND priv_reqs touch_element)
endif()
if("${target}" STREQUAL "esp32p4")
if(CONFIG_SOC_TOUCH_SENSOR_SUPPORTED AND CONFIG_SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP)
list(APPEND srcs "touch_sens_wakeup.c")
list(APPEND priv_reqs esp_driver_touch_sens)
endif()
idf_component_register(SRCS ${srcs}
PRIV_REQUIRES ${priv_reqs}
INCLUDE_DIRS ".")
PRIV_REQUIRES esp_driver_uart esp_driver_gpio esp_timer esp_driver_touch_sens
INCLUDE_DIRS ${includes})

View File

@@ -0,0 +1,3 @@
dependencies:
touch_sens_examples_common:
path: ${IDF_PATH}/examples/peripherals/touch_sensor/touch_sens_examples_common

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@@ -12,8 +12,7 @@
extern "C" {
#endif
// TODO: [ESP32P4] add P4 when runner is ready
#define EXAMPLE_TOUCH_LSLEEP_WAKEUP_SUPPORT (CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3)
#define TOUCH_LSLEEP_SUPPORTED (SOC_TOUCH_SENSOR_SUPPORTED && SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP)
void example_wait_gpio_inactive(void);
@@ -23,7 +22,7 @@ esp_err_t example_register_timer_wakeup(void);
esp_err_t example_register_uart_wakeup(void);
#if EXAMPLE_TOUCH_LSLEEP_WAKEUP_SUPPORT
#if TOUCH_LSLEEP_SUPPORTED
void example_register_touch_wakeup(void);
#endif

View File

@@ -50,7 +50,7 @@ static void light_sleep_task(void *args)
* Otherwise the chip may fall sleep again before running uart task */
vTaskDelay(1);
break;
#if EXAMPLE_TOUCH_LSLEEP_WAKEUP_SUPPORT
#if TOUCH_LSLEEP_SUPPORTED
case ESP_SLEEP_WAKEUP_TOUCHPAD:
wakeup_reason = "touch";
break;
@@ -83,7 +83,7 @@ void app_main(void)
example_register_timer_wakeup();
/* Enable wakeup from light sleep by uart */
example_register_uart_wakeup();
#if EXAMPLE_TOUCH_LSLEEP_WAKEUP_SUPPORT
#if TOUCH_LSLEEP_SUPPORTED
/* Enable wakeup from light sleep by touch element */
example_register_touch_wakeup();
#endif

View File

@@ -1,18 +1,22 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include "freertos/FreeRTOS.h"
#include "esp_log.h"
#include "driver/touch_sens.h"
#include "touch_sens_example_config.h"
static const char *TAG = "touch_wakeup";
#define EXAMPLE_TOUCH_SAMPLE_CFG_NUM 1
#define EXAMPLE_TOUCH_CHANNEL_NUM 5
#define EXAMPLE_TOUCH_CHANNEL_NUM 3
#define EXAMPLE_TOUCH_CHAN_INIT_SCAN_TIMES 3
// If you want to change the wake-up channels, please make sure the channel GPIOs won't conflict to the EXT wakeup GPIOs
static int s_channel_id[EXAMPLE_TOUCH_CHANNEL_NUM] = {7, 8, 9};
// Active threshold to benchmark ratio. (i.e., touch will be activated when data >= benchmark * (1 + ratio))
static float s_thresh2bm_ratio[EXAMPLE_TOUCH_CHANNEL_NUM] = {
[0 ... EXAMPLE_TOUCH_CHANNEL_NUM - 1] = 0.02f, // 2%
@@ -20,13 +24,13 @@ static float s_thresh2bm_ratio[EXAMPLE_TOUCH_CHANNEL_NUM] = {
static bool example_touch_on_active_cb(touch_sensor_handle_t sens_handle, const touch_active_event_data_t *event, void *user_ctx)
{
ESP_EARLY_LOGW("isr", "ch %d active", (int)event->chan_id);
ESP_EARLY_LOGW("touch callback", "ch %d active", (int)event->chan_id);
return false;
}
static bool example_touch_on_inactive_cb(touch_sensor_handle_t sens_handle, const touch_inactive_event_data_t *event, void *user_ctx)
{
ESP_EARLY_LOGW("isr", "ch %d inactive", (int)event->chan_id);
ESP_EARLY_LOGW("touch callback", "ch %d inactive", (int)event->chan_id);
return false;
}
@@ -48,13 +52,25 @@ static void example_touch_do_initial_scanning(touch_sensor_handle_t sens_handle,
for (int i = 0; i < EXAMPLE_TOUCH_CHANNEL_NUM; i++) {
/* Read the initial benchmark of the touch channel */
uint32_t benchmark[EXAMPLE_TOUCH_SAMPLE_CFG_NUM] = {};
#if SOC_TOUCH_SUPPORT_BENCHMARK
ESP_ERROR_CHECK(touch_channel_read_data(chan_handle[i], TOUCH_CHAN_DATA_TYPE_BENCHMARK, benchmark));
#else
/* Read smooth data instead if the hardware does not support benchmark */
ESP_ERROR_CHECK(touch_channel_read_data(chan_handle[i], TOUCH_CHAN_DATA_TYPE_SMOOTH, benchmark));
#endif // SOC_TOUCH_SUPPORT_BENCHMARK
/* Calculate the proper active thresholds regarding the initial benchmark */
printf("[CH %d]", i);
touch_channel_config_t chan_cfg = {};
printf("Touch [CH %d]", s_channel_id[i]);
/* Generate the default channel configuration and then update the active threshold based on the real benchmark */
touch_channel_config_t chan_cfg = EXAMPLE_TOUCH_CHAN_CFG_DEFAULT();
for (int j = 0; j < EXAMPLE_TOUCH_SAMPLE_CFG_NUM; j++) {
chan_cfg.active_thresh[j] = (uint32_t)(benchmark[j] * s_thresh2bm_ratio[j]);
#if SOC_TOUCH_SENSOR_VERSION == 1
// Touch V1 (ESP32) uses absolute threshold.
chan_cfg.abs_active_thresh[j] = (uint32_t)(benchmark[j] * (1 - s_thresh2bm_ratio[i]));
printf(" %d: %"PRIu32", %"PRIu32"\t", j, benchmark[j], chan_cfg.abs_active_thresh[j]);
#else
chan_cfg.active_thresh[j] = (uint32_t)(benchmark[j] * s_thresh2bm_ratio[i]);
printf(" %d: %"PRIu32", %"PRIu32"\t", j, benchmark[j], chan_cfg.active_thresh[j]);
#endif // SOC_TOUCH_SENSOR_VERSION == 1
}
printf("\n");
/* Update the channel configuration */
@@ -64,39 +80,46 @@ static void example_touch_do_initial_scanning(touch_sensor_handle_t sens_handle,
esp_err_t example_register_touch_wakeup(void)
{
/* Handles of touch sensor */
touch_sensor_handle_t sens_handle = NULL;
touch_sensor_sample_config_t sample_cfg[EXAMPLE_TOUCH_SAMPLE_CFG_NUM] = {
TOUCH_SENSOR_V3_DEFAULT_SAMPLE_CONFIG(1, 1, 1),
};
touch_channel_handle_t chan_handle[EXAMPLE_TOUCH_CHANNEL_NUM];
/* Step 1: Create a new touch sensor controller handle with default sample configuration */
touch_sensor_sample_config_t sample_cfg[TOUCH_SAMPLE_CFG_NUM] = EXAMPLE_TOUCH_SAMPLE_CFG_DEFAULT();
touch_sensor_config_t sens_cfg = TOUCH_SENSOR_DEFAULT_BASIC_CONFIG(EXAMPLE_TOUCH_SAMPLE_CFG_NUM, sample_cfg);
ESP_ERROR_CHECK(touch_sensor_new_controller(&sens_cfg, &sens_handle));
/* Step 2: Create and enable the new touch channel handles with default configurations */
touch_channel_config_t chan_cfg = EXAMPLE_TOUCH_CHAN_CFG_DEFAULT();
for (int i = 0; i < EXAMPLE_TOUCH_CHANNEL_NUM; i++) {
ESP_ERROR_CHECK(touch_sensor_new_channel(sens_handle, s_channel_id[i], &chan_cfg, &chan_handle[i]));
/* Display the touch channel corresponding GPIO number, you can also know from `touch_sensor_channel.h` */
touch_chan_info_t chan_info = {};
ESP_ERROR_CHECK(touch_sensor_get_channel_info(chan_handle[i], &chan_info));
printf("Touch [CH %d] enabled on GPIO%d\n", s_channel_id[i], chan_info.chan_gpio);
}
/* Step 3: Confiture the default filter for the touch sensor (Note: Touch V1 uses software filter) */
touch_sensor_filter_config_t filter_cfg = TOUCH_SENSOR_DEFAULT_FILTER_CONFIG();
ESP_ERROR_CHECK(touch_sensor_config_filter(sens_handle, &filter_cfg));
touch_channel_handle_t chan_handle[EXAMPLE_TOUCH_CHANNEL_NUM];
touch_channel_config_t chan_cfg = {
.active_thresh = {5000}, // Initial threshold
};
for (int i = 0; i < EXAMPLE_TOUCH_CHANNEL_NUM; i++) {
ESP_ERROR_CHECK(touch_sensor_new_channel(sens_handle, i, &chan_cfg, &chan_handle[i]));
}
/* (Optional) Do the initial scanning to initialize the touch channel data
* Without this step, the channel data in the first read will be invalid
*/
example_touch_do_initial_scanning(sens_handle, chan_handle);
/* (Optional) Register the callbacks, optional for light sleep wakeup */
touch_event_callbacks_t callbacks = {
.on_active = example_touch_on_active_cb,
.on_inactive = example_touch_on_inactive_cb,
};
ESP_ERROR_CHECK(touch_sensor_register_callbacks(sens_handle, &callbacks, NULL));
/* Step 4: Enable the light sleep wake-up with the basic configuration */
touch_sleep_config_t light_slp_cfg = TOUCH_SENSOR_DEFAULT_LSLP_CONFIG();
ESP_ERROR_CHECK(touch_sensor_config_sleep_wakeup(sens_handle, &light_slp_cfg));
/* Step 5: Enable touch sensor controller and start continuous scanning before entering light sleep */
ESP_ERROR_CHECK(touch_sensor_enable(sens_handle));
ESP_ERROR_CHECK(touch_sensor_start_continuous_scanning(sens_handle));

View File

@@ -1,101 +0,0 @@
/*
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "esp_sleep.h"
#include "touch_element/touch_button.h"
static const char *TAG = "touch_wakeup";
#define TOUCH_BUTTON_NUM 5
/* Touch buttons handle */
static touch_button_handle_t button_handle[TOUCH_BUTTON_NUM];
/* Touch buttons channel array */
static const touch_pad_t channel_array[TOUCH_BUTTON_NUM] = {
TOUCH_PAD_NUM1,
TOUCH_PAD_NUM2,
TOUCH_PAD_NUM3,
TOUCH_PAD_NUM4,
TOUCH_PAD_NUM5,
};
/* Touch buttons channel sensitivity array */
static const float channel_sens_array[TOUCH_BUTTON_NUM] = {
0.03F,
0.03F,
0.03F,
0.03F,
0.03F,
};
/* Button event handler task */
static void button_handler_task(void *arg)
{
(void) arg; //Unused
touch_elem_message_t element_message;
while (1) {
/* Waiting for touch element messages */
touch_element_message_receive(&element_message, portMAX_DELAY);
if (element_message.element_type != TOUCH_ELEM_TYPE_BUTTON) {
continue;
}
/* Decode message */
const touch_button_message_t *button_message = touch_button_get_message(&element_message);
if (button_message->event == TOUCH_BUTTON_EVT_ON_PRESS) {
ESP_LOGI(TAG, "Button[%"PRIu32"] Press", (uint32_t)element_message.arg);
} else if (button_message->event == TOUCH_BUTTON_EVT_ON_RELEASE) {
ESP_LOGI(TAG, "Button[%"PRIu32"] Release", (uint32_t)element_message.arg);
} else if (button_message->event == TOUCH_BUTTON_EVT_ON_LONGPRESS) {
ESP_LOGI(TAG, "Button[%"PRIu32"] LongPress", (uint32_t)element_message.arg);
}
}
vTaskDelete(NULL);
}
esp_err_t example_register_touch_wakeup(void)
{
/* Initialize Touch Element library */
touch_elem_global_config_t global_config = TOUCH_ELEM_GLOBAL_DEFAULT_CONFIG();
ESP_ERROR_CHECK(touch_element_install(&global_config));
ESP_LOGI(TAG, "Touch element library installed");
touch_button_global_config_t button_global_config = TOUCH_BUTTON_GLOBAL_DEFAULT_CONFIG();
ESP_ERROR_CHECK(touch_button_install(&button_global_config));
ESP_LOGI(TAG, "Touch button installed");
for (int i = 0; i < TOUCH_BUTTON_NUM; i++) {
touch_button_config_t button_config = {
.channel_num = channel_array[i],
.channel_sens = channel_sens_array[i]
};
/* Create Touch buttons */
ESP_ERROR_CHECK(touch_button_create(&button_config, &button_handle[i]));
/* Set EVENT as the dispatch method */
ESP_ERROR_CHECK(touch_button_set_dispatch_method(button_handle[i], TOUCH_ELEM_DISP_EVENT));
/* Subscribe touch button events (On Press, On Release, On LongPress) */
ESP_ERROR_CHECK(touch_button_subscribe_event(button_handle[i],
TOUCH_ELEM_EVENT_ON_PRESS |
TOUCH_ELEM_EVENT_ON_RELEASE |
TOUCH_ELEM_EVENT_ON_LONGPRESS,
(void *)channel_array[i]));
}
ESP_LOGI(TAG, "Touch buttons created");
touch_elem_sleep_config_t sleep_config = {
.sample_count = global_config.hardware.sample_count,
.sleep_cycle = global_config.hardware.sleep_cycle,
};
/* Enable one of registered touch button as light/deep sleep wake-up source */
ESP_ERROR_CHECK(touch_element_enable_light_sleep(&sleep_config));
touch_element_start();
xTaskCreate(&button_handler_task, "button_handler_task", 4 * 1024, NULL, 6, NULL);
ESP_LOGI(TAG, "touch wakeup source is ready");
return ESP_OK;
}