led_strip例程分析

/*
 * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
 *
 * SPDX-License-Identifier: Unlicense OR CC0-1.0
 */
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "driver/rmt_tx.h"
#include "led_strip_encoder.h"


#define RMT_LED_STRIP_RESOLUTION_HZ 10000000 // 10MHz resolution, 1 tick = 0.1us (led strip needs a high resolution)
#define RMT_LED_STRIP_GPIO_NUM      7

#define EXAMPLE_LED_NUMBERS         16
#define EXAMPLE_CHASE_SPEED_MS      10

static const char *TAG = "example";

static uint8_t led_strip_pixels[(EXAMPLE_LED_NUMBERS) * 3];//数组来LED的RGB值 3的倍数

/**
 * @brief Simple helper function, converting HSV color space to RGB color space
 *
 * Wiki: https://en.wikipedia.org/wiki/HSL_and_HSV
 *
 */
void led_strip_hsv2rgb(uint32_t h, uint32_t s, uint32_t v, uint32_t *r, uint32_t *g, uint32_t *b)
{
    h %= 360; // h -> [0,360]
    uint32_t rgb_max = v * 2.55f;
    uint32_t rgb_min = rgb_max * (100 - s) / 100.0f;

    uint32_t i = h / 60;
    uint32_t diff = h % 60;

    // RGB adjustment amount by hue
    uint32_t rgb_adj = (rgb_max - rgb_min) * diff / 60;
    
    switch (i) {
    case 0:
        *r = rgb_max;
        *g = rgb_min + rgb_adj;
        *b = rgb_min;
        break;
    case 1:
        *r = rgb_max - rgb_adj;
        *g = rgb_max;
        *b = rgb_min;
        break;
    case 2:
        *r = rgb_min;
        *g = rgb_max;
        *b = rgb_min + rgb_adj;
        break;
    case 3:
        *r = rgb_min;
        *g = rgb_max - rgb_adj;
        *b = rgb_max;
        break;
    case 4:
        *r = rgb_min + rgb_adj;
        *g = rgb_min;
        *b = rgb_max;
        break;
    default:
        *r = rgb_max;
        *g = rgb_min;
        *b = rgb_max - rgb_adj;
        break;
    }
}

