目录

一、简介

二、所需材料

三、官方例程

四、使用方法

4.1 RMT初始化

4.2 WS2812初始化

4.3 点亮WS2812

五、LED颜色渐变

5.1 第一种实现方法

5.2 第二种实现方法

5.3 彩虹跑马灯


一、简介

官方关于RMT的介绍:RMT(红外遥控器)是一个红外发送/接收控制器, 其特殊设计支持生成各类信号。红外遥控发射器从内置的 RAM(随机存取存储器)区中读取连续的脉冲码, 并对输出信号进行载波调制。尽管RMT外设主要用于远程红外应用,由于其灵活的数据格式,RMT同样可支持其它协议。WS2812是集成了驱动电路和单线控制的数字RGB LED,其协议数据格式兼容于RMT外设。

详细参考:ESP-IDF 编程指南 Remote Control (RMT)

由于RMT的灵活特性,自然也可以编程以用于控制WS2812灯条。

二、所需材料

平台:VScode+ESP-IDF

ESP32开发板                ×1

WS2812灯条                 ×1

连接线                           若干

三、官方例程

官方给出了相关的库以及相应的参考例程,那只要学会怎么用轮子就可以了。

首先 ctrl+shift+p 打开命令面板,键入 ESP-IDF show examples projects :

打开ESP-IDF example界面,找到 led_strip 例程:

点击 使用例程i2s_adc_dac创建项目就可以了。

四、使用方法

4.1 RMT初始化

对RMT的初始化需要设置 rmt_config_t 中的相关参数,根据官方的说明:

填好相关参数后,需要调用函数 rmt_config()​​​​​​ 以使初始化参数有效和函数 rmt_driver_install() 安装驱动。相应代码:

// 使用默认参数填入rmt_config_t结构体
rmt_config_t config = RMT_DEFAULT_CONFIG_TX(CONFIG_EXAMPLE_RMT_TX_GPIO, RMT_TX_CHANNEL);
// 将时钟设置为40MHz
config.clk_div = 2;// 调用两个函数完成初始化
ESP_ERROR_CHECK(rmt_config(&config));
ESP_ERROR_CHECK(rmt_driver_install(config.channel, 0, 0));

4.2 WS2812初始化

WS2812的初始化简单一点:

// install ws2812 driver 安装ws2812驱动
led_strip_config_t strip_config = LED_STRIP_DEFAULT_CONFIG(CONFIG_EXAMPLE_STRIP_LED_NUMBER, (led_strip_dev_t)config.channel);
led_strip_t *strip = led_strip_new_rmt_ws2812(&strip_config);
if (!strip) {ESP_LOGE(TAG, "install WS2812 driver failed");
}
// Clear LED strip (turn off all LEDs)关闭所有ws2812
ESP_ERROR_CHECK(strip->clear(strip, 100));

根据 led_strip_config_t 的定义,该结构体的第一个参数为WS2812灯的数量,第二个参数为RMT的通道值。

/**
* @brief LED Strip Configuration Type
*
*/
typedef struct {uint32_t max_leds;   /*!< Maximum LEDs in a single strip */led_strip_dev_t dev; /*!< LED strip device (e.g. RMT channel, PWM channel, etc) */
} led_strip_config_t;

这样就完成了初始化,可以开始使用了。

4.3 点亮WS2812

使用 led_strip_s 结构体中的 set_pixel 函数设置各个灯珠的8位RGB值。使用该函数逐一设置每个灯珠的值,灯珠的位置从0开始计数,每调用一次设置一个灯珠。

设置好灯珠颜色后,调用 refresh 函数将颜色更新到灯条上。

