ESP-IDF使用Button组件实现按键检测的功能

2024-05-24 12:12

本文主要是介绍ESP-IDF使用Button组件实现按键检测的功能,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

ESP32使用Button组件实现按键检测的功能

    • ESP-IDF 组件管理
    • LED 组件简介
    • 测试button组件
    • 写在最后

ESP-IDF 组件管理

IDF 组件管理器工具用于下载 ESP-IDF CMake 项目的依赖项,该下载在 CMake 运行期间自动完成。IDF 组件管理器可以从自动从组件注册表 或 Git 仓库获取组件,具体的使用和介绍,请查看官方文档,需要注意的是 ESP-IDF 管理器是 IDF4.4 以后引入的特性,使用IDF框架时,建议尽量使用最新的 release 版本 IDF 构建自己的项目。

要获取组件列表,请参阅 https://components.espressif.com/

LED 组件简介

  1. 我们从 ESP-IDF 组件管理器网页搜索我们需要的组件【button】,然后 点开 espressif/button 组件
    在这里插入图片描述
    在这里插入图片描述

  2. button 组件简介

Button按键组件实现了 GPIO 和 ADC 两种按键,并允许同时创建两种不同的按键。下图显示了两种按键的硬件设计:
在这里插入图片描述

  • GPIO 按键优点有:每一个按键占用独立的 IO,之间互不影响,稳定性高;缺点有:按键数量多时占用太多 IO 资源。

  • ADC 按键优点有:可多个按键共用一个 ADC 通道,占用 IO 资源少;缺点有:不能同时按下多按键,当按键因氧化等因素导致闭合电阻增大时,容易误触,稳定性不高。
    每个按键拥有下表的 8 个事件:
    在这里插入图片描述
    每个按键可以有 回调轮询 两种使用方式:

  • 回调:一个按键的每个事件都可以为其注册一个回调函数,产生事件时回调函数将会被调用。这种方式的效率和实时性高,不会丢失事件。

  • 轮询:在程序中周期性调用 :ciot_button_get_event 查询按键当前的事件。
    这种方式使用简单,适合任务简单的场合,当然你也可以将以上两种方式组合使用。

注意:回调函数中不能有 TaskDelay 等阻塞的操作

具体功能和使用方法,请查看官方文档

测试button组件

  1. 使用 VSCODE 的 ESP-IDF 插件创建一个 helloword 的工程
    在这里插入图片描述
  2. 复制button组件界面上配置组件的命令 idf.py add-dependency "espressif/button^3.2.0" 在当前 helloworld 工程下增加 button组件
    在这里插入图片描述

PS:遇到的一些问题及解决方法:

  • idf.py 的命令无法执行,提示 idf.py : 无法将 “idf.py ”项识别为 cmet、函数、脚本文件或可运行程序的名称。请检査名称的拼写,如果包括路径,请确保路径正确,然后再试一次。 或者只会打开 idf.py 这个文件而不执行这个文件的内容.
    解决方法:
    指令只能在 ESP-IDF Terminal 中执行,不能在系统自带的 powershell 等工具中执行
    在这里插入图片描述
  1. 生成 idf_component.yml 文件后,使用命令 idf.py build 或者插件上面的编译按钮对整个工程先进行一次编译,编译完成后,组件就会出现在 managed_components 目录下
    在这里插入图片描述

  2. 此处我们测试最简单GPIO控制LED的功能;将D:\Espressif\MyProject\hello_world\managed_components\espressif__button\examples\button_power_save\main\main.c 文件里面的内容全部复制到 hello_world_main.c
    在这里插入图片描述

并对 hello_world_main.c 的内容进行稍微的修改,因为我们不测试低功耗的相关功能,故删除低功耗测试的相关代码,并且修改 GPIO 及按键按下的有效电平;以下使用IO0作为按键输入,且有效电平为低电平。

/** SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD** SPDX-License-Identifier: Apache-2.0*/#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "esp_pm.h"
#include "iot_button.h"
#include "esp_sleep.h"
#include "esp_idf_version.h"/* Most development boards have "boot" button attached to GPIO0.* You can also change this to another pin.*/
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C6
#define BOOT_BUTTON_NUM         9
#else
#define BOOT_BUTTON_NUM         0
#endif
#define BUTTON_ACTIVE_LEVEL     0static const char *TAG = "button_test";const char *button_event_table[] = {"BUTTON_PRESS_DOWN","BUTTON_PRESS_UP","BUTTON_PRESS_REPEAT","BUTTON_PRESS_REPEAT_DONE","BUTTON_SINGLE_CLICK","BUTTON_DOUBLE_CLICK","BUTTON_MULTIPLE_CLICK","BUTTON_LONG_PRESS_START","BUTTON_LONG_PRESS_HOLD","BUTTON_LONG_PRESS_UP",
};static void button_event_cb(void *arg, void *data)
{ESP_LOGI(TAG, "Button event %s", button_event_table[(button_event_t)data]);#if CONFIG_GPIO_BUTTON_SUPPORT_POWER_SAVEesp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause();if (cause != ESP_SLEEP_WAKEUP_UNDEFINED) {ESP_LOGI(TAG, "Wake up from light sleep, reason %d", cause);}#endif
}void button_init(uint32_t button_num)
{button_config_t btn_cfg = {.type = BUTTON_TYPE_GPIO,.gpio_button_config = {.gpio_num = button_num,.active_level = BUTTON_ACTIVE_LEVEL,
#if CONFIG_GPIO_BUTTON_SUPPORT_POWER_SAVE.enable_power_save = true,
#endif},};button_handle_t btn = iot_button_create(&btn_cfg);assert(btn);esp_err_t err = iot_button_register_cb(btn, BUTTON_PRESS_DOWN, button_event_cb, (void *)BUTTON_PRESS_DOWN);err |= iot_button_register_cb(btn, BUTTON_PRESS_UP, button_event_cb, (void *)BUTTON_PRESS_UP);err |= iot_button_register_cb(btn, BUTTON_PRESS_REPEAT, button_event_cb, (void *)BUTTON_PRESS_REPEAT);err |= iot_button_register_cb(btn, BUTTON_PRESS_REPEAT_DONE, button_event_cb, (void *)BUTTON_PRESS_REPEAT_DONE);err |= iot_button_register_cb(btn, BUTTON_SINGLE_CLICK, button_event_cb, (void *)BUTTON_SINGLE_CLICK);err |= iot_button_register_cb(btn, BUTTON_DOUBLE_CLICK, button_event_cb, (void *)BUTTON_DOUBLE_CLICK);err |= iot_button_register_cb(btn, BUTTON_LONG_PRESS_START, button_event_cb, (void *)BUTTON_LONG_PRESS_START);err |= iot_button_register_cb(btn, BUTTON_LONG_PRESS_HOLD, button_event_cb, (void *)BUTTON_LONG_PRESS_HOLD);err |= iot_button_register_cb(btn, BUTTON_LONG_PRESS_UP, button_event_cb, (void *)BUTTON_LONG_PRESS_UP);ESP_ERROR_CHECK(err);
}
#if CONFIG_GPIO_BUTTON_SUPPORT_POWER_SAVE
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
void power_save_init(void)
{esp_pm_config_t pm_config = {.max_freq_mhz = CONFIG_EXAMPLE_MAX_CPU_FREQ_MHZ,.min_freq_mhz = CONFIG_EXAMPLE_MIN_CPU_FREQ_MHZ,
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE.light_sleep_enable = true
#endif};ESP_ERROR_CHECK(esp_pm_configure(&pm_config));
}
#else
void power_save_init(void)
{
#if CONFIG_IDF_TARGET_ESP32esp_pm_config_esp32_t pm_config = {
#elif CONFIG_IDF_TARGET_ESP32S2esp_pm_config_esp32s2_t pm_config = {
#elif CONFIG_IDF_TARGET_ESP32C3esp_pm_config_esp32c3_t pm_config = {
#elif CONFIG_IDF_TARGET_ESP32S3esp_pm_config_esp32s3_t pm_config = {
#elif CONFIG_IDF_TARGET_ESP32C2esp_pm_config_esp32c2_t pm_config = {
#endif.max_freq_mhz = CONFIG_EXAMPLE_MAX_CPU_FREQ_MHZ,.min_freq_mhz = CONFIG_EXAMPLE_MIN_CPU_FREQ_MHZ,
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE.light_sleep_enable = true
#endif};ESP_ERROR_CHECK(esp_pm_configure(&pm_config));
}
#endif
#endifvoid app_main(void)
{#if CONFIG_GPIO_BUTTON_SUPPORT_POWER_SAVEpower_save_init();
#endifbutton_init(BOOT_BUTTON_NUM);
}
  1. 对修改完成的功能进行编译,并下载到测试的开发板上,按下接到 IO0 上的按键,就可以通过日志参看按键的事件:
    在这里插入图片描述

写在最后

如果觉得文章对您有帮助,请关注、点赞、收藏,谢谢!

这篇关于ESP-IDF使用Button组件实现按键检测的功能的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/998377

相关文章

Java实现字节字符转bcd编码

《Java实现字节字符转bcd编码》BCD是一种将十进制数字编码为二进制的表示方式,常用于数字显示和存储,本文将介绍如何在Java中实现字节字符转BCD码的过程,需要的小伙伴可以了解下... 目录前言BCD码是什么Java实现字节转bcd编码方法补充总结前言BCD码(Binary-Coded Decima

Vue和React受控组件的区别小结

《Vue和React受控组件的区别小结》本文主要介绍了Vue和React受控组件的区别小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学... 目录背景React 的实现vue3 的实现写法一:直接修改事件参数写法二:通过ref引用 DOMVu

SpringBoot全局域名替换的实现

《SpringBoot全局域名替换的实现》本文主要介绍了SpringBoot全局域名替换的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录 项目结构⚙️ 配置文件application.yml️ 配置类AppProperties.Ja

Java使用Javassist动态生成HelloWorld类

《Java使用Javassist动态生成HelloWorld类》Javassist是一个非常强大的字节码操作和定义库,它允许开发者在运行时创建新的类或者修改现有的类,本文将简单介绍如何使用Javass... 目录1. Javassist简介2. 环境准备3. 动态生成HelloWorld类3.1 创建CtC

使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解

《使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解》本文详细介绍了如何使用Python通过ncmdump工具批量将.ncm音频转换为.mp3的步骤,包括安装、配置ffmpeg环... 目录1. 前言2. 安装 ncmdump3. 实现 .ncm 转 .mp34. 执行过程5. 执行结

Python实现批量CSV转Excel的高性能处理方案

《Python实现批量CSV转Excel的高性能处理方案》在日常办公中,我们经常需要将CSV格式的数据转换为Excel文件,本文将介绍一个基于Python的高性能解决方案,感兴趣的小伙伴可以跟随小编一... 目录一、场景需求二、技术方案三、核心代码四、批量处理方案五、性能优化六、使用示例完整代码七、小结一、

Java实现将HTML文件与字符串转换为图片

《Java实现将HTML文件与字符串转换为图片》在Java开发中,我们经常会遇到将HTML内容转换为图片的需求,本文小编就来和大家详细讲讲如何使用FreeSpire.DocforJava库来实现这一功... 目录前言核心实现:html 转图片完整代码场景 1:转换本地 HTML 文件为图片场景 2:转换 H

Java使用jar命令配置服务器端口的完整指南

《Java使用jar命令配置服务器端口的完整指南》本文将详细介绍如何使用java-jar命令启动应用,并重点讲解如何配置服务器端口,同时提供一个实用的Web工具来简化这一过程,希望对大家有所帮助... 目录1. Java Jar文件简介1.1 什么是Jar文件1.2 创建可执行Jar文件2. 使用java

C#使用Spire.Doc for .NET实现HTML转Word的高效方案

《C#使用Spire.Docfor.NET实现HTML转Word的高效方案》在Web开发中,HTML内容的生成与处理是高频需求,然而,当用户需要将HTML页面或动态生成的HTML字符串转换为Wor... 目录引言一、html转Word的典型场景与挑战二、用 Spire.Doc 实现 HTML 转 Word1

C#实现一键批量合并PDF文档

《C#实现一键批量合并PDF文档》这篇文章主要为大家详细介绍了如何使用C#实现一键批量合并PDF文档功能,文中的示例代码简洁易懂,感兴趣的小伙伴可以跟随小编一起学习一下... 目录前言效果展示功能实现1、添加文件2、文件分组(书签)3、定义页码范围4、自定义显示5、定义页面尺寸6、PDF批量合并7、其他方法