void app_main(void)
{
    uint32_t red = 0;
    uint32_t green = 0;
    uint32_t blue = 0;
    uint16_t hue = 0;
    uint16_t start_rgb = 0;

    ESP_LOGI(TAG, "Create RMT TX channel");
    rmt_channel_handle_t led_chan = NULL;
    rmt_tx_channel_config_t tx_chan_config = {
        .clk_src = RMT_CLK_SRC_DEFAULT, // select source clock
        .gpio_num = RMT_LED_STRIP_GPIO_NUM,
        .mem_block_symbols = 64, // increase the block size can make the LED less flickering
        .resolution_hz = RMT_LED_STRIP_RESOLUTION_HZ,
        .trans_queue_depth = 4, // set the number of transactions that can be pending in the background
    };
    ESP_ERROR_CHECK(rmt_new_tx_channel(&tx_chan_config, &led_chan));

    ESP_LOGI(TAG, "Install led strip encoder");
    ESP_LOGI(TAG, "Install led strip gpio is %d",RMT_LED_STRIP_GPIO_NUM);
    rmt_encoder_handle_t led_encoder = NULL;
    led_strip_encoder_config_t encoder_config = {
        .resolution = RMT_LED_STRIP_RESOLUTION_HZ,
    };
    ESP_ERROR_CHECK(rmt_new_led_strip_encoder(&encoder_config, &led_encoder));

    ESP_LOGI(TAG, "Enable RMT TX channel");
    ESP_ERROR_CHECK(rmt_enable(led_chan));

    ESP_LOGI(TAG, "Start LED rainbow chase");
    rmt_transmit_config_t tx_config = {
        .loop_count = 0, // no transfer loop
    };
    while (1) {
        for (int i = 0; i < 3; i++) {//i小于3是因为 下层循环j+=3 关系到的是led_strip_pixels[]这个数组的元素分配
        //比如i=0,j取值 0,3,6,9等等,那i=1,2就j的取值就能覆盖所有example_led_number了 
            for (int j = i;  j < EXAMPLE_LED_NUMBERS; j += 3) {//每次外层i循环进来都走一次 int j=i;
                // Build RGB pixels
                hue = j * 360 / EXAMPLE_LED_NUMBERS + start_rgb;
                led_strip_hsv2rgb(hue, 100, 25, &red, &green, &blue);
                led_strip_pixels[j * 3 + 0] = green;
                led_strip_pixels[j * 3 + 1] = blue;
                led_strip_pixels[j * 3 + 2] = red;
            }
            // Flush RGB values to LEDs
            ESP_ERROR_CHECK(rmt_transmit(led_chan, led_encoder, led_strip_pixels, sizeof(led_strip_pixels), &tx_config));
            ESP_ERROR_CHECK(rmt_tx_wait_all_done(led_chan, portMAX_DELAY));
            vTaskDelay(pdMS_TO_TICKS(EXAMPLE_CHASE_SPEED_MS));
            memset(led_strip_pixels, 0, sizeof(led_strip_pixels));//用0来pixels的数据,实现的效果就是灯不亮
            ESP_ERROR_CHECK(rmt_transmit(led_chan, led_encoder, led_strip_pixels, sizeof(led_strip_pixels), &tx_config));
            ESP_ERROR_CHECK(rmt_tx_wait_all_done(led_chan, portMAX_DELAY));
            vTaskDelay(pdMS_TO_TICKS(EXAMPLE_CHASE_SPEED_MS));
        }
        start_rgb += 60;
    }
}

参数定义:

h:色调(Hue),取值范围通常是[0, 360)。但在这里,代码通过h %= 360;确保了h的值在[0, 360)范围内。
s:饱和度(Saturation),取值范围通常是[0, 100]或[0, 1](这里假设是[0, 100])。
v:亮度(Value/Brightness),取值范围通常是[0, 100]或[0, 1](这里假设是[0, 100])。
r, g, b:这三个是指针,用于存储转换后的RGB值。
计算RGB的最大值和最小值:

rgb_max:基于亮度v计算RGB中的最大值。
rgb_min:基于亮度和饱和度计算RGB中的最小值。
计算i和diff:

i:表示h在哪个RGB扇区(总共有6个扇区)。
diff:表示h在当前扇区内的偏移量。
计算RGB调整量

rgb_adj:基于diff和rgb_max、rgb_min的差值计算RGB的调整量。
根据i的值设置RGB值:

使用switch语句根据i的值来设置r、g、b的值。这里对应了HSV颜色空间中的6个扇区。

增加串口输入灯光延迟时间跟亮度,两个数据中间空格隔开 回车结束输入

/*
 * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
 *
 * SPDX-License-Identifier: Unlicense OR CC0-1.0
 */
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "driver/rmt_tx.h"
#include "led_strip_encoder.h"
#include "driver/uart.h"

#define UART_NUM UART_NUM_0 // 假设我们使用UART0
#define BUF_SIZE 256 // 读取缓冲区大小

#define RMT_LED_STRIP_RESOLUTION_HZ 10000000 // 10MHz resolution, 1 tick = 0.1us (led strip needs a high resolution)
#define RMT_LED_STRIP_GPIO_NUM      7

#define EXAMPLE_LED_NUMBERS         16
int EXAMPLE_CHASE_SPEED_MS  =  10;

int EXAMPLE_V = 25;

static const char *TAG = "example";

static uint8_t led_strip_pixels[(EXAMPLE_LED_NUMBERS) * 3];//数组来LED的RGB值 3的倍数

