使用ESP-IDF开发方式控制RGB LED灯。

1、准备工作

1.1、硬件模块
  • ESP32-WROVER-E
  • LED
1.2、软件
  • VSCode ESP开发插件
  • ESP-IDF SDK
1.3、连线

RGB LED的三个控制引脚分别连接ESP32开发板的12、14、27号引脚,简图如下: image-20210924210712312

2、代码

2.1、目标

本次要实现如下LED灯光效果:红绿蓝分别闪烁三次->红色呼吸灯->绿色呼吸灯->蓝色呼吸灯->黄色显示最亮、一半亮、最弱亮度。

2.2、步骤

(1)在VSCode中,使用ESP32插件新建项目rgbLED; (2)在主程序文件中添加如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#include "driver/ledc.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

#define LED_RED_CH LEDC_CHANNEL_0
#define LED_GREEN_CH LEDC_CHANNEL_1
#define LED_BLUE_CH LEDC_CHANNEL_2

#define LED_RED_PIN 27
#define LED_GREEN_PIN 14
#define LED_BLUE_PIN 12

void ledc_init()
{

ledc_timer_config_t ledc_timer = {
.speed_mode = LEDC_LOW_SPEED_MODE,
.timer_num = LEDC_TIMER_0,
.duty_resolution = LEDC_TIMER_13_BIT,
.freq_hz = 5000,
.clk_cfg = LEDC_AUTO_CLK
};

ESP_ERROR_CHECK(ledc_timer_config(&ledc_timer));

ledc_channel_config_t ledc_red_chan = {
.speed_mode = LEDC_LOW_SPEED_MODE,
.channel = LED_RED_CH,
.timer_sel = LEDC_TIMER_0,
.intr_type = LEDC_INTR_DISABLE,
.gpio_num = LED_RED_PIN,
.duty = 0,
.hpoint = 0
};
ESP_ERROR_CHECK(ledc_channel_config(&ledc_red_chan));

ledc_channel_config_t ledc_green_chan = {
.speed_mode = LEDC_LOW_SPEED_MODE,
.channel = LED_GREEN_CH,
.timer_sel = LEDC_TIMER_0,
.intr_type = LEDC_INTR_DISABLE,
.gpio_num = LED_GREEN_PIN,
.duty = 0,
.hpoint = 0
};
ESP_ERROR_CHECK(ledc_channel_config(&ledc_green_chan));

ledc_channel_config_t ledc_blue_chan = {
.speed_mode = LEDC_LOW_SPEED_MODE,
.channel = LED_BLUE_CH,
.timer_sel = LEDC_TIMER_0,
.intr_type = LEDC_INTR_DISABLE,
.gpio_num = LED_BLUE_PIN,
.duty = 0,
.hpoint = 0
};
ESP_ERROR_CHECK(ledc_channel_config(&ledc_blue_chan));

ledc_fade_func_install(0);
}

