ESP32学习笔记----WS2812使用

一、 简介

1.1 硬件介绍

ESP32-S3 SoC 芯片支持以下功能:

  • 2.4 GHz Wi-Fi
  • 低功耗蓝牙
  • 高性能 Xtensa® 32 位 LX7 双核处理器
  • 运行 RISC-V 或 FSM 内核的超低功耗协处理器
  • 多种外设
  • 内置安全硬件
  • USB OTG 接口
  • USB 串口/JTAG 控制

1.2 官方资料

ESP-IDF编程指南
红外遥控RMT

1.3 开发环境

软件:IDF 5.1.1
硬件:ESP32-S3-LCD-EV-Board-MB 开发板

1.4 WS2812介绍

WS2812是一种智能控制LED灯源,集成了控制电路和RGB芯片在一个5050封装组件中。它的主要特点和技术规格如下:

  • 集成设计:WS2812将控制电路和RGB芯片集成在同一个封装中,大大简化了电路设计和安装过程
  • 信号重塑电路:内置信号重塑电路,可以保证波形在每次传递到下一个驱动器时不会发生失真累积
  • 电源丢失重置电路:内置的电源丢失重置电路确保了在电源失效的情况下灯具能够正确重置
  • 颜色和亮度:每个像素可以在三原色中实现256级亮度控制,总共可以显示16777216种颜色。扫描频率不低于400Hz/s
  • 串联传输信号:通过单线串联端口传输信号,任意两点之间的距离超过5米时,信号传输不需要增加电路
  • 刷新率:在30fps的刷新率下,低速模式下的串联数量不少于512点,高速模式不少于1024点
  • 数据传输速率:以800Kbps的速率发送数据
  • 一致性和性价比:灯光的颜色具有很高的一致性,并且成本效益高
  • 应用范围:广泛应用于全彩模块、柔性灯条、室内/室外LED不规则屏幕等LED装饰照明
  • 电气特性:功率供应电压为6.0~7.0V。LED的红、绿、蓝三色分别在1.8-2.2V、3.0-3.2V、3.2-3.4V的电压下工作
  • 数据传输方式:采用单NZR通信模式。在上电复位后,第一个像素接收来自控制器的24位数据,然后传递到下一个像素

引脚定义

符号功能描述
VDDPower supply LED
DOUTControl data signal output
VSSGround
DINControl data signal input

数据传输时间(TH+TL=1.25us±600ns)

T0H0 code, high voltage time0.35us±150ns
T1H1 code, high voltage time0.7us±150ns
T0H0 code, low voltage time0.8us±150ns
T1H1 code, low voltage time0.6us±150ns
RESlow voltage timeAbove 50us

时序图

WS2812时序图

数据传输方法

WS2812数据传输方法

24bit数据结构

WS2812传输数据结构

应用电路

WS2812应用电路
WS2812是一颗数字LED灯珠,采用单总线通讯,每颗灯珠支持24bit的颜色控制,也即RGB888,信号线通过DIN输入,经过一颗灯珠之后,信号线上前24bit数据会被该灯珠锁存,之后将剩下的数据信号整形之后通过DOUT输出

二、点亮一颗WS2812

2.1 引脚确认

我使用的是ESP32-S3-LCD-EV-Board-MB开发版
ESP32-S3-LCD-EV-Board-MB原理图
查看乐鑫官网上的开发板原理图可知WS2812的控制引脚为IO4

2.2组件添加

前往乐鑫组件管理器搜索ws2812
led_strip
找到led_strip组件,在当前工程目录下使用以下命令添加组件

idf.py add-dependency "espressif/led_strip^2.5.3"

2.3添加代码

此时将main.c文件修改为以下内容

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "led_strip.h"

static const char *TAG = "HK";

// GPIO assignment
#define LED_STRIP_BLINK_GPIO  4
// Numbers of the LED in the strip
#define LED_STRIP_LED_NUMBERS 1
// 10MHz resolution, 1 tick = 0.1us (led strip needs a high resolution)
#define LED_STRIP_RMT_RES_HZ  (10 * 1000 * 1000)

led_strip_handle_t configure_led(void)
{
    // LED strip general initialization, according to your led board design
    led_strip_config_t strip_config = {
        .strip_gpio_num = LED_STRIP_BLINK_GPIO,   // The GPIO that connected to the LED strip's data line
        .max_leds = LED_STRIP_LED_NUMBERS,        // The number of LEDs in the strip,
        .led_pixel_format = LED_PIXEL_FORMAT_GRB, // Pixel format of your LED strip
        .led_model = LED_MODEL_WS2812,            // LED strip model
        .flags.invert_out = false,                // whether to invert the output signal
    };

    // LED strip backend configuration: RMT
    led_strip_rmt_config_t rmt_config = {
#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)
        .rmt_channel = 0,
#else
        .clk_src = RMT_CLK_SRC_DEFAULT,        // different clock source can lead to different power consumption
        .resolution_hz = LED_STRIP_RMT_RES_HZ, // RMT counter clock frequency
        .flags.with_dma = false,               // DMA feature is available on ESP target like ESP32-S3
#endif
    };

    // LED Strip object handle
    led_strip_handle_t led_strip;
    ESP_ERROR_CHECK(led_strip_new_rmt_device(&strip_config, &rmt_config, &led_strip));
    ESP_LOGI(TAG, "Created LED strip object with RMT backend");
    return led_strip;
}

void app_main(void)
{
    ESP_LOGI(TAG,"ws2812 start");
    led_strip_handle_t led_strip = configure_led();
    bool led_on_off = false;

    // 设置亮度为 50%
    uint8_t brightness = 50; // 百分比
    uint8_t red = (0 * brightness) / 100;
    uint8_t green = (0 * brightness) / 100;
    uint8_t blue = (139 * brightness) / 100;

    while (1)
    {
        ESP_LOGI(TAG,"ws2812 test");
        if (led_on_off) {
            /* Set the LED pixel using RGB from 0 (0%) to 255 (100%) for each color */
            for (int i = 0; i < LED_STRIP_LED_NUMBERS; i++) {
                ESP_ERROR_CHECK(led_strip_set_pixel(led_strip, i, red, green, blue));
            }
            /* Refresh the strip to send data */
            ESP_ERROR_CHECK(led_strip_refresh(led_strip));
            ESP_LOGI(TAG, "LED ON!");
        } else {
            /* Set all LED off to clear all pixels */
            ESP_ERROR_CHECK(led_strip_clear(led_strip));
            ESP_LOGI(TAG, "LED OFF!");
        }

        led_on_off = !led_on_off;
        vTaskDelay(pdMS_TO_TICKS(500));
    }
    

}

2.4 实验现象

查看开发板led灯闪烁
WS2812实验现象

三、代码讲解

3.1初始化

在configure_led函数中初始化led控制引脚与rmt

led_strip_handle_t configure_led(void)
{
    // LED strip general initialization, according to your led board design
    led_strip_config_t strip_config = {
        .strip_gpio_num = LED_STRIP_BLINK_GPIO,   // The GPIO that connected to the LED strip's data line
        .max_leds = LED_STRIP_LED_NUMBERS,        // The number of LEDs in the strip,
        .led_pixel_format = LED_PIXEL_FORMAT_GRB, // Pixel format of your LED strip
        .led_model = LED_MODEL_WS2812,            // LED strip model
        .flags.invert_out = false,                // whether to invert the output signal
    };

    // LED strip backend configuration: RMT
    led_strip_rmt_config_t rmt_config = {
#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)
        .rmt_channel = 0,
#else
        .clk_src = RMT_CLK_SRC_DEFAULT,        // different clock source can lead to different power consumption
        .resolution_hz = LED_STRIP_RMT_RES_HZ, // RMT counter clock frequency
        .flags.with_dma = false,               // DMA feature is available on ESP target like ESP32-S3
#endif
    };

    // LED Strip object handle
    led_strip_handle_t led_strip;
    ESP_ERROR_CHECK(led_strip_new_rmt_device(&strip_config, &rmt_config, &led_strip));
    ESP_LOGI(TAG, "Created LED strip object with RMT backend");
    return led_strip;
}

3.2 亮度控制

对于数字 LED,我们可以通过调整发送到 LED 的 RGB 值来控制亮度。降低 RGB 值将降低亮度。


// 设置亮度为 50%
uint8_t brightness = 50; // 百分比
uint8_t red = (255 * brightness) / 100;
uint8_t green = (255 * brightness) / 100;
uint8_t blue = (255 * brightness) / 100;

led_strip_set_pixel(strip, 0, red, green, blue);
led_strip_flush(strip);

3.3 刷新RGB灯数据

将设置好的RGB值传递给led_strip_set_pixel()函数
led_strip_set_pixel 函数通常用于控制 LED 灯带中单个 LED 的颜色。这个函数是 ESP-IDF 中 LED 控制库的一部分,用于设置指定 LED 灯的颜色。
led_strip_flush 函数来更新 LED 灯带,以显示新颜色。
led_strip_clear 函数来清除led灯带,以关闭灯光

在一下这段代码中,在while循环里使用led_strip_set_pixel函数设置WS2812的颜色,使用led_strip_clear函数清除所有像素,每隔500ms重复一次操作

    // 设置亮度为 50%
    uint8_t brightness = 50; // 百分比
    uint8_t red = (0 * brightness) / 100;
    uint8_t green = (0 * brightness) / 100;
    uint8_t blue = (139 * brightness) / 100;

    while (1)
    {
        ESP_LOGI(TAG,"ws2812 test");
        if (led_on_off) {
            /* Set the LED pixel using RGB from 0 (0%) to 255 (100%) for each color */
            for (int i = 0; i < LED_STRIP_LED_NUMBERS; i++) {
                ESP_ERROR_CHECK(led_strip_set_pixel(led_strip, i, red, green, blue));
            }
            /* Refresh the strip to send data */
            ESP_ERROR_CHECK(led_strip_refresh(led_strip));
            ESP_LOGI(TAG, "LED ON!");
        } else {
            /* Set all LED off to clear all pixels */
            ESP_ERROR_CHECK(led_strip_clear(led_strip));
            ESP_LOGI(TAG, "LED OFF!");
        }

        led_on_off = !led_on_off;
        vTaskDelay(pdMS_TO_TICKS(500));
    }

四、代码地址

Github仓库:ws2812

  • 22
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HKElec

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值