/**
* @brief Set RGB for a specific pixel 设置特定灯珠的RGB值
*
* @param strip: LED strip WS2812的结构体
* @param index: index of pixel to set 需要设置的灯的位置下标,从0开始
* @param red: red part of color 红色的值
* @param green: green part of color 绿色的值
* @param blue: blue part of color 蓝色的值
*
* @return
*      - ESP_OK: Set RGB for a specific pixel successfully
*      - ESP_ERR_INVALID_ARG: Set RGB for a specific pixel failed because of invalid parameters
*      - ESP_FAIL: Set RGB for a specific pixel failed because other error occurred
*/
esp_err_t (*set_pixel)(led_strip_t *strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue);/**
* @brief Refresh memory colors to LEDs 用内存中的颜色更新LEDs
*
* @param strip: LED strip WS2812的结构体
* @param timeout_ms: timeout value for refreshing task 更新任务超时的值
*
* @return
*      - ESP_OK: Refresh successfully
*      - ESP_ERR_TIMEOUT: Refresh failed because of timeout
*      - ESP_FAIL: Refresh failed because some other error occurred
*
* @note:
*      After updating the LED colors in the memory, a following invocation of this API is needed to flush colors to strip.
*      在更新内存中的LED颜色值后,需要调用该API将颜色更新到灯条上。
*/
esp_err_t (*refresh)(led_strip_t *strip, uint32_t timeout_ms);

简单使用:

uint32_t Green=100, Red=100, Blue=100;
for(int j=0; j < LED_Number; j ++){// 设置ws2812的RGB的值ESP_ERROR_CHECK(strip->set_pixel(strip, j, Red, Green, Blue));
}// 给WS2812发送RGB的值
ESP_ERROR_CHECK(strip->refresh(strip, 100));

五、LED颜色渐变

我写了一个颜色渐变的程序,三种颜色的值按照正弦变化,两两错开120°。原理如图

根据这个原理设计程序,LED灯颜色在渐变时的过度就会十分自然。LED所显示的颜色依次为红、橙、黄、绿、靛、紫。

具体代码如下:

5.1 第一种实现方法

第一种方法预先计算好正弦函数的样本值,并存储在一个数组中,然后依次把元素的值作为RGB的值发送给LED灯条,实现颜色渐变效果。

函数声明(放在头文件中):

/*** @brief 所有灯颜色渐变效果,注:必须同时包含SinValue[]数组才能使用* * @param strip LED灯带的结构体* @param LED_Number 点亮的LED的数量* @param GradualChangeRate LED渐变的速度,数值越大,速度越慢,一般为50*/
void WS2812B_ColourGradualChange1(led_strip_t *strip,uint16_t LED_Number,uint16_t GradualChangeRate);

函数定义(放在库文件中):

/*** @brief sin()函数从0到2π的样本值,一共255个点,最大值为255,最小值为0* * 离散信号函数:SinValue(k)=(255*sin(2*k*π/255)+255)/2 (四舍五入取整数)* */
uint8_t  const SinValue[256]={ 128,   131,   134,   137,   140,   143,   147,   150,   153,   156,159,   162,   165,   168,   171,   174,   177,   180,   182,   185,188,   191,   194,   196,   199,   201,   204,   206,   209,   211,214,   216,   218,   220,   223,   225,   227,   229,   230,   232,234,   236,   237,   239,   240,   242,   243,   245,   246,   247,248,   249,   250,   251,   252,   252,   253,   253,   254,   254,255,   255,   255,   255,   255,   255,   255,   255,   255,   254,254,   253,   253,   252,   251,   250,   249,   249,   247,   246,245,   244,   243,   241,   240,   238,   237,   235,   233,   231,229,   228,   226,   224,   221,   219,   217,   215,   212,   210,208,   205,   203,   200,   198,   195,   192,   189,   187,   184,181,   178,   175,   172,   169,   166,   163,   160,   157,   154,151,   148,   145,   142,   139,   136,   132,   129,   126,   123,120,   117,   114,   111,   107,   104,   101,    98,    95,    92,89,    86,    83,    80,    77,    74,    72,    69,    66,    63, 61,    58,    55,    53,    50,    48,    45,    43,    41,    38, 36,    34,    32,    30,    28,    26,    24,    22,    21,    19, 17,    16,    14,    13,    12,    10,     9,     8,     7,     6, 5,     4,     4,     3,     2,     2,     1,     1,     1,     0,  0,     0,     0,     0,     1,     1,     1,     2,     2,     3,3,     4,     5,     6,     6,     7,     9,    10,    11,    12,  14,    15,    17,    18,    20,    21,    23,    25,    27,    29, 31,    33,    35,    37,    40,    42,    44,    47,    49,    52, 54,    57,    59,    62,    65,    67,    70,    73,    76,    79, 82,    85,    88,    91,    94,    97,   100,   103,   106,   109,  112,   115,   118,   121,   125,   128
};void WS2812B_ColourGradualChange1(led_strip_t *strip, uint16_t LED_Number, uint16_t GradualChangeRate)
{uint32_t Green=0,Red=0,Blue=0;uint8_t i,ir,ib;for(i=0;i<255;i++){ir=i+85;ib=i+170;Green=SinValue[i];Red=SinValue[ir];Blue=SinValue[ib];for(int j=0; j < LED_Number; j ++){// 设置ws2812的RGB的值ESP_ERROR_CHECK(strip->set_pixel(strip, j, Red, Green, Blue));}// 给WS2812发送RGB的值ESP_ERROR_CHECK(strip->refresh(strip, 100));vTaskDelay(pdMS_TO_TICKS(GradualChangeRate));}
}

将代码放在库中便可直接调用。

5.2 第二种实现方法

第二种方法使用 math.h 中的sin()函数,实时计算RGB各自的值,并发送给LED灯条。

函数声明(放在头文件中):

/*** @brief 所有灯颜色渐变效果* * @param strip:LED灯带的结构体* @param LED_Number:点亮的LED的数量* @param GradualChangeRate:LED渐变的速度,数值越大,速度越慢,一般为50*/
void WS2812B_ColourGradualChange2(led_strip_t *strip,uint16_t LED_Number,uint16_t GradualChangeRate);

函数定义(放在库文件中):

// 必须包含math.h库
#include <math.h>void WS2812B_ColourGradualChange2(led_strip_t *strip,uint16_t LED_Number,uint16_t GradualChangeRate)
{uint32_t Green=0,Red=0,Blue=0;for(uint16_t i=0; i<628; i++){// 使用sin()函数分别计算三原色的值Green = (int)(127*sin(i/100.0)+127);Red = (int)(127*sin((i+209.3)/100)+127);Blue = (int)(127*sin((i+418.7)/100)+127);for(int j=0; j < LED_Number; j ++){// 设置ws2812的RGB的值ESP_ERROR_CHECK(strip->set_pixel(strip, j, Red, Green, Blue));}// 给WS2812发送RGB的值ESP_ERROR_CHECK(strip->refresh(strip, 100));vTaskDelay(pdMS_TO_TICKS(GradualChangeRate));}
}

两种实现方法的效果差别不大

5.3 彩虹跑马灯

依旧使用前述原理实现彩虹跑马灯效果,每个灯的颜色均不同。

函数声明(放在头文件中):

/*** @brief 彩虹跑马灯效果* * @param strip:LED灯带的结构体* @param LED_Number:点亮的LED的数量* @param GradualChangeRate:LED渐变的速度,数值越大,速度越慢,一般为50*/
void WS2812B_TrottingHorseLamp1(led_strip_t *strip,uint16_t LED_Number,uint16_t GradualChangeRate);

函数定义(放在库文件中):

void WS2812B_TrottingHorseLamp1(led_strip_t *strip, uint16_t LED_Number, uint16_t GradualChangeRate)
{uint32_t Green=0,Red=0,Blue=0;uint8_t i,ir,ib;for(i=0;i<256;i++){ir=i+85;ib=i+170;for(int j=0; j < LED_Number; j ++){// 根据灯珠的位置计算RGB的值Green = SinValue[(i+10*j)%256];Red = SinValue[(ir+10*j)%256];Blue = SinValue[(ib+10*j)%256];// 设置ws2812的RGB的值ESP_ERROR_CHECK(strip->set_pixel(strip, j, Red, Green, Blue));}// 给WS2812发送RGB的值ESP_ERROR_CHECK(strip->refresh(strip, 100));vTaskDelay(pdMS_TO_TICKS(GradualChangeRate));}
}

这样便可实现平滑的彩虹跑马灯效果。

ESP32使用外设RMT控制WS2812灯条相关推荐

  1. Arduino控制WS2812灯带(灯环)

    设计者:STCode(公众号同名) Arduino控制WS2812灯带(灯环) 1) WS2812灯 WS2812灯带 WS2812灯环 WS2812是一个集控制电路与发光电路于一体的智能外空LED光 ...

  2. STM32+ws2812灯条,点灯升级版

    ws2812系列灯条,是一种可寻址的RGB  LED彩灯,可以自定义颜色.点灯速度等.只需要一个IO就可以控制多个灯.ws2812系列有三根线,分别为VCC.GND.信号控制线.作为优化升级版的ws2 ...

  3. esp32 控制ws2812灯带

    采用的arduino控制,利用别人写好的模块进行控制 vs code搜索Adafruit_NeoPixel导入项目中 代码实现 #include <Adafruit_NeoPixel.h> ...

  4. micropython开发idethonny_用ESP32+MicroPython+Thonny点亮WS2812灯带

    本帖最后由 gada888 于 2019-4-30 14:31 编辑 尽管python的编程软件很多,anaconda,pycharm or python ide.个人认为最好用的是Thonny.虽然 ...

  5. 在ESP8266上控制WS2812灯带及热释电传感器原码

    请在ARDUINO IDE中自行添加Adafruit_NeoPixel库即可.测试正常. #include <Adafruit_NeoPixel.h> #ifdef __AVR__  #i ...

  6. 【小项目关键技术五】控制全彩 WS2812 灯环/灯带

    Ref: Arduino控制WS2812灯带(灯环) #include <FastLED.h>#define LED_PIN 13// Information about the LED ...

  7. ESP32 驱动WS2812B 灯条

    //WS2812 灯条 #include <Arduino.h> #include <Adafruit_NeoPixel.h>//关键是这个库 #define WS_PIN   ...

  8. Arduino控制1302颗ws2812灯珠显示圣诞树和圣诞老人(附程序源码)

    Arduino控制1302颗ws2812灯珠显示圣诞树和圣诞老人 设计者:STCode(公众号同名) 效果直接看视频~ Arduino控制ws2812灯带显示圣诞树和圣诞老人 1)项目介绍 该设计一共 ...

  9. 关于STM32利用TIM+PWM+DMA控制WS2812

    开发环境 MCU:STM32F103c8t6 开发工具:STM32CubeMX 使用板子参考原理图:STM32F103C8T6最小系统板开源链接 PWM 脉宽调制(PWM)基本原理:控制方式就是对逆变 ...

最新文章

  1. 资源贴|吴恩达新课发布第1天,3万人观看 | 完整PPT
  2. python期末知识点总结_期末考试必备复习提纲丨9年级数学上册知识点总结归纳(人教版)...
  3. 每秒处理请求数和并发的关系
  4. Ubuntu16.04彻底删除旧内核
  5. python做大型网站_Python中的大型Web应用:一个好的架构
  6. Excel催化剂开源第37波-音视频文件元数据提取(分辨率,时长,采样率等)
  7. 机票预订系统活动图_软件工程(第五版)--习题及答案技术总结.docx
  8. wimbuilder2教程_Wimbuilder WIN10XPE制作所需的工程文件
  9. 《Algorithms》Comparable 实现排序大全
  10. 200 万年薪的博士,华为到底看重什么?
  11. 网站去色的通用方法(简单)
  12. Selenium自动化测试WebDriver下载
  13. C# -- 使用FileInfo获取文件信息
  14. Android Wear缺少本质上的创新
  15. 菜鸟的Hadoop快速入门
  16. linux mbr 分区表修复,linux fdisk修复分区
  17. RGB颜色值与十六进制颜色码转换及颜色码对照表
  18. matlab 计算逆时针夹角,计算两个向量的逆时针夹角
  19. 【转帖】Windows文件系统过滤驱动开发教程-楚狂人
  20. Nginx 负载均衡和动静分离

热门文章

  1. corex9服务器组装攻略,TT CoreX9首测!安静地做个黑胖子决不当保险柜、烤箱、麻将桌、仓鼠笼子!...
  2. httpposterror_HttpPost方式调用接口的3种方式
  3. linux vim基础设置
  4. Latex写作心得-投稿至Elsevier
  5. 快速排序之——挖坑法实现
  6. 基于单片机的红外报警系统设计
  7. 常用的WebService网站
  8. 库函数strcpy、memcpy和memset
  9. HCIP---GRE
  10. 站长说说之网站seo优化主要有哪些方面