forked from espressif/esp-idf
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(touch_sens): add example for the touch sensor v3
- Loading branch information
Showing
11 changed files
with
450 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
6 changes: 6 additions & 0 deletions
6
examples/peripherals/touch_sensor/touch_sensor_v3/CMakeLists.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# 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) | ||
project(touch_sens_example) |
125 changes: 125 additions & 0 deletions
125
examples/peripherals/touch_sensor/touch_sensor_v3/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
| Supported Targets | ESP32-P4 | | ||
| ----------------- | -------- | | ||
|
||
# Capacity Touch Sensor Example (for hardware version 3) | ||
|
||
(See the README.md file in the upper level 'examples' directory for more information about examples.) | ||
|
||
This example is going to demonstrate how to register the touch channels and read the data. | ||
|
||
## How to Use Example | ||
|
||
### Hardware Required | ||
|
||
* A development board with any supported Espressif SOC chip (see `Supported Targets` table above) | ||
* A USB cable for power supply and programming | ||
* (Optional) Touch board with touch buttons on it. | ||
- If you don't have a touch board, you can connect the touch pins with male jump wires and touch it directly for testing. | ||
|
||
### Configure the Project | ||
|
||
You can determine the touch channel number by ``EXAMPLE_TOUCH_CHANNEL_NUM`` in the example. And adjust the active threshold by ``s_thresh2bm_ratio``. | ||
|
||
### Build and Flash | ||
|
||
Build the project and flash it to the board, then run monitor tool to view serial output: | ||
|
||
``` | ||
idf.py -p PORT build flash monitor | ||
``` | ||
|
||
(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 | ||
|
||
You can see the following output in the monitor if the example runs successfully: | ||
|
||
``` | ||
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 | ||
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 | ||
================================= | ||
benchmark [CH 0]: 4115 2056 1028 | ||
chan_data [CH 0]: 4115 2056 1028 | ||
benchmark [CH 1]: 4644 2322 1160 | ||
chan_data [CH 1]: 4644 2322 1160 | ||
benchmark [CH 2]: 4848 2423 1211 | ||
chan_data [CH 2]: 4848 2423 1211 | ||
benchmark [CH 3]: 4337 2168 1084 | ||
chan_data [CH 3]: 4337 2168 1084 | ||
================================= | ||
benchmark [CH 0]: 4109 2054 1027 | ||
chan_data [CH 0]: 4109 2054 1027 | ||
benchmark [CH 1]: 4638 2318 1158 | ||
chan_data [CH 1]: 4638 2318 1158 | ||
benchmark [CH 2]: 4843 2421 1210 | ||
chan_data [CH 2]: 4845 2421 1210 | ||
benchmark [CH 3]: 4334 2167 1084 | ||
chan_data [CH 3]: 4334 2167 1083 | ||
... | ||
``` | ||
|
||
And if you touch and release a button, you will see the following output: | ||
|
||
``` | ||
... | ||
I (1321) touch_callback: [CH 1] active | ||
================================= | ||
benchmark [CH 0]: 4111 2055 1027 | ||
chan_data [CH 0]: 4111 2055 1027 | ||
benchmark [CH 1]: 4676 2339 1168 | ||
chan_data [CH 1]: 17701 8798 4399 | ||
benchmark [CH 2]: 4870 2434 1217 | ||
chan_data [CH 2]: 4867 2433 1217 | ||
benchmark [CH 3]: 4333 2165 1082 | ||
chan_data [CH 3]: 4333 2165 1082 | ||
================================= | ||
benchmark [CH 0]: 4109 2053 1027 | ||
chan_data [CH 0]: 4108 2053 1027 | ||
benchmark [CH 1]: 4676 2339 1168 | ||
chan_data [CH 1]: 11256 8817 4363 | ||
benchmark [CH 2]: 4868 2434 1217 | ||
chan_data [CH 2]: 4862 2429 1214 | ||
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 | ||
... | ||
``` | ||
|
||
## 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. |
3 changes: 3 additions & 0 deletions
3
examples/peripherals/touch_sensor/touch_sensor_v3/main/CMakeLists.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
idf_component_register(SRCS "touch_sens_v3_example_main.c" | ||
PRIV_REQUIRES esp_driver_touch_sens | ||
INCLUDE_DIRS ".") |
169 changes: 169 additions & 0 deletions
169
examples/peripherals/touch_sensor/touch_sensor_v3/main/touch_sens_v3_example_main.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,169 @@ | ||
/* | ||
* SPDX-FileCopyrightText: 2024 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_sens.h" | ||
#include "soc/lp_analog_peri_struct.h" | ||
#include "esp_check.h" | ||
|
||
// Touch version 3 supports multiple sample configurations | ||
#define EXAMPLE_TOUCH_SAMPLE_CFG_NUM TOUCH_SAMPLE_CFG_NUM | ||
#define EXAMPLE_TOUCH_CHANNEL_NUM 4 | ||
#define EXAMPLE_TOUCH_CHAN_INIT_SCAN_TIMES 3 | ||
|
||
static touch_sensor_handle_t s_sens_handle = NULL; | ||
static touch_channel_handle_t s_chan_handle[EXAMPLE_TOUCH_CHANNEL_NUM] = {}; | ||
// 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% | ||
}; | ||
|
||
bool example_touch_on_active_callback(touch_sensor_handle_t sens_handle, const touch_active_event_data_t *event, void *user_ctx) | ||
{ | ||
ESP_EARLY_LOGI("touch_callback", "[CH %d] active", (int)event->chan_id); | ||
return false; | ||
} | ||
|
||
bool example_touch_on_inactive_callback(touch_sensor_handle_t sens_handle, const touch_inactive_event_data_t *event, void *user_ctx) | ||
{ | ||
ESP_EARLY_LOGI("touch_callback", "[CH %d] inactive", (int)event->chan_id); | ||
return false; | ||
} | ||
|
||
static void example_touch_do_initial_scanning(void) | ||
{ | ||
/* 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)); | ||
|
||
/* 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)); | ||
} | ||
|
||
/* Disable the touch channel to rollback the state */ | ||
ESP_ERROR_CHECK(touch_sensor_disable(s_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)); | ||
/* Calculate the proper active thresholds regarding the initial benchmark */ | ||
printf("[CH %d]", i); | ||
touch_channel_config_t chan_cfg = {}; | ||
for (int j = 0; j < EXAMPLE_TOUCH_SAMPLE_CFG_NUM; j++) { | ||
chan_cfg.active_thresh[j] = (uint32_t)(benchmark[j] * s_thresh2bm_ratio[j]); | ||
printf(" %d: %"PRIu32", %"PRIu32"\t", j, benchmark[j], chan_cfg.active_thresh[j]); | ||
} | ||
printf("\n"); | ||
/* Update the channel configuration */ | ||
ESP_ERROR_CHECK(touch_sensor_reconfig_channel(s_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] = { | ||
TOUCH_SENSOR_DEFAULT_SAMPLE_CONFIG0(), | ||
#if EXAMPLE_TOUCH_SAMPLE_CFG_NUM > 1 | ||
TOUCH_SENSOR_DEFAULT_SAMPLE_CONFIG1(), | ||
#endif | ||
#if EXAMPLE_TOUCH_SAMPLE_CFG_NUM > 2 | ||
TOUCH_SENSOR_DEFAULT_SAMPLE_CONFIG2(), | ||
#endif | ||
}; | ||
/* Allocate new touch controller handle */ | ||
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)); | ||
|
||
/* Allocate new touch channel on the touch controller */ | ||
touch_channel_config_t chan_cfg = { | ||
/** Set the touch channel active threshold of each sample configuration. | ||
* | ||
* @How to Determine: | ||
* As the actual threshold is affected by various factors in real application, | ||
* 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%) | ||
* Please adjust the coeff to guarantee the threshold < smooth_data - benchmark | ||
* | ||
* @Typical Practice: | ||
* Normally, we can't determine a fixed threshold at the beginning, | ||
* but we can give them estimated values first and update them after an initial scanning (like this example), | ||
* Step1: set an estimated value for each sample configuration first. (i.e., here) | ||
* Step2: then reconfig the threshold after the initial scanning.(see `example_touch_do_initial_scanning`) | ||
* Step3: adjust the `s_thresh2bm_ratio` to a proper value to trigger the active callback | ||
*/ | ||
.active_thresh = { | ||
5000, // estimated active threshold of sample configuration 0 | ||
#if EXAMPLE_TOUCH_SAMPLE_CFG_NUM > 1 | ||
2500, // estimated active threshold of sample configuration 1 | ||
#endif | ||
#if EXAMPLE_TOUCH_SAMPLE_CFG_NUM > 2 | ||
1000, // estimated active threshold of sample configuration 2 | ||
#endif | ||
}, | ||
}; | ||
for (int i = 0; i < EXAMPLE_TOUCH_CHANNEL_NUM; i++) { | ||
ESP_ERROR_CHECK(touch_sensor_new_channel(s_sens_handle, i, &chan_cfg, &s_chan_handle[i])); | ||
} | ||
|
||
/* 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(); | ||
|
||
/* Register the touch sensor callbacks, here only take `active` and `deactivate` 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)); | ||
|
||
/* Enable the touch sensor */ | ||
ESP_ERROR_CHECK(touch_sensor_enable(s_sens_handle)); | ||
|
||
/* Start continuous scanning, you can also trigger oneshot scanning manually */ | ||
ESP_ERROR_CHECK(touch_sensor_start_continuous_scanning(s_sens_handle)); | ||
|
||
uint32_t benchmark[EXAMPLE_TOUCH_SAMPLE_CFG_NUM] = {}; | ||
uint32_t chan_data[EXAMPLE_TOUCH_SAMPLE_CFG_NUM] = {}; | ||
while (1) { | ||
printf("=================================\n"); | ||
for (int i = 0; i < EXAMPLE_TOUCH_CHANNEL_NUM; i++) { | ||
/* 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)); | ||
printf("benchmark [CH %d]:", i); | ||
for (int j = 0; j < EXAMPLE_TOUCH_SAMPLE_CFG_NUM; j++) { | ||
printf(" %"PRIu32, benchmark[j]); | ||
} | ||
printf("\n"); | ||
/* 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]:", i); | ||
for (int j = 0; j < EXAMPLE_TOUCH_SAMPLE_CFG_NUM; j++) { | ||
printf(" %"PRIu32, chan_data[j]); | ||
} | ||
printf("\n\n"); | ||
} | ||
/* Read and display the data every 300 ms */ | ||
vTaskDelay(pdMS_TO_TICKS(300)); | ||
} | ||
} |
14 changes: 14 additions & 0 deletions
14
examples/peripherals/touch_sensor/touch_sensor_v3/pytest_touch_sens_v3.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD | ||
# SPDX-License-Identifier: Unlicense OR CC0-1.0 | ||
import pytest | ||
from pytest_embedded import Dut | ||
|
||
|
||
@pytest.mark.esp32p4 | ||
@pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='esp32p4 runners do not support touch pins') | ||
@pytest.mark.generic | ||
def test_touch_sens_v3(dut: Dut) -> None: | ||
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]+') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.