ESP32 IDF的触摸按键例子

硬件资源

1.ESP32 开发板

2. LED灯(-接到GND, +通过10K电阻接到PIN4)

3. 触摸按键(接到PIN32,对应触摸通道9)

预期效果:

1. 点动模式:小于1s的触摸,LED交替亮灭

2. 长按模式:大于1s的触摸,LED快速闪烁(100ms)

3. 带防抖

代码如下

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "driver/touch_pad.h" // 添加触摸传感器头文件
#include "esp_log.h"

#define BLINK_GPIO 4
#define TOUCH_THRESHOLD 500   // 触摸阈值
#define DEBOUNCE_TIME 50      // 防抖时间,单位ms
#define SHORT_PRESS_TIME 1000 // 短按时间阈值,单位ms

// 添加LED控制状态变量
static bool led_state = false;
static bool led_blink_mode = false;

// 添加触摸按键读取任务
void task_read_touch(void *pvParameter)
{
    uint16_t touch_value;
    TickType_t press_start = 0;
    bool is_touching = false;
    uint16_t last_touch_value = TOUCH_THRESHOLD;
    TickType_t last_change_time = 0;

    while (1)
    {
        touch_pad_read(TOUCH_PAD_NUM9, &touch_value);
        TickType_t current_time = xTaskGetTickCount();

        // 防抖处理
        if (abs(touch_value - last_touch_value) > 50 &&
            (current_time - last_change_time) > pdMS_TO_TICKS(DEBOUNCE_TIME))
        {
            // 检测触摸开始
            if (!is_touching && touch_value < TOUCH_THRESHOLD)
            {
                is_touching = true;
                press_start = current_time;
                last_change_time = current_time;
                ESP_LOGI("TOUCH", "Touch start, value: %d", touch_value);
            }
            // 检测触摸结束
            else if (is_touching && touch_value >= TOUCH_THRESHOLD)
            {
                is_touching = false;
                TickType_t press_duration = current_time - press_start;
                last_change_time = current_time;

                // 短按(小于1秒)
                if (press_duration < pdMS_TO_TICKS(SHORT_PRESS_TIME))
                {
                    led_state = !led_state;
                    gpio_set_level(BLINK_GPIO, led_state);
                    ESP_LOGI("TOUCH", "Short press detected! LED: %d", led_state);
                }
                else
                {
                    // 长按结束后关闭LED
                    led_state = false;
                    led_blink_mode = false;
                    gpio_set_level(BLINK_GPIO, 0);
                    ESP_LOGI("TOUCH", "Long press ended, LED off");
                }
            }
        }

        // 更新上一次的触摸值
        last_touch_value = touch_value;

        // 长按检测(超过1秒)并处理LED闪烁
        if (is_touching && (current_time - press_start) >= pdMS_TO_TICKS(SHORT_PRESS_TIME))
        {
            led_state = !led_state;
            gpio_set_level(BLINK_GPIO, led_state);
            ESP_LOGI("TOUCH", "Long press - LED blinking: %d", led_state);
            vTaskDelay(pdMS_TO_TICKS(100));
        }
        else
        {
            vTaskDelay(pdMS_TO_TICKS(20)); // 提高采样频率
        }
    }
}

void app_main(void)
{
    // 配置 GPIO
    gpio_config_t io_conf_led =
        {
            .pin_bit_mask = (1ULL << BLINK_GPIO),
            .mode = GPIO_MODE_OUTPUT,
            .pull_up_en = GPIO_PULLUP_DISABLE,
            .pull_down_en = GPIO_PULLDOWN_DISABLE,
            .intr_type = GPIO_INTR_DISABLE

        };
    gpio_config(&io_conf_led);

    // 初始化触摸传感器
    touch_pad_init();
    touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_1V);
    touch_pad_config(TOUCH_PAD_NUM9, 0); // GPIO15 对应 TOUCH_PAD_NUM9

    // 等待触摸传感器稳定
    vTaskDelay(pdMS_TO_TICKS(100));

    // 创建任务

    xTaskCreate(&task_read_touch, "read_touch", 2048, NULL, 5, NULL);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值