/**
 * @brief Simple helper function, converting HSV color space to RGB color space
 *
 * Wiki: https://en.wikipedia.org/wiki/HSL_and_HSV
 *
 */
void led_strip_hsv2rgb(uint32_t h, uint32_t s, uint32_t v, uint32_t *r, uint32_t *g, uint32_t *b)
{
    h %= 360; // h -> [0,360]
    uint32_t rgb_max = v * 2.55f;
    uint32_t rgb_min = rgb_max * (100 - s) / 100.0f;

    uint32_t i = h / 60;
    uint32_t diff = h % 60;

    // RGB adjustment amount by hue
    uint32_t rgb_adj = (rgb_max - rgb_min) * diff / 60;
    
    switch (i) {
    case 0:
        *r = rgb_max;
        *g = rgb_min + rgb_adj;
        *b = rgb_min;
        break;
    case 1:
        *r = rgb_max - rgb_adj;
        *g = rgb_max;
        *b = rgb_min;
        break;
    case 2:
        *r = rgb_min;
        *g = rgb_max;
        *b = rgb_min + rgb_adj;
        break;
    case 3:
        *r = rgb_min;
        *g = rgb_max - rgb_adj;
        *b = rgb_max;
        break;
    case 4:
        *r = rgb_min + rgb_adj;
        *g = rgb_min;
        *b = rgb_max;
        break;
    default:
        *r = rgb_max;
        *g = rgb_min;
        *b = rgb_max - rgb_adj;
        break;
    }
}

// UART读取任务
void uart_read_task(void *pvParameters)
{
    uint8_t data[BUF_SIZE];
    size_t len;

    while (1) {
        // 读取UART数据
        len = uart_read_bytes(UART_NUM, data, sizeof(data), 100 / portTICK_PERIOD_MS);

        if (len > 0) {
            // 处理接收到的数据

            char *token = strtok((char *)data, " ");

            if (token != NULL) {
                EXAMPLE_CHASE_SPEED_MS = atoi(token);
                token = strtok(NULL, " ");
            }

            if (token != NULL) {
                EXAMPLE_V = atoi(token);
                token = strtok(NULL, " ");
            }
        printf("\n");
        memset(data, 0, BUF_SIZE);
        }
    }
}

