Files
ESPC3-wireless/app/drivers/led_strip/led_strip.c

259 lines
9.3 KiB
C
Raw Normal View History

2025-08-20 11:31:55 +08:00
#include "led_strip.h"
rmt_channel_handle_t led_chan = NULL;
rmt_encoder_handle_t led_encoder = NULL;
rmt_transmit_config_t tx_config = {
.loop_count = 0, // no transfer loop
};
// 颜色结构体
2025-09-15 16:47:11 +08:00
static rgb_color_t expression[EXAMPLE_LED_NUMBERS];
static rgb_color_t expression_lat[EXAMPLE_LED_NUMBERS] = {0};
// 延时计数
2025-09-15 16:47:11 +08:00
static uint16_t rgb_toggle_cnt[EXAMPLE_LED_NUMBERS] = {10,10};
static uint16_t rgb_toggle_cnt_lat[EXAMPLE_LED_NUMBERS] = {2000,2000};
2025-09-15 16:47:11 +08:00
2025-08-20 11:31:55 +08:00
static uint8_t led_strip_pixels[EXAMPLE_LED_NUMBERS * 3];
uint16_t toggle_cycle = 1000;
// 翻转标志位
2025-09-15 16:47:11 +08:00
bool toggle_flag[EXAMPLE_LED_NUMBERS] = {true,true};
bool toggle_flag_lat[EXAMPLE_LED_NUMBERS] = {true,true};
2025-09-15 16:47:11 +08:00
2025-10-28 11:25:13 +08:00
rgb_color_t rgb_color_none = {0,0,0,0,0,1,0,RGB_COLOR_NONE};
2025-09-15 16:47:11 +08:00
rgb_color_t rgb_color_rad = {0,255,0,0,0,1,0,RGB_COLOR_RAD};
rgb_color_t rgb_color_orange = {0,255,80,0,0,1,0,RGB_COLOR_ORANGE};
rgb_color_t rgb_color_green = {0,0,255,0,0,1,0,RGB_COLOR_GREEN};
rgb_color_t rgb_color_blue = {0,0,0,255,0,1,0,RGB_COLOR_BLUE};
rgb_color_t rgb_color_cyan = {0,0,255,255,0,1,0,RGB_COLOR_CYAN};
rgb_color_t rgb_color_purple = {0,255,0,255,0,1,0,RGB_COLOR_PURPLE};
rgb_color_t rgb_color_white = {0,255,255,255,0,1,0,RGB_COLOR_WHITE};
rgb_color_t rgb_color_green_white = {0,0,255,0,0,2,20,RGB_COLOR_GREEN_WHITE};
rgb_color_t rgb_color_green_purple = {0,0,255,0,0,2,20,RGB_COLOR_GREEN_PURPLE};
2025-08-20 11:31:55 +08:00
void led_strip_init(void)
{
// ESP_LOGI(TAG, "Create RMT TX channel");
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");
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");
2025-09-15 16:47:11 +08:00
rgb_color_change(0,RGB_COLOR_ORANGE);
rgb_color_change(1,RGB_COLOR_ORANGE);
2025-08-20 11:31:55 +08:00
}
void led_strip_set_pixel(uint8_t pin, uint8_t index, uint8_t green, uint8_t blue, uint8_t red)
{
led_strip_pixels[0 + index * 3] = green;
led_strip_pixels[1 + index * 3] = red;
led_strip_pixels[2 + index * 3] = blue;
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));
}
void work_rgb_led_start(void)
{
led_strip_init();
/* 创建 shell 的接收任务 _work_sh() */
static os_work_t work_handler_rgb_led;
os_work_create(&work_handler_rgb_led, "work-rgb-led", _work_rgb_led, NULL, OS_PRIORITY_NORMAL);
os_work_submit(default_os_work_q_hdl, &work_handler_rgb_led, toggle_cycle * 0.5);
}
void _work_rgb_led(void *arg)
{
2025-09-15 16:47:11 +08:00
static uint16_t rgb_toggle_cnt_update[EXAMPLE_LED_NUMBERS] = {10,10};
if(!rgb_toggle_cnt_update[0]--)
2025-08-20 11:31:55 +08:00
{
2025-09-15 16:47:11 +08:00
rgb_toggle_cnt_update[0] = rgb_toggle_cnt[0];
rgb_toggle(0,&expression[0]);
2025-08-20 11:31:55 +08:00
}
2025-09-15 16:47:11 +08:00
if(!rgb_toggle_cnt_update[1]--)
{
rgb_toggle_cnt_update[1] = rgb_toggle_cnt[1];
rgb_toggle(1,&expression[1]);
}
os_work_later(WORD_TIME_MS);
2025-08-20 11:31:55 +08:00
}
2025-09-15 16:47:11 +08:00
void rgb_update_cyle(uint8_t index, uint16_t cyle)
2025-08-20 11:31:55 +08:00
{
2025-09-15 16:47:11 +08:00
toggle_flag[index] = (cyle == 888 ? false : true);
2025-08-29 11:09:37 +08:00
2025-09-15 16:47:11 +08:00
rgb_toggle_cnt[index] = cyle / WORD_TIME_MS - 1;
}
void rgb_color_change(uint8_t index, uint8_t color)
{
static uint8_t rgb_color_lat[EXAMPLE_LED_NUMBERS] = {0};
if(rgb_color_lat[index] != color)
{
switch(color)
{
2025-10-28 11:25:13 +08:00
case RGB_COLOR_NONE:
memcpy(&expression[index], &rgb_color_none, sizeof(rgb_color_none));
break;
case RGB_COLOR_RAD:
memcpy(&expression[index], &rgb_color_rad, sizeof(rgb_color_rad));
break;
case RGB_COLOR_ORANGE:
memcpy(&expression[index], &rgb_color_orange, sizeof(rgb_color_orange));
break;
case RGB_COLOR_GREEN:
memcpy(&expression[index], &rgb_color_green, sizeof(rgb_color_green));
break;
case RGB_COLOR_WHITE:
memcpy(&expression[index], &rgb_color_white, sizeof(rgb_color_white));
break;
case RGB_COLOR_PURPLE:
memcpy(&expression[index], &rgb_color_purple, sizeof(rgb_color_purple));
break;
case RGB_COLOR_CYAN:
memcpy(&expression[index], &rgb_color_cyan, sizeof(rgb_color_cyan));
break;
case RGB_COLOR_BLUE:
memcpy(&expression[index], &rgb_color_blue, sizeof(rgb_color_blue));
break;
case RGB_COLOR_GREEN_WHITE:
memcpy(&expression[index], &rgb_color_green_white, sizeof(rgb_color_green_white));
break;
case RGB_COLOR_GREEN_PURPLE:
memcpy(&expression[index], &rgb_color_green_purple, sizeof(rgb_color_green_purple));
break;
default:
break;
}
expression[index].index = index;
rgb_color_lat[index] = color;
}
2025-08-20 11:31:55 +08:00
}
2025-09-15 16:47:11 +08:00
void rgb_toggle(uint8_t index, rgb_color_t* rgb_color)
2025-08-29 11:08:30 +08:00
{
2025-09-15 16:47:11 +08:00
if(rgb_color->color_cnt > 1)
{
breathing_color_change(index,rgb_color);
led_strip_set_pixel(0,rgb_color->index,rgb_color->green,rgb_color->blue,rgb_color->red);
return;
}
if(rgb_color->toggle_flag == 0)
led_strip_set_pixel(0,rgb_color->index,rgb_color->green,rgb_color->blue,rgb_color->red);
else
led_strip_set_pixel(0,rgb_color->index,0,0,0);
if(toggle_flag[index] == true)
rgb_color->toggle_flag = !rgb_color->toggle_flag;
}
uint8_t breathing_dispose(uint8_t index, rgb_color_t* rgb_color,int16_t* vel, uint8_t color_min, uint8_t color_max)
{
static int dir[EXAMPLE_LED_NUMBERS] = {1,1}, color_dir[EXAMPLE_LED_NUMBERS] = {1,1}, color_cnt[EXAMPLE_LED_NUMBERS] = {0,0};
*vel += dir[index] * rgb_color->colortoggle_speed;
if(*vel > color_max){*vel = color_max; dir[index] = -1;}
else if(*vel < color_min){*vel = color_min; dir[index] = 1; color_cnt[index] += color_dir[index];}
2025-08-29 11:08:30 +08:00
2025-09-15 16:47:11 +08:00
if(color_cnt[index] >= rgb_color->color_cnt -1 )
color_dir[index] = -1;
else if(color_cnt[index] <= 0)
color_dir[index] = 1;
2025-08-29 11:08:30 +08:00
2025-09-15 16:47:11 +08:00
return color_cnt[index];
2025-08-29 11:08:30 +08:00
}
2025-09-15 16:47:11 +08:00
void breathing_color_change(uint8_t index, rgb_color_t* rgb_color)
2025-08-29 11:08:30 +08:00
{
2025-09-15 16:47:11 +08:00
static int16_t COLOR_SUM[EXAMPLE_LED_NUMBERS];
uint8_t color_cnt = breathing_dispose(index, rgb_color, &COLOR_SUM[index], 0, 255);
switch (rgb_color->color_type)
2025-08-29 11:08:30 +08:00
{
case RGB_COLOR_GREEN_WHITE:
{
switch(color_cnt)
{
case 0:
{
rgb_color->red = 0;
2025-09-15 16:47:11 +08:00
rgb_color->green = (uint8_t)COLOR_SUM[index];
2025-08-29 11:08:30 +08:00
rgb_color->blue = 0;
break;
}
case 1:
{
2025-09-15 16:47:11 +08:00
rgb_color->red = (uint8_t)COLOR_SUM[index];
rgb_color->green = (uint8_t)COLOR_SUM[index];
rgb_color->blue = (uint8_t)COLOR_SUM[index];
2025-08-29 11:08:30 +08:00
break;
}
}
break;
}
case RGB_COLOR_GREEN_PURPLE:
{
switch(color_cnt)
{
case 0:
{
rgb_color->red = 0;
2025-09-15 16:47:11 +08:00
rgb_color->green = (uint8_t)COLOR_SUM[index];
2025-08-29 11:08:30 +08:00
rgb_color->blue = 0;
break;
}
case 1:
{
2025-09-15 16:47:11 +08:00
rgb_color->red = (uint8_t)COLOR_SUM[index];
2025-08-29 11:08:30 +08:00
rgb_color->green = 0;
2025-09-15 16:47:11 +08:00
rgb_color->blue = (uint8_t)COLOR_SUM[index];
2025-08-29 11:08:30 +08:00
break;
}
}
break;
}
default:
break;
}
}
2025-09-10 10:19:53 +08:00
void rgb_Indicator_light_on(uint8_t index, uint8_t color, uint16_t cyle)
{
2025-09-15 16:47:11 +08:00
if(expression_lat[index].color_type == 0 && expression_lat[index].color_type != color)
2025-09-10 10:19:53 +08:00
{
2025-09-15 16:47:11 +08:00
memcpy(&expression_lat[index], &expression[index], sizeof(rgb_color_t));
2025-09-10 10:19:53 +08:00
rgb_color_change(index, color);
}
// 设置较大的时间计数,防止数值被轻易到达
if(rgb_toggle_cnt_lat[index] == 2000 )
2025-09-10 10:19:53 +08:00
{
2025-09-15 16:47:11 +08:00
rgb_toggle_cnt_lat[index] = rgb_toggle_cnt[index];
printf("rgb_toggle_cnt[index]:%d\n",rgb_toggle_cnt[index]);
2025-09-15 16:47:11 +08:00
rgb_update_cyle(index, cyle);
2025-09-10 10:19:53 +08:00
}
if(toggle_flag[index] == false)
{
toggle_flag_lat[index] = !toggle_flag_lat[index];
toggle_flag[index] = !toggle_flag[index];
}
2025-09-10 10:19:53 +08:00
}
void rgb_Indicator_light_off(uint8_t index)
{
2025-09-15 16:47:11 +08:00
rgb_color_change(index, expression_lat[index].color_type);
rgb_update_cyle(index,(rgb_toggle_cnt_lat[index] + 1) * WORD_TIME_MS );
toggle_flag[index] = toggle_flag_lat[index];
2025-09-15 16:47:11 +08:00
memset(&expression_lat[index], 0, sizeof(rgb_color_t));
rgb_toggle_cnt_lat[index] = 2000;
2025-09-15 16:47:11 +08:00
}