3. DHT22 高精度温湿度数据上云

DHT22 高精度温湿度数据上云 学习卡片

任务目标

使用ESP32的LEDC外设产生PWM信号,驱动LED实现从暗到亮再变暗的呼吸效果。通过本案例理解PWM的占空比、频率概念,以及LEDC通道的配置方法。

所需硬件与接线

  • ESP32开发板
  • LED一个(建议串联220Ω限流电阻)
  • 杜邦线

将LED阳极(长脚)经限流电阻连接到GPIO2,阴极(短脚)接GND。

核心原理

LEDC(LED Control)是ESP32内置的PWM外设,通过设置频率和占空比控制输出。呼吸灯的关键在于动态改变占空比:占空比从0逐步增大到最大值(LED渐亮),再逐步减小到0(LED渐暗),循环往复。本案例使用8位分辨率(0~255),频率设为5kHz(高于人眼闪烁感知阈值)。

完整代码

#include <stdio.h>
#include "driver/ledc.h"
#include "esp_err.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

#define LED_GPIO        2
#define LEDC_TIMER      LEDC_TIMER_0
#define LEDC_MODE       LEDC_LOW_SPEED_MODE
#define LEDC_CHANNEL    LEDC_CHANNEL_0
#define LEDC_DUTY_RES   LEDC_TIMER_8_BIT   // 8位分辨率,占空比0~255
#define LEDC_FREQ_HZ    5000               // 5kHz PWM频率

void app_main(void)
{
    // 1. 配置LEDC定时器
    ledc_timer_config_t timer_conf = {
        .speed_mode      = LEDC_MODE,
        .duty_resolution = LEDC_DUTY_RES,
        .timer_num       = LEDC_TIMER,
        .freq_hz         = LEDC_FREQ_HZ,
        .clk_cfg         = LEDC_AUTO_CLK
    };
    ESP_ERROR_CHECK(ledc_timer_config(&timer_conf));

    // 2. 配置LEDC通道
    ledc_channel_config_t channel_conf = {
        .gpio_num   = LED_GPIO,
        .speed_mode = LEDC_MODE,
        .channel    = LEDC_CHANNEL,
        .intr_type  = LEDC_INTR_DISABLE,
        .timer_sel  = LEDC_TIMER,
        .duty       = 0,
        .hpoint     = 0
    };
    ESP_ERROR_CHECK(ledc_channel_config(&channel_conf));

    // 3. 呼吸循环:渐亮→渐暗
    while (1) {
        // 渐亮:占空比从0增加到255
        for (int duty = 0; duty <= 255; duty++) {
            ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, LEDC_CHANNEL, duty));
            ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, LEDC_CHANNEL));
            vTaskDelay(pdMS_TO_TICKS(5));  // 每步延时5ms,约1.3s完成渐亮
        }
        // 渐暗:占空比从255减小到0
        for (int duty = 255; duty >= 0; duty--) {
            ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, LEDC_CHANNEL, duty));
            ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, LEDC_CHANNEL));
            vTaskDelay(pdMS_TO_TICKS(5));
        }
    }
}

编译与烧录

  1. 在ESP-IDF环境中创建项目,将上述代码保存为main.c(替换模板中的同名文件)。
  2. 在项目根目录执行 idf.py set-target esp32 设置目标芯片。
  3. 执行 idf.py build 编译。
  4. 连接开发板,执行 idf.py -p /dev/ttyUSB0 flash monitor 烧录并打开串口监视器(Windows端口号请按实际修改)。

验证方法

烧录成功后,观察GPIO2所接LED是否呈现周期性呼吸效果:亮度从完全熄灭平滑增强到最亮,再平滑减弱至熄灭,循环周期约2.6秒。若LED不亮,检查接线和GPIO2是否被其他外设占用;若亮度跳变不连续,检查延时是否过短导致人眼无法分辨中间亮度等级。

关键参数调整

  • 呼吸速度:修改vTaskDelay的延时值(当前5ms),增大则变慢,减小则变快。
  • 亮度范围:修改for循环的上下限(当前0~255),可限制最大亮度。
  • PWM频率:修改LEDC_FREQ_HZ,频率过低会导致LED闪烁,过高可能超出LEDC支持范围。