void app_main(void)
{

ledc_init();

while(1){

//blink red
for(int i=0; i<3; i++){
ledc_set_duty_and_update(LEDC_LOW_SPEED_MODE,LED_RED_CH,8191,0);
vTaskDelay(400/portTICK_PERIOD_MS);
ledc_set_duty_and_update(LEDC_LOW_SPEED_MODE,LED_RED_CH,0,0);
vTaskDelay(400/portTICK_PERIOD_MS);
}

//blink green
for(int i=0; i<3; i++){
ledc_set_duty_and_update(LEDC_LOW_SPEED_MODE,LED_GREEN_CH,8191,0);
vTaskDelay(400/portTICK_PERIOD_MS);
ledc_set_duty_and_update(LEDC_LOW_SPEED_MODE,LED_GREEN_CH,0,0);
vTaskDelay(400/portTICK_PERIOD_MS);
}

//blink blue
for(int i=0; i<3; i++){
ledc_set_duty_and_update(LEDC_LOW_SPEED_MODE,LED_BLUE_CH,8191,0);
vTaskDelay(400/portTICK_PERIOD_MS);
ledc_set_duty_and_update(LEDC_LOW_SPEED_MODE,LED_BLUE_CH,0,0);
vTaskDelay(400/portTICK_PERIOD_MS);
}

//fade
ledc_set_fade_time_and_start(LEDC_LOW_SPEED_MODE,LED_RED_CH,8191,3000,LEDC_FADE_WAIT_DONE);
ledc_set_fade_time_and_start(LEDC_LOW_SPEED_MODE,LED_RED_CH,0,3000,LEDC_FADE_WAIT_DONE);

ledc_set_fade_time_and_start(LEDC_LOW_SPEED_MODE,LED_GREEN_CH,8191,3000,LEDC_FADE_WAIT_DONE);
ledc_set_fade_time_and_start(LEDC_LOW_SPEED_MODE,LED_GREEN_CH,0,3000,LEDC_FADE_WAIT_DONE);

ledc_set_fade_time_and_start(LEDC_LOW_SPEED_MODE,LED_BLUE_CH,8191,3000,LEDC_FADE_WAIT_DONE);
ledc_set_fade_time_and_start(LEDC_LOW_SPEED_MODE,LED_BLUE_CH,0,3000,LEDC_FADE_WAIT_DONE);

//yello color
ledc_set_duty_and_update(LEDC_LOW_SPEED_MODE,LED_RED_CH,8191,0);
ledc_set_duty_and_update(LEDC_LOW_SPEED_MODE,LED_GREEN_CH,8191,0);
ledc_set_duty_and_update(LEDC_LOW_SPEED_MODE,LED_BLUE_CH,0,0);
vTaskDelay(2000/portTICK_PERIOD_MS);

ledc_set_duty_and_update(LEDC_LOW_SPEED_MODE,LED_RED_CH,4095,0);
ledc_set_duty_and_update(LEDC_LOW_SPEED_MODE,LED_GREEN_CH,4095,0);
ledc_set_duty_and_update(LEDC_LOW_SPEED_MODE,LED_BLUE_CH,0,0);
vTaskDelay(2000/portTICK_PERIOD_MS);

ledc_set_duty_and_update(LEDC_LOW_SPEED_MODE,LED_RED_CH,100,0);
ledc_set_duty_and_update(LEDC_LOW_SPEED_MODE,LED_GREEN_CH,100,0);
ledc_set_duty_and_update(LEDC_LOW_SPEED_MODE,LED_BLUE_CH,0,0);
vTaskDelay(2000/portTICK_PERIOD_MS);

//close
ledc_stop(LEDC_LOW_SPEED_MODE,LED_RED_CH,0);
ledc_stop(LEDC_LOW_SPEED_MODE,LED_GREEN_CH,0);
ledc_stop(LEDC_LOW_SPEED_MODE,LED_BLUE_CH,0);
vTaskDelay(1000/portTICK_PERIOD_MS);

}
}

(3)说明:

  • ledc 控制器操作按照如下配置: Key Settings of LED PWM Controller's API

其配置流程为: :one: 先使用 ledc_timer_config() 配置定时器,设置PWM频率和占空比分辨率; :two: 再使用ledc_channel_config() 配置通道,将要控制的LED引脚与定时器配置的PWM相关联; :three: 然后使用ledc_set_duty() 直接设置PWM占空比,或者ledc_set_fade_with_time逐渐改变占空比,以控制LED的亮度;

3、测试

3.1、编译和烧录

将硬件连接好,并在VSCode中,使用命令:

1
idf.py build flash -p COM6

进行编译并通过串口COM6烧写。

3.2、查看效果

可以看到LED按照预期的效果显示。

3.3、波形效果
  • ledc_set_duty_and_update(LEDC_LOW_SPEED_MODE,LED_RED_CH,4095,0); 该函数设置占空比4095,而分辨率设置为13位,因此占空比为50%,其波形图如下: image-20210925133531531
  • ledc_set_fade_time_and_start();该函数设置占空比逐渐增加,从0到100%,其效果如下: image-20210925134940213
  • 视频教程: