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 上的按键,就可以通过日志参看按键的事件:
    在这里插入图片描述

写在最后

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/14054.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue.js基础组件4--下

1.动态组件 1.定义动态组件 利用动态组件可以动态切换页面中显示的组件。使用<component>标签可以定义动态组件&#xff0c;语法格式如下。 <component is"要渲染的组件"></component>上述语法格式中&#xff0c;<component>标签必须配合i…

Java IO与NIO来Copy文件的四种方法实现以及性能对比

使用Java的IO与NIO来Copy文件的四种方法实现以及性能对比 FileCopyRunner接口&#xff0c;定义了Copy文件的接口&#xff0c;等下在测试类中使用匿名内部类来实现。 package nio.channel;import java.io.File;public interface FileCopyRunner {void copyFile(File source , …

【C语言】明析部分C语言内存函数

目录 1.memcpy 2.memmove 3.memset 4.memcmp 以下都是内存函数&#xff0c;作用单位均是字节 1.memcpy memcpy是C/C语言中的一个内存拷贝函数&#xff0c;其原型为&#xff1a; void* memcpy(void* dest, const void* src, size_t n);目标空间&#xff08;字节&#xff09…

【Linux系统化学习】应用层——HTTPS协议

目录 什么是加密、解密 为什么要加密 臭名昭著的”运营商劫持“ 常见的加密方式 对称加密 非对称加密 数据摘要&&数据指纹 两个用途 HTTPS的工作过程探究 方案1——只是用对称加密 方案2——只使用非对称加密 方案3——双方都是用非对称加密 方案4——对称…

科技引领乡村振兴新潮流:运用现代信息技术手段,提升农业生产和乡村管理效率,打造智慧化、现代化的美丽乡村

一、引言 随着科技的不断进步&#xff0c;现代信息技术已经渗透到社会的各个领域&#xff0c;成为推动社会发展的重要力量。在乡村振兴战略的背景下&#xff0c;科技的力量同样不容忽视。本文旨在探讨如何运用现代信息技术手段&#xff0c;提升农业生产和乡村管理效率&#xf…

java自学阶段二:JavaWeb开发--day04(Maven学习)

day04学习笔记 一、学习目标 1.了解maven的基础概念&#xff1b; 2.学会maven的部署&#xff1b; 3.maven的作用&#xff1a;标准化&#xff1b;方便找依赖 maven就是一个开源项目&#xff0c;专门用来管理和构建Java项目的&#xff1b;我们自己写的项目结构可能会千奇百怪&am…

每日一题《leetcode--116.填充每个结点的下一个右侧结点》

https://leetcode.cn/problems/populating-next-right-pointers-in-each-node/ 题目要求给每个结点的next指针进行填充&#xff0c;使每个结点的next指针指向其下一个右侧结点。如果右侧没有结点&#xff0c;则将next指针设置为空。 struct Node* connect(struct Node* root) {…

快速搭建 WordPress 外贸电商网站指南

本指南全面解析了在 Hostinger 平台上部署 WordPress 外贸电商网站的详细步骤&#xff0c;涵盖托管方案选择、WordPress 一键安装、主题挑选与演示数据导入、主题个性化定制、SEO插件插件 AIOSEO 安装、通过 GTranslate 实现多语言自动翻译、地区访问控制插件&#xff0c;助力用…

人工智能(Educoder)-- 机器学习 -- 神经网络(初级)

第一关 注&#xff1a; 神经网络的起源和应用 起源&#xff1a;神经网络最早由心理学家和神经学家开创&#xff0c;目的是模拟生物神经系统对真实世界物体的交互反应。应用&#xff1a;现代神经网络用于分类&#xff08;如图像识别、文本分类&#xff09;和数值预测&#xff08…

Windows下安装部署rocketmq

1.1.下载安装rocketmq 下载 | RocketMQ 下载完后解压到自定义目录&#xff0c;MQ解压路径\rocketmq-all-4.6.0-bin-release&#xff1b;&#xff08;Windows10系统解压路径不要出现空格&#xff09; 1.2.配置环境变量 配置环境变量&#xff0c;变量名&#xff1a;ROCKETM…

深入探索C/C++内存管理

目录 C/C内存分布 C语言中动态内存管理方式 calloc realloc free C中动态内存管理方式 new和delete操作内置类型 new和delete操作自定义类型 operator new和operator delete函数 new和delete的实现原理 内置类型 自定义类型 定位new和表达式(placement-new) 常见面试…

C++进阶之路:何为运算符重载、赋值运算符重载与前后置++重载(类与对象_中篇)

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…

机器学习之词袋模型

目录 1 词袋模型基本概念 2 词袋模型的表示方法 2.1 三大方法 1 独热表示法&#xff08;One-Hot&#xff09; 2 词频表示法&#xff08;Term Frequency, TF&#xff09; 3 词频-逆文档频率表示法&#xff08;TF-IDF&#xff09; 2.2 例子 1 词袋模型基本概念 词袋模型&a…

《Effective Objective-C 2.0》读书笔记——熟悉Objective-C

目录 第一章&#xff1a;熟悉Objective-C第1条&#xff1a;了解Objective-C语言的起源第2条&#xff1a;在类的头文件中尽量少引入其他头文件第3条&#xff1a;多用字面量语法&#xff0c;少用与之等价的方法第4条&#xff1a;多用类型常量&#xff0c;少用#define预处理指令第…

社交网络安全:保护用户数据的Facebook实践

在数字化时代&#xff0c;社交网络安全成为了人们关注的焦点之一。作为全球最大的社交平台之一&#xff0c;Facebook一直在致力于保护用户数据安全和隐私。本文将探讨Facebook在社交网络安全方面的实践&#xff0c;以及它所采取的措施来保护用户数据的安全性。 1. 数据加密与隐…

AC/DC电源模块:适用于各种功率需求的电子设备

BOSHIDA AC/DC电源模块&#xff1a;适用于各种功率需求的电子设备 AC/DC电源模块是一种广泛应用于不同电子设备中的电源转换模块。它具有输出稳定、高效率、可靠性强等特点&#xff0c;适用于各种功率需求的电子设备。在本文中&#xff0c;我们将探讨AC/DC电源模块的工作原理…

亚信安慧AntDB数据库采集技术创新:ACC从Java到Go的转型之路

传统的指标采集方法通常使用一些命令行工具&#xff0c;如top、free等来获取系统的性能数据。然而&#xff0c;这种方法存在一些缺点。首先&#xff0c;这些命令行工具输出的数据格式通常是文本形式&#xff0c;需要进行解析和处理才能得到有用的信息&#xff0c;这增加了开发者…

计算机网络-BGP概述

一、概述 到目前为止我们已经学习了静态路由、OSPF、RIP、IS-IS了&#xff0c;前面我们也了解到按照区域或者范围来分&#xff0c;路由协议可以划分为&#xff1a;IGP内部网关协议、EGP外部网关协议&#xff0c;而我们前面学习的动态路由都属于IGP的范畴. IGP是用于单一自治系统…

科技赋能,拓宽生活边界

在当今多元化与快速变化的社会中&#xff0c;社会适应能力成为了衡量个人能否顺利融入社会、享受生活品质的关键指标。对于盲人朋友而言&#xff0c;这一能力尤为重要&#xff0c;它不仅关乎日常生活的便利&#xff0c;更影响到心理的健康与社会参与度。在此背景下&#xff0c;…