玩转ESP32 PWM输出,制作炫酷呼吸灯效果

什么是PWM

PWM(Pulse Width Modulation)是一种常用的模拟信号产生技术,它通过对一个定时器的计数值进行调整来改变输出信号的占空比,从而控制输出信号的平均电压值,实现对电子元件的精确控制。

ESP32共拥有16个PWM通道,每个通道都可以设置不同的频率和分辨率。在使用PWM功能之前,需要先对相应的GPIO引脚进行初始化,并选择相应的PWM通道进行配置,然后才能通过修改PWM占空比来控制引脚输出的电信号。
在这里插入图片描述

软硬件使用

软件:arduino2.0.4
硬件:ESP32-WROOM-32E

ESP32实现PWM输出

呼吸灯是一种常见的LED特效,它可以让LED的亮度逐渐增加和减少,营造出一种类似于人呼吸的效果。下面是一个使用ESP32 PWM实现呼吸灯效果的示例代码

#include "esp32-hal-timer.h"

#define LED_PIN 18          // 设置LED连接的GPIO引脚
#define LED_CHANNEL 0      // 设置PWM通道号
#define LED_RESOLUTION 8   // 设置PWM分辨率(位数)
#define delay_time 3       // 延时时间

void setup() {
  Serial.begin(115200);
  ledcSetup(LED_CHANNEL, 5000, LED_RESOLUTION);   // 配置PWM通道
  ledcAttachPin(LED_PIN, LED_CHANNEL);             // 将PWM通道连接到LED引脚
  Serial.println("初始化完成");
}

void loop() {
  // 呼吸灯效果:逐渐增加和减少占空比
  for (int duty = 0; duty < 255; duty++) {
    ledcWrite(LED_CHANNEL, duty);          // 增加亮度
    delay(delay_time);
  }
  for (int duty = 255; duty > 0; duty--) {
    ledcWrite(LED_CHANNEL, duty);          // 减少亮度
    delay(delay_time);
  }
}

示例中使用 ledcSetup 函数配置了一个 PWM 通道(LED_CHANNEL),并将它连接到一个GPIO引脚(LED_PIN)。然后,我们在 loop() 中使用循环来逐渐增加和减少PWM占空比,从而实现呼吸灯的效果。

除了基本的呼吸灯效果外,我们还可以制作更炫酷的呼吸灯效果。下面是一个使用ESP32的定时器和中断功能制作呼吸灯效果的示例代码:

#include "esp32-hal-timer.h"

#define LED_PIN 12          // 设置LED1连接的GPIO18引脚
#define LED_PIN2 13          // 设置LED2连接的GPIO19引脚
#define LED_CHANNEL 0      // 设置LED1 PWM通道号
#define LED_CHANNEL2 1      // 设置LED2 PWM通道号
#define LED_RESOLUTION 8   // 设置PWM分辨率(位数)
#define delay_time 3
#define set_time   3
hw_timer_t *timer = NULL;

void IRAM_ATTR onTimer() {
  static uint32_t duty = 255;
  static bool isIncreasing = false;
  // 更新占空比
  if (isIncreasing) {
    duty++;
    if (duty >= 255) {
      isIncreasing = false;
    }
  } else {
    duty--;
    if (duty <= 0) {
      isIncreasing = true;
    }
  }
  // 更改PWM占空比
  ledcWrite(LED_CHANNEL, duty);
}

void setup() {
  Serial.begin(115200);
  ledcSetup(LED_CHANNEL, 5000, LED_RESOLUTION);           // 配置PWM通道0
  ledcSetup(LED_CHANNEL2, 5000, LED_RESOLUTION);           // 配置PWM通道1
  ledcAttachPin(LED_PIN, LED_CHANNEL);                     // 将PWM通道连接到LED引脚
  ledcAttachPin(LED_PIN2, LED_CHANNEL2);

  timer = timerBegin(0, 80, true);            // 设置计时器0,预分频80,countUp为true
  timerAttachInterrupt(timer, onTimer, true);             // 将定时器0连接到onTimer函数
  timerAlarmWrite(timer, set_time * 1000, true);                        // 设置定时器报警时间为 set_time ms,重复报警
  timerAlarmEnable(timer);     
  Serial.println("初始化完成");                       
}

void loop() {
  // 呼吸灯效果:逐渐增加和减少占空比
  for (int duty = 0; duty < 255; duty++) {
    ledcWrite(LED_CHANNEL2, duty);         // 增加亮度
    delay(delay_time);
  }
  for (int duty = 255; duty > 0; duty--) {
    ledcWrite(LED_CHANNEL2, duty);         // 减少亮度
    delay(delay_time);
  }
}

代码讲解

ledcSetup(channel, frequency, resolution)
该函数用于设置一个 PWM 通道的频率和分辨率。
channel:PWM 通道号,0~15
frequency:PWM 信号的频率,单位为赫兹(Hz)
resolution:PWM 信号的分辨率,即占空比的位数

ledcAttachPin(pin, channel)
该函数用于将指定引脚连接到指定 PWM 通道。
pin:要连接的引脚编号
channel:要连接到该引脚的 PWM 通道号

因此,上述代码的作用如下:
ledcSetup(LED_CHANNEL, 5000, LED_RESOLUTION)配置 PWM 通道 0 的频率为 5 kHz,分辨率为 8 位;

ledcSetup(LED_CHANNEL2, 5000, LED_RESOLUTION)配置 PWM 通道 1 的频率为 5 kHz,分辨率为 8 位;

ledcAttachPin(LED_PIN, LED_CHANNEL)将 PWM 通道 0 连接到 LED 引脚;

ledcAttachPin(LED_PIN2, LED_CHANNEL2)将 PWM 通道 1 连接到 LED2 引脚。

结语

在这里插入图片描述

  • 5
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值