当前位置: 首页 > article >正文

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

文章目录

  • 什么是PWM
  • 软硬件使用
  • 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 引脚。

结语

在这里插入图片描述


http://www.kler.cn/a/17958.html

相关文章:

  • 软件工程师简历(精选篇)
  • 淘宝代购系统;海外代购系统;代购程序,代购系统源码PHP前端源码
  • 2024年11月12日Github流行趋势
  • 鸿蒙学习基本概念
  • 什么时候需要复写hashcode()和compartTo方法
  • Java面向对象编程进阶之包装类
  • Leetcode495. 提莫攻击
  • 【键入网址到网页显示】
  • asp.net+sqlserver社区居民健康档案管理系统
  • InsCode体验报告
  • Axios概述
  • 冀永楠:OCR技术的应用与发展
  • Winform从入门到精通(36)——ColorDialog(史上最全)
  • 五音不全?手把手教你用自己声音唱任何歌;最详细的Auto-GPT整理;4月AI绘画模型推荐;HayoAI平台简直太酷了 | ShowMeAI日报
  • 错题本——数据库系统工程师 2022
  • 大家都去荷兰注册公司到底是为了什么?
  • MySQL数据库——MySQL修改和删除索引(DROP INDEX)
  • 后端程序员的前端必备【Vue】 - 07 ES6新语法
  • 测试20K要什么水平?25岁测试工程师成功斩下offer(附面试题)
  • 校园网自动登陆(河南科技学院)
  • cartographer源码阅读---位姿推测器
  • 榜单!直接式TPMS前装搭载率突破60%,哪些厂商在领跑
  • 2008-2020年上市公司能源消耗数据
  • MySQL知识学习06(SQL语句在MySQL中的执行过程)
  • 使用循环数组和环形链表实现双端队列
  • PVE 安装 windows10