ESP32集成了多达10个(或更多,依据具体型号)可配置的Touch引脚(如下图),能够感知轻微的电容变化,从而实现非机械式的触摸控制。
这些引脚可以配置为检测触摸事件,非常适合于构建低功耗、无按键的用户界面。

Touch引脚实际上是一个电容式传感器,具有内部振荡器电路,可测量固定时间内引脚上的充电/放电频率。
例如,如果您触摸这些引脚中的任何一个,手指电荷将通过改变连接到触摸传感器的 RC 电路来改变这个周期数。
下面用示例来说明其使用方法
从 https://gitee.com/billyzh/esp32-cpp-lesson 下载本教程的源码到本地硬盘文件夹,如d:\esp32-cpp-lesson
在VSCode中,选择【文件】->【打开文件夹...】选择上一步保存的文件夹打开
选择config.h文件,修改第10行为
#define APP_LESSON32_A 1
打开unit3-lesson32a/board_config文件,设置器件使用的引脚,
#define TOUCH_1_PIN GPIO_NUM_2
监测引脚触摸状态,代码如下(unit2-lesson32a/my_board.cpp):
MyBoard::MyBoard() : Board() {
Log::Info(TAG, "===== Create Board ...... =====");
Log::Info(TAG, "initial led.");
led_ = new GpioLed(BUILTIN_LED_PIN, false); // no pwm
xTaskCreate([](void* pvParam){
MyBoard *board = static_cast<MyBoard*>(pvParam);
board->TouchCheck();
}, "TouchDetected_Task", 4096, this, 1, NULL);
Log::Info( TAG, "===== Board config completed. =====");
}
void MyBoard::TouchCheck() {
while (1) {
touch_value_t tv = touchRead(TOUCH_1_PIN);
if (tv < kThreshold) {
Log::Info(TAG, "Touch detected.");
Application& app = Application::GetInstance();
app.OnPinTouchEvent(kTouch1);
}
delay(100);
}
}
程序解读
1. 本程序使用xTaskCreate创建一个匿名任务,在这个任务里调用MyBoard的TouchCheck方法;
2. TouchCheck是一个死循环,意味着任务会一直执行, 在循环内读取触摸引脚电容值,当读取的值小于阀值时,判定有触摸发生,然后调用Application类的OnPinTouchEvent;
关于xTaskCreate函数,请查看FreeRTOS相关文档。
控制LED闪烁
闪烁代码如下(unit3-lesson31a/my_application.cpp):
void MyApplication::OnLoop() {
if (touch1_detected_) {
Led *led = Board::GetInstance().GetLed();
led->TurnOn();
delay(200);
led->TurnOff();
touch1_detected_ = false;
}
delay(1);
}
bool MyApplication::OnPinTouchEvent(const std::string& pin_name) {
if (pin_name == kTouch1) {
touch1_detected_=true;
return true;
}
return Application::OnPinTouchEvent(pin_name);
}
程序解读
1. 在OnLoop方法中检测touch1_detected_的值,若为true,则点亮LED 0.2秒,touch1_deteted_是MyApplication类的一个私有变量,并使用了volatile定义,防止编译器优化变量访问,确保每次读写都直接操作内存;
2. 重载Application类的OnPinTouchEvent方法实现业务,这里简单的设置touch1_detected_变量为true;
编译项目并上传开发板检验
本例实际上是一个多任务并行的程序,一个任务执行触摸检测(TouchCheck),另一个任务为主任务(OnLoop), 有关多任务的知识在后面小节讲解。
选择config.h文件,修改第10行为
#define APP_LESSON32_B 1
打开unit3-lesson32b/board_config文件,设置器件使用的引脚,
#define TOUCH_1_PIN GPIO_NUM_2
设置引脚触电摸中断,代码如下(unit2-lesson32b/my_board.cpp):
void _OnTouched() {
Log::Info(TAG, "Touch detected.");
Application& app = Application::GetInstance();
app.OnPinTouchEvent(kTouch1);
}
MyBoard::MyBoard() : Board() {
Log::Info(TAG, "===== Create Board ...... =====");
Log::Info(TAG, "initial led.");
led_ = new GpioLed(BUILTIN_LED_PIN, false); // no pwm
touchAttachInterrupt(
TOUCH_1_PIN,
_OnTouched, /* 中断调用函数 */
kThreshold /* 中断触发阀值 */
);
//参考:https://www.xpstem.com/doc/arduino-esp32/api/touch
Log::Info( TAG, "===== Board config completed. =====");
}
程序解读
1. 本程序使用touchAttachInterrupt关联触摸引脚(TOUCH_1_PIN)和中断处理程序(_OnTouched),第三个参数为中断触发阀值; 2. 在中断处理程序中,调用Application类的OnPinTouchEvent;
中断
中断是指当 CPU 在正常处理主程序时,突然发生了另一件事件 A(中断发生)需要 CPU 去处理,这时 CPU 就会暂停处理主程序(中断响应),转而去处理事件 A(中断服务)。当事件 A 处理完以后,再回到主程序原来中断的地方继续执行主程序(中断返回)。这一整个过程称为中断。

中断可以根据中断源分为 硬件中断 和 软件中断:
硬件中断:也被称为外部中断,硬件中断响应外部硬件事件而发生。例如,当检测到触摸时会发生触摸中断,而当 GPIO 引脚的状态发生变化时会发生 GPIO 中断;
软件中断:当触发软件事件(例如定时器溢出)时,会发生这种类型的中断,定时器中断也是软件中断。
控制LED闪烁
这部分代码与上一示例是一样的,不再详述。
有关TouchRead和touchAttachInterrupt的更多信息,请查看ESP32 TOUCH API
作业:
将本小节两种引脚触摸处理程序封装为一个TouchPin类
递归简单点来说,就是一个函数直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解。
本小节主要介绍按键信号转换、Button类及派生类、和Button交互推荐流程。
本小节主要介绍Ws2812灯珠的使用、对父类进行扩展实现自定义功能,和指针向下强制转换的使用。
本小节主要介绍RGB三色LED的使用,以及多态的具体实现。
ESP32 Arduino Framework是专门针对ESP32开发板的Arduino应用开发框架,为用户开发IOT应用、HMI应用提供一致的开发体验。
ESPConnect是一个基于现代浏览器的管理器,在你需要快速验证、调试、管理文件、检查状态的时候,它能帮你省下大量打开和切换重型工具的时间。
本文介绍两种使用TEA5767收音机模块实现FM收音机的方案,感兴趣的朋友可在此基础上实现更丰富的功能。
GPIOViewer 是一个强大的 Arduino 库,专门为 ESP32 芯片设计,可以实时监控 ESP32 芯片上的所有 GPIO 引脚状态。它可以帮助你快速直观地了解每个引脚的当前状态,例如高电平、低电平、输入、输出、中断等等。
在音频处理领域,I2S是一种广泛使用的通信协议,它专门用于芯片之间的音频数据传输。ESP32 作为一款高性能的微控制器,不仅支持 I2S 通信,还提供了强大的硬件接口和灵活的软件库,使其成为音频项目开发的理想选择。
小鹏物联网智能浇花系统是照顾植物的好帮手,支持自动控制和手动控制两种模式,可通过电脑端和手机端查看数据和控制浇水。
Arduino开发环境下适用于ESP32芯片系列开发板的应用开发框架。