11/*
2- * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
2+ * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
33 *
44 * SPDX-License-Identifier: CC0-1.0
55 */
1212#include "esp_check.h"
1313#include "touch_sens_example_config.h"
1414
15- static touch_sensor_handle_t s_sens_handle = NULL ;
16- static touch_channel_handle_t s_chan_handle [EXAMPLE_TOUCH_CHANNEL_NUM ] = {};
15+ // Touch version 3 supports multiple sample configurations (i.e. supports frequency hopping),
16+ // others only have one set of sample configurations.
17+ #define EXAMPLE_TOUCH_SAMPLE_CFG_NUM TOUCH_SAMPLE_CFG_NUM // Up to 'TOUCH_SAMPLE_CFG_NUM'
18+ #define EXAMPLE_TOUCH_CHANNEL_NUM 4
19+ #define EXAMPLE_TOUCH_CHAN_INIT_SCAN_TIMES 3
20+
21+ ESP_STATIC_ASSERT (EXAMPLE_TOUCH_SAMPLE_CFG_NUM <= TOUCH_SAMPLE_CFG_NUM , "sample configuration number exceed the supported number" );
22+ ESP_STATIC_ASSERT (EXAMPLE_TOUCH_CHANNEL_NUM <= (TOUCH_MAX_CHAN_ID - TOUCH_MIN_CHAN_ID + 1 ), "touch channel number exceed the max supported number " );
23+
1724// Active threshold to benchmark ratio. (i.e., touch will be activated when data >= benchmark * (1 + ratio))
1825static float s_thresh2bm_ratio [EXAMPLE_TOUCH_CHANNEL_NUM ] = {
1926 [0 ... EXAMPLE_TOUCH_CHANNEL_NUM - 1 ] = 0.015f , // 1.5%
2027};
2128// The touch channel IDs that used in this example
29+ // For the corresponding GPIOs of these channel, please refer to 'touch_sensor_channel.h'
2230static int s_channel_id [EXAMPLE_TOUCH_CHANNEL_NUM ] = {
2331 TOUCH_MIN_CHAN_ID ,
2432 TOUCH_MIN_CHAN_ID + 1 ,
@@ -38,58 +46,73 @@ bool example_touch_on_inactive_callback(touch_sensor_handle_t sens_handle, const
3846 return false;
3947}
4048
41- static void example_touch_do_initial_scanning (void )
49+ static void example_touch_do_initial_scanning (touch_sensor_handle_t sens_handle , touch_channel_handle_t chan_handle [] )
4250{
4351 /* Enable the touch sensor to do the initial scanning, so that to initialize the channel data */
44- ESP_ERROR_CHECK (touch_sensor_enable (s_sens_handle ));
52+ ESP_ERROR_CHECK (touch_sensor_enable (sens_handle ));
4553
4654 /* Scan the enabled touch channels for several times, to make sure the initial channel data is stable */
4755 for (int i = 0 ; i < EXAMPLE_TOUCH_CHAN_INIT_SCAN_TIMES ; i ++ ) {
48- ESP_ERROR_CHECK (touch_sensor_trigger_oneshot_scanning (s_sens_handle , 2000 ));
56+ ESP_ERROR_CHECK (touch_sensor_trigger_oneshot_scanning (sens_handle , 2000 ));
4957 }
5058
5159 /* Disable the touch channel to rollback the state */
52- ESP_ERROR_CHECK (touch_sensor_disable (s_sens_handle ));
60+ ESP_ERROR_CHECK (touch_sensor_disable (sens_handle ));
5361
5462 /* (Optional) Read the initial channel benchmark and reconfig the channel active threshold accordingly */
5563 printf ("Initial benchmark and new threshold are:\n" );
5664 for (int i = 0 ; i < EXAMPLE_TOUCH_CHANNEL_NUM ; i ++ ) {
5765 /* Read the initial benchmark of the touch channel */
5866 uint32_t benchmark [EXAMPLE_TOUCH_SAMPLE_CFG_NUM ] = {};
59- ESP_ERROR_CHECK (touch_channel_read_data (s_chan_handle [i ], TOUCH_CHAN_DATA_TYPE_BENCHMARK , benchmark ));
67+ #if SOC_TOUCH_SUPPORT_BENCHMARK
68+ ESP_ERROR_CHECK (touch_channel_read_data (chan_handle [i ], TOUCH_CHAN_DATA_TYPE_BENCHMARK , benchmark ));
69+ #else
70+ /* Read smooth data instead if the touch V1 hardware does not support benchmark */
71+ ESP_ERROR_CHECK (touch_channel_read_data (chan_handle [i ], TOUCH_CHAN_DATA_TYPE_SMOOTH , benchmark ));
72+ #endif // SOC_TOUCH_SUPPORT_BENCHMARK
6073 /* Calculate the proper active thresholds regarding the initial benchmark */
61- printf ("[CH %d]" , i );
74+ printf ("Touch [CH %d]" , s_channel_id [i ]);
75+ /* Generate the default channel configuration and then update the active threshold based on the real benchmark */
6276 touch_channel_config_t chan_cfg = EXAMPLE_TOUCH_CHAN_CFG_DEFAULT ();
6377 for (int j = 0 ; j < EXAMPLE_TOUCH_SAMPLE_CFG_NUM ; j ++ ) {
78+ #if SOC_TOUCH_SENSOR_VERSION == 1
79+ // Touch V1 (ESP32) uses absolute threshold.
80+ chan_cfg .abs_active_thresh [j ] = (uint32_t )(benchmark [j ] * (1 - s_thresh2bm_ratio [i ]));
81+ printf (" %d: %" PRIu32 ", %" PRIu32 "\t" , j , benchmark [j ], chan_cfg .abs_active_thresh [j ]);
82+ #else
6483 chan_cfg .active_thresh [j ] = (uint32_t )(benchmark [j ] * s_thresh2bm_ratio [i ]);
6584 printf (" %d: %" PRIu32 ", %" PRIu32 "\t" , j , benchmark [j ], chan_cfg .active_thresh [j ]);
85+ #endif // SOC_TOUCH_SENSOR_VERSION == 1
6686 }
6787 printf ("\n" );
6888 /* Update the channel configuration */
69- ESP_ERROR_CHECK (touch_sensor_reconfig_channel (s_chan_handle [i ], & chan_cfg ));
89+ ESP_ERROR_CHECK (touch_sensor_reconfig_channel (chan_handle [i ], & chan_cfg ));
7090 }
7191}
7292
7393void app_main (void )
7494{
75- /* Use the default sample configurations */
76- touch_sensor_sample_config_t sample_cfg [EXAMPLE_TOUCH_SAMPLE_CFG_NUM ] = EXAMPLE_TOUCH_SAMPLE_CFG_DEFAULT ();
77- /* Allocate new touch controller handle */
78- touch_sensor_config_t sens_cfg = TOUCH_SENSOR_DEFAULT_BASIC_CONFIG (EXAMPLE_TOUCH_SAMPLE_CFG_NUM , sample_cfg );
79- ESP_ERROR_CHECK (touch_sensor_new_controller (& sens_cfg , & s_sens_handle ));
95+ /* Handles of touch sensor */
96+ touch_sensor_handle_t sens_handle = NULL ;
97+ touch_channel_handle_t chan_handle [EXAMPLE_TOUCH_CHANNEL_NUM ];
8098
81- /* Configure the touch sensor filter */
82- touch_sensor_filter_config_t filter_cfg = TOUCH_SENSOR_DEFAULT_FILTER_CONFIG ();
83- ESP_ERROR_CHECK (touch_sensor_config_filter (s_sens_handle , & filter_cfg ));
99+ /* Step 1: Create a new touch sensor controller handle with default sample configuration */
100+ touch_sensor_sample_config_t sample_cfg [TOUCH_SAMPLE_CFG_NUM ] = EXAMPLE_TOUCH_SAMPLE_CFG_DEFAULT ();
101+ touch_sensor_config_t sens_cfg = TOUCH_SENSOR_DEFAULT_BASIC_CONFIG (EXAMPLE_TOUCH_SAMPLE_CFG_NUM , sample_cfg );
102+ ESP_ERROR_CHECK (touch_sensor_new_controller (& sens_cfg , & sens_handle ));
84103
104+ /* Step 2: Create and enable the new touch channel handles with default configurations */
85105 /** Following is about setting the touch channel active threshold of each sample configuration.
86106 *
87107 * @How to Determine:
88108 * As the actual threshold is affected by various factors in real application,
89109 * we need to run the touch app first to get the `benchmark` and the `smooth_data` that being touched.
90110 *
91111 * @Formula:
92- * threshold = benchmark * coeff, (coeff for example, 0.1%~20%)
112+ * Touch V1 uses absolute threshold, and it has no benchmark, so you can use untouched smooth data instead:
113+ * abs_active_thresh = benchmark * (1 - coeff), (coeff for example, 0.1%~20%)
114+ * Touch V2/V3 uses relative threshold:
115+ * active_thresh = benchmark * coeff, (coeff for example, 0.1%~20%)
93116 * Please adjust the coeff to guarantee the threshold < smooth_data - benchmark
94117 *
95118 * @Typical Practice:
@@ -102,48 +125,55 @@ void app_main(void)
102125 touch_channel_config_t chan_cfg = EXAMPLE_TOUCH_CHAN_CFG_DEFAULT ();
103126 /* Allocate new touch channel on the touch controller */
104127 for (int i = 0 ; i < EXAMPLE_TOUCH_CHANNEL_NUM ; i ++ ) {
105- ESP_ERROR_CHECK (touch_sensor_new_channel (s_sens_handle , s_channel_id [i ], & chan_cfg , & s_chan_handle [i ]));
128+ ESP_ERROR_CHECK (touch_sensor_new_channel (sens_handle , s_channel_id [i ], & chan_cfg , & chan_handle [i ]));
129+ /* Display the touch channel corresponding GPIO number, you can also know from `touch_sensor_channel.h` */
130+ touch_chan_info_t chan_info = {};
131+ ESP_ERROR_CHECK (touch_sensor_get_channel_info (chan_handle [i ], & chan_info ));
132+ printf ("Touch [CH %d] enabled on GPIO%d\n" , s_channel_id [i ], chan_info .chan_gpio );
106133 }
134+ printf ("=================================\n" );
135+
136+ /* Step 3: Confiture the default filter for the touch sensor (Note: Touch V1 uses software filter) */
137+ touch_sensor_filter_config_t filter_cfg = TOUCH_SENSOR_DEFAULT_FILTER_CONFIG ();
138+ ESP_ERROR_CHECK (touch_sensor_config_filter (sens_handle , & filter_cfg ));
107139
108- /* Do the initial scanning to initialize the touch channel data
140+ /* Step 4: Do the initial scanning to initialize the touch channel data
109141 * Without this step, the channel data in the first read will be invalid
110142 */
111- example_touch_do_initial_scanning ();
143+ example_touch_do_initial_scanning (sens_handle , chan_handle );
112144
113- /* Register the touch sensor callbacks, here only take `active` and `deactivate ` event for example */
145+ /* Step 5: Register the touch sensor callbacks, here only take `active` and `inactive ` event for example */
114146 touch_event_callbacks_t callbacks = {
115147 .on_active = example_touch_on_active_callback ,
116148 .on_inactive = example_touch_on_inactive_callback ,
117- .on_measure_done = NULL ,
118- .on_scan_done = NULL ,
119- .on_timeout = NULL ,
120- .on_proximity_meas_done = NULL ,
121149 };
122- ESP_ERROR_CHECK (touch_sensor_register_callbacks (s_sens_handle , & callbacks , NULL ));
150+ ESP_ERROR_CHECK (touch_sensor_register_callbacks (sens_handle , & callbacks , NULL ));
123151
124- /* Enable the touch sensor */
125- ESP_ERROR_CHECK (touch_sensor_enable (s_sens_handle ));
152+ /* Step 6: Enable the touch sensor */
153+ ESP_ERROR_CHECK (touch_sensor_enable (sens_handle ));
126154
127- /* Start continuous scanning, you can also trigger oneshot scanning manually */
128- ESP_ERROR_CHECK (touch_sensor_start_continuous_scanning (s_sens_handle ));
155+ /* Step 7: Start continuous scanning, you can also trigger oneshot scanning manually */
156+ ESP_ERROR_CHECK (touch_sensor_start_continuous_scanning (sens_handle ));
129157
130- uint32_t benchmark [ EXAMPLE_TOUCH_SAMPLE_CFG_NUM ] = {};
131- uint32_t chan_data [EXAMPLE_TOUCH_SAMPLE_CFG_NUM ] = {};
158+ /* Step8: Print the sampled data of each enabled touch channel */
159+ uint32_t data [EXAMPLE_TOUCH_SAMPLE_CFG_NUM ] = {};
132160 while (1 ) {
133161 printf ("=================================\n" );
134162 for (int i = 0 ; i < EXAMPLE_TOUCH_CHANNEL_NUM ; i ++ ) {
163+ #if SOC_TOUCH_SUPPORT_BENCHMARK
135164 /* Read and print the benchmark of each sample configuration */
136- ESP_ERROR_CHECK (touch_channel_read_data (s_chan_handle [i ], TOUCH_CHAN_DATA_TYPE_BENCHMARK , benchmark ));
165+ ESP_ERROR_CHECK (touch_channel_read_data (chan_handle [i ], TOUCH_CHAN_DATA_TYPE_BENCHMARK , data ));
137166 printf ("benchmark [CH %d]:" , s_channel_id [i ]);
138167 for (int j = 0 ; j < EXAMPLE_TOUCH_SAMPLE_CFG_NUM ; j ++ ) {
139- printf (" %" PRIu32 , benchmark [j ]);
168+ printf (" %" PRIu32 , data [j ]);
140169 }
141170 printf ("\n" );
171+ #endif
142172 /* Read and print the channel data of each sample configuration */
143- ESP_ERROR_CHECK (touch_channel_read_data (s_chan_handle [i ], TOUCH_CHAN_DATA_TYPE_SMOOTH , chan_data ));
144- printf ("chan_data [CH %d]:" , s_channel_id [i ]);
173+ ESP_ERROR_CHECK (touch_channel_read_data (chan_handle [i ], TOUCH_CHAN_DATA_TYPE_SMOOTH , data ));
174+ printf ("smooth [CH %d]:" , s_channel_id [i ]);
145175 for (int j = 0 ; j < EXAMPLE_TOUCH_SAMPLE_CFG_NUM ; j ++ ) {
146- printf (" %" PRIu32 , chan_data [j ]);
176+ printf (" %" PRIu32 , data [j ]);
147177 }
148178 printf ("\n\n" );
149179 }
0 commit comments