ESP32使用LED组件实现各种LED控制
ESP-IDF 组件管理
IDF 组件管理器工具用于下载 ESP-IDF CMake 项目的依赖项,该下载在 CMake 运行期间自动完成。IDF 组件管理器可以从自动从组件注册表 或 Git 仓库获取组件,具体的使用和介绍,请查看官方文档,需要注意的是 ESP-IDF 管理器是 IDF4.4 以后引入的特性,使用IDF框架时,建议尽量使用最新的 release 版本 IDF 构建自己的项目。
要获取组件列表,请参阅 https://components.espressif.com/
LED 组件简介
- 我们从 ESP-IDF 组件管理器网页搜索我们需要的组件,比如 LED,然后 点开 led_indicator 组件
- led_indicator 组件简介
LED 指示灯是最简单的输出外设之一,可以通过不同形式的闪烁指示系统当前的工作状态。ESP-IoT-Solution 提供的 LED 指示灯组件具有以下功能:
- 支持定义多组闪烁类型
- 支持定义闪烁类型优先级
- 支持创建多个指示灯
- LEDC 等驱动支持调节亮度,渐变,颜色等
具体功能和使用方法,请查看官方文档
测试LED组件
- 使用 VSCODE 的 ESP-IDF 插件创建一个 helloword 的工程
- 复制LED 指示灯组件界面上配置组件的命令
idf.py add-dependency "espressif/led_indicator^0.9.2"
在当前 helloworld 工程下增加 led_indicator 组件
PS:遇到的一些问题及解决方法:
- idf.py 的命令无法执行,提示
idf.py : 无法将 “idf.py ”项识别为 cmet、函数、脚本文件或可运行程序的名称。请检査名称的拼写,如果包括路径,请确保路径正确,然后再试一次。
或者只会打开 idf.py 这个文件而不执行这个文件的内容.
解决方法:
指令只能在 ESP-IDF Terminal 中执行,不能在系统自带的 powershell 等工具中执行
- 生成
idf_component.yml
文件后,使用命令idf.py build
或者插件上面的编译按钮对整个工程先进行一次编译,编译完成后,组件就会出现在managed_components
目录下
- 此处我们测试最简单GPIO控制LED的功能;将D:\Espressif\MyProject\hello_world\managed_components\espressif__led_indicator\examples\indicator\gpio\main\main.c 文件里面的内容全部复制到 hello_world_main.c 中
并对 hello_world_main.c 的内容进行稍微的修改,修改 GPIO 及点亮 LED 的电平
/*
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <inttypes.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#if CONFIG_EXAMPLE_ENABLE_CONSOLE_CONTROL
#include "cmd_led_indicator.h"
#endif
#include "esp_idf_version.h"
#include "esp_log.h"
#include "led_indicator.h"
#define GPIO_LED_PIN 33 //设置GPIO33为LED
#define GPIO_ACTIVE_LEVEL 1 //设置高电平点亮LED
static const char *TAG = "led_gpio";
static led_indicator_handle_t led_handle = NULL;
/**
* @brief Define blinking type and priority.
*
*/
enum {
BLINK_DOUBLE = 0,
BLINK_TRIPLE,
BLINK_SLOW,
BLINK_FAST,
BLINK_MAX,
};
/**
* @brief Blinking twice times has a priority level of 0 (highest).
*
*/
static const blink_step_t double_blink[] = {
{LED_BLINK_HOLD, LED_STATE_ON, 500},
{LED_BLINK_HOLD, LED_STATE_OFF, 500},
{LED_BLINK_HOLD, LED_STATE_ON, 500},
{LED_BLINK_HOLD, LED_STATE_OFF, 500},
{LED_BLINK_STOP, 0, 0},
};
/**
* @brief Blinking three times has a priority level of 1.
*
*/
static const blink_step_t triple_blink[] = {
{LED_BLINK_HOLD, LED_STATE_ON, 500},
{LED_BLINK_HOLD, LED_STATE_OFF, 500},
{LED_BLINK_HOLD, LED_STATE_ON, 500},
{LED_BLINK_HOLD, LED_STATE_OFF, 500},
{LED_BLINK_HOLD, LED_STATE_ON, 500},
{LED_BLINK_HOLD, LED_STATE_OFF, 500},
{LED_BLINK_STOP, 0, 0},
};
/**
* @brief Slow blinking takes priority level 2.
*
*/
static const blink_step_t slow_blink[] = {
{LED_BLINK_HOLD, LED_STATE_ON, 1000},
{LED_BLINK_HOLD, LED_STATE_OFF, 1000},
{LED_BLINK_LOOP, 0, 0},
};
/**
* @brief Fast blinking has priority level 3(lowest).
*
*/
static const blink_step_t fast_blink[] = {
{LED_BLINK_HOLD, LED_STATE_ON, 100},
{LED_BLINK_HOLD, LED_STATE_OFF, 100},
{LED_BLINK_LOOP, 0, 0},
};
blink_step_t const *led_mode[] = {
[BLINK_DOUBLE] = double_blink,
[BLINK_TRIPLE] = triple_blink,
[BLINK_SLOW] = slow_blink,
[BLINK_FAST] = fast_blink,
[BLINK_MAX] = NULL,
};
#if CONFIG_EXAMPLE_ENABLE_CONSOLE_CONTROL
static void led_cmd_cb(cmd_type_t cmd_type, uint32_t mode_index)
{
switch (cmd_type) {
case START:
led_indicator_start(led_handle, mode_index);
ESP_LOGI(TAG, "start blink: %"PRIu32"", mode_index);
break;
case STOP:
led_indicator_stop(led_handle, mode_index);
ESP_LOGI(TAG, "stop blink: %"PRIu32"", mode_index);
break;
case PREEMPT_START:
led_indicator_preempt_start(led_handle, mode_index);
ESP_LOGI(TAG, "preempt start blink: %"PRIu32"", mode_index);
break;
case PREEMPT_STOP:
led_indicator_preempt_stop(led_handle, mode_index);
ESP_LOGI(TAG, "preempt stop blink: %"PRIu32"", mode_index);
break;
default:
ESP_LOGE(TAG, "unknown cmd type: %d", cmd_type);
break;
}
}
#endif
void app_main(void)
{
led_indicator_gpio_config_t gpio_config = {
.gpio_num = GPIO_LED_PIN,
.is_active_level_high = GPIO_ACTIVE_LEVEL,
};
const led_indicator_config_t config = {
.mode = LED_GPIO_MODE,
.led_indicator_gpio_config = &gpio_config,
.blink_lists = led_mode,
.blink_list_num = BLINK_MAX,
};
led_handle = led_indicator_create(&config);
assert(led_handle != NULL);
#if CONFIG_EXAMPLE_ENABLE_CONSOLE_CONTROL
cmd_led_indicator_t cmd_led_indicator = {
.cmd_cb = led_cmd_cb,
.mode_count = BLINK_MAX,
};
ESP_ERROR_CHECK(cmd_led_indicator_init(&cmd_led_indicator));
#else
while (1) {
for (int i = 0; i < BLINK_MAX; i++) {
led_indicator_start(led_handle, i);
ESP_LOGI(TAG, "start blink: %d", i);
vTaskDelay(4000 / portTICK_PERIOD_MS);
led_indicator_stop(led_handle, i);
ESP_LOGI(TAG, "stop blink: %d", i);
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
#endif
}
- 对修改完成的功能进行编译,并下载到测试的开发板上,开发板LED按照闪烁2次/闪烁3次/慢速一直闪烁/快速-直闪烁的效率循环进行
写在最后
如果觉得文章对您有帮助,请关注、点赞、收藏,谢谢!