void app_main(void)
{
    uint32_t red = 0;
    uint32_t green = 0;
    uint32_t blue = 0;
    uint16_t hue = 0;
    uint16_t start_rgb = 0;

    ESP_LOGI(TAG, "Create RMT TX channel");
    rmt_channel_handle_t led_chan = NULL;
    rmt_tx_channel_config_t tx_chan_config = {
        .clk_src = RMT_CLK_SRC_DEFAULT, // select source clock
        .gpio_num = RMT_LED_STRIP_GPIO_NUM,
        .mem_block_symbols = 64, // increase the block size can make the LED less flickering
        .resolution_hz = RMT_LED_STRIP_RESOLUTION_HZ,
        .trans_queue_depth = 4, // set the number of transactions that can be pending in the background
    };
    ESP_ERROR_CHECK(rmt_new_tx_channel(&tx_chan_config, &led_chan));

    ESP_LOGI(TAG, "Install led strip encoder");
    ESP_LOGI(TAG, "Install led strip gpio is %d",RMT_LED_STRIP_GPIO_NUM);
    rmt_encoder_handle_t led_encoder = NULL;
    led_strip_encoder_config_t encoder_config = {
        .resolution = RMT_LED_STRIP_RESOLUTION_HZ,
    };
    ESP_ERROR_CHECK(rmt_new_led_strip_encoder(&encoder_config, &led_encoder));

    ESP_LOGI(TAG, "Enable RMT TX channel");
    ESP_ERROR_CHECK(rmt_enable(led_chan));

    ESP_LOGI(TAG, "Start LED rainbow chase");
    rmt_transmit_config_t tx_config = {
        .loop_count = 0, // no transfer loop
    };

        // UART配置
    uart_config_t uart_config = {
        .baud_rate = 115200,
        .data_bits = UART_DATA_8_BITS,
        .parity = UART_PARITY_DISABLE,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE
    };
    // 设置UART参数
    ESP_ERROR_CHECK(uart_param_config(UART_NUM, &uart_config));

    // 安装UART驱动
    ESP_ERROR_CHECK(uart_driver_install(UART_NUM, BUF_SIZE * 2, 0, 0, NULL, 0));

    // 创建UART读取任务
    xTaskCreate(&uart_read_task, "uart_read_task", 2048, NULL, 10, NULL);
    while (1) {
        for (int i = 0; i < 4; i++) {//i小于3是因为 下层循环j+=3 关系到的是led_strip_pixels[]这个数组的元素分配
        //比如i=0,j取值 0,3,6,9等等,那i=1,2就j的取值就能覆盖所有example_led_number了 
            for (int j = i;  j < EXAMPLE_LED_NUMBERS; j += 4) {//每次外层i循环进来都走一次 int j=i;
                // Build RGB pixels
                hue = j * 360 / EXAMPLE_LED_NUMBERS + start_rgb;
                led_strip_hsv2rgb(hue, 100, EXAMPLE_V, &red, &green, &blue);
                led_strip_pixels[j * 3 + 0] = green;
                led_strip_pixels[j * 3 + 1] = blue;
                led_strip_pixels[j * 3 + 2] = red;
            }
            // Flush RGB values to LEDs
            ESP_ERROR_CHECK(rmt_transmit(led_chan, led_encoder, led_strip_pixels, sizeof(led_strip_pixels), &tx_config));
            ESP_ERROR_CHECK(rmt_tx_wait_all_done(led_chan, portMAX_DELAY));
            vTaskDelay(pdMS_TO_TICKS(EXAMPLE_CHASE_SPEED_MS));
            memset(led_strip_pixels, 0, sizeof(led_strip_pixels));//用0来pixels的数据,实现的效果就是灯不亮
            ESP_ERROR_CHECK(rmt_transmit(led_chan, led_encoder, led_strip_pixels, sizeof(led_strip_pixels), &tx_config));
            ESP_ERROR_CHECK(rmt_tx_wait_all_done(led_chan, portMAX_DELAY));
            vTaskDelay(pdMS_TO_TICKS(EXAMPLE_CHASE_SPEED_MS));
        }
        start_rgb += 60;
    }
}

相关推荐

  1. led_strip分析

    2024-07-10 14:50:04       16 阅读
  2. esp32idf使用thingscloud

    2024-07-10 14:50:04       51 阅读
  3. 【issue-halcon学习】ball.hdev

    2024-07-10 14:50:04       38 阅读
  4. 【issue-halcon学习】fin.hdev

    2024-07-10 14:50:04       62 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-10 14:50:04       52 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-10 14:50:04       54 阅读
  3. 在Django里面运行非项目文件

    2024-07-10 14:50:04       45 阅读
  4. Python语言-面向对象

    2024-07-10 14:50:04       55 阅读

热门阅读

  1. 一个用于在虚拟桌面下跑chrome的docker镜像

    2024-07-10 14:50:04       17 阅读
  2. 东方通Tongweb发布vue前端,HSTS漏洞修复

    2024-07-10 14:50:04       17 阅读
  3. 【无标题】

    2024-07-10 14:50:04       17 阅读
  4. Redis教程(二十三):Redis的底层数据结构

    2024-07-10 14:50:04       21 阅读
  5. 博客网站目录网址导航自适应主题php源码

    2024-07-10 14:50:04       18 阅读
  6. 这道笔试题,给了我一点小小的c语言震撼

    2024-07-10 14:50:04       16 阅读
  7. python压缩PDF方案(Ghostscript+pdfc)

    2024-07-10 14:50:04       19 阅读