4.3.2 LED灯调节亮度#
4.3.2.1 简介#
本课程将引导您深入了解如何利用脉宽调制(PWM)技术来调节LED灯的亮度。PWM是一种通过快速切换电源来改变LED亮度的高效方法,它通过调整信号的占空比来控制LED的平均电流,从而实现亮度的无级调节。课程内容包括PWM原理、电路设计、编程实现及实际应用案例,旨在帮助学员掌握LED亮度控制的核心技术,并能够应用于各种电子项目中。
4.3.2.2 元件知识#
模拟信号 与 数字信号
模拟信号在时间和数值上都是连续的。相反,数字信号或离散时间信号是由一系列数值组成的时序序列。生活中大多数信号都是模拟信号。一个常见的模拟信号的例子是:一天中的温度会持续变化,不可能突然从 0℃ 突然跃升至 10℃。然而,数字信号能够瞬间改变数值。这种变化以数字形式表示为 1 和 0(这是二进制代码的基础)。当将其绘制成如下图表并进行比较时,其差异会更加明显。

一个常见的模拟信号的例子是:一天中的温度会持续变化,不可能突然从 0℃ 突然跃升至 10℃。然而,数字信号则不同。在实际应用中,我们通常使用二进制作为数字信号,即一系列的 0 和 1。由于二进制信号只有两种值(0 或 1),所以它具有极高的稳定性和可靠性。最后,模拟信号和数字信号都可以相互转换。
PWM
PWM,即脉宽调制,是一种利用数字信号来控制模拟电路的非常有效的方法。普通的处理器无法直接输出模拟信号。而PWM 技术则使得这种转换(将数字信号转换为模拟信号)变得非常便捷。
PWM 技术通过数字引脚发送特定频率的方波信号,即高电平和低电平的交替输出,每次交替持续一段时间。每组高电平和低电平的总时长通常是固定的,这被称为周期(注意:周期的倒数即为频率)。高电平输出的时间通常被称为“脉冲宽度”,而占空比则是脉冲持续时间(PW)与波形总周期(T)的比率所占的百分比。
高电平输出持续的时间越长,对应的占空比就越大,相应的模拟信号电压也就越高。以下图表展示了在 0V 至 5V 之间(高电平为 5V)模拟信号电压随脉冲宽度(0% - 100%)的变化情况:

脉宽调制的占空比越长,输出功率就越高。既然我们已经理解了这种关系,就可以利用脉宽调制来控制 LED 的亮度或直流电机的速度等等。
从上述内容可以看出,脉宽调制并非真正的模拟方式,电压的有效值相当于相应的模拟值。因此,我们可以控制 LED 和其他输出模块的输出功率,以实现不同的效果。
ESP32 和 PWM
在 ESP32 上,LEDC(PWM)控制器有 16 个独立通道,每个通道都可以独立控制频率、占空比,甚至精度。与传统的 PWM 引脚不同,ESP32 的 PWM 输出引脚是可配置的,每个通道有一个或多个 PWM 输出引脚。最大频率与位精度之间的关系如以下公式所示,其中位的最大值为 31 。

例如,生成一个具有 8 位精度的脉宽调制信号(2^8 = 256,数值范围从 0 到 255),其最大频率为 80,000,000 / 255 = 312,500 赫兹。
4.3.2.3 接线图#
LED模块的S引脚连接到io27
⚠️ 特别注意:智慧农场已经组装好了,这里不需要把LED模块拆下来又重新组装和接线,这里再次提供接线图,是为了方便您编写代码!

4.3.2.4 实验代码#
代码文件在Arduino_代码文件夹中,代码文件为4_3_2_Breathing_LED,如下图所示:

鼠标双击4_3_2_Breathing_LED.ino即可在Arduino IDE中打开。
/*
* 文件名 : Breathing_LED
* 功能 : 让led灯像呼吸一样忽明忽暗.
* 编译IDE:ARDUINO 2.3.6
* 作者 : https://www.keyesrobot.cn/
*/
const int ledPin = 27; // 定义LED的GPIO引脚
void setup() {
pinMode(ledPin, OUTPUT); //设置LED引脚为输出模式。
}
void loop() {
for (int i = 0; i < 255; i++) { //使LED逐渐亮
analogWrite(ledPin, i); //输出PWM
delay(10);
}
for (int i = 255; i > -1; i--) { //使LED逐渐熄灭
analogWrite(ledPin, i); //输出PWM
delay(10);
}
}
4.3.2.5 实验结果#
按照接线图接好线,外接电源,选择好正确的开发板板型(ESP32 Dev Module)和 适当的串口端口(COMxx),然后单击按钮
上传代码。上传代码成功后,即可实现LED灯从暗慢慢变亮,然后再由亮慢慢变暗。以此循环的现象。

4.3.2.6 代码说明#
for (int i = 0; i < 255; i++) {
...
}
for→ 创建计数循环。官方介绍:for | Arduino Documentationint i = 0→ 从0开始计数。i < 255→ 循环条件(i<255时执行)。官方介绍:<(less than) | Arduino Documentationi++→ 每次循环i增加1。官方介绍:++ (increment) | Arduino Documentation

①:设置循环初始值,只是执行一遍,执行后进入②。
②:判断是否瞒住循环条件,如图中i <= 255则是i小于等于255就能进入循环代码③中。
③:循环代码,将需要循环的代码放到这里,如我们这个代码是需要控制pwm值从0到255所以我们只需将i的值当初pwm值即可然后进入④。
④:i++ 是i在原来的值上再加一的操作等于 i = i +1 (i- -则是等效 i = i - 1),执行完后进入⑤。
⑤:i的值加一(或减一)后接着判断i的值是否小于等于255,如果是则继续进入循环代码③,如果不是则退出for循环。
analogWrite(ledPin, i); //Output PWM
analogWrite()→ Arduino PWM输出函数ledPin→ 支持PWM的引脚(带~符号)i→ 占空比值(0-255)