| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- /* Touch Pad Interrupt Example
- This example code is in the Public Domain (or CC0 licensed, at your option.)
- Unless required by applicable law or agreed to in writing, this
- software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
- CONDITIONS OF ANY KIND, either express or implied.
- */
- #include <stdio.h>
- #include "freertos/FreeRTOS.h"
- #include "freertos/task.h"
- #include "esp_log.h"
- #include "driver/touch_pad.h"
- #include "soc/rtc_cntl_reg.h"
- #include "soc/sens_reg.h"
- static const char* TAG = "Touch pad";
- #define TOUCH_THRESH_NO_USE (0)
- #define TOUCH_THRESH_PERCENT (99)
- 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;
- //delay some time in order to make the filter work and get a initial value
- vTaskDelay(500/portTICK_PERIOD_MS);
- 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 val: %d\n", 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 99% 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();
- 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: %d; init val: %d\n", 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_LOGI(TAG, "Change mode...%s\n", 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()
- {
- 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()
- {
- // Initialize touch pad peripheral, it will start a timer to run a filter
- ESP_LOGI(TAG, "Initializing touch pad");
- touch_pad_init();
- // Initialize and start a software filter to detect slight change of capacitance.
- touch_pad_filter_start(10);
- // Set measuring time and sleep time
- // In this case, measurement will sustain 0xffff / 8Mhz = 8.19ms
- // Meanwhile, sleep time between two measurement will be 0x1000 / 150Khz = 27.3 ms
- touch_pad_set_meas_time(0x1000, 0xffff);
- //set reference voltage for charging/discharging
- // In this case, the high reference valtage will be 2.4V - 1.5V = 0.9V
- // The low reference voltage will be 0.8V, so that the procedure of charging
- // and discharging would be very fast.
- touch_pad_set_voltage(TOUCH_HVOLT_2V4, TOUCH_LVOLT_0V8, TOUCH_HVOLT_ATTEN_1V5);
- // Init touch pad IO
- tp_example_touch_pad_init();
- // 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", 2048, NULL, 5, NULL);
- }
|