implement new light mode (off/day/night/simulation)
missing: - fully connect it to the ui - setup duration in light settings Signed-off-by: Peter Siegmund <developer@mars3142.org>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
idf_component_register(SRCS
|
||||
src/led_manager.cpp
|
||||
src/led_status.c
|
||||
src/led_strip_ws2812.c
|
||||
INCLUDE_DIRS "include"
|
||||
PRIV_REQUIRES
|
||||
insa
|
||||
@@ -8,4 +8,5 @@ idf_component_register(SRCS
|
||||
esp_event
|
||||
esp_timer
|
||||
persistence-manager
|
||||
simulator
|
||||
)
|
||||
|
@@ -10,4 +10,10 @@ menu "Led Manager Configuration"
|
||||
default 2
|
||||
help
|
||||
The number of the status WLED pin.
|
||||
|
||||
config LED_STRIP_MAX_LEDS
|
||||
int "Maximum number of LEDs"
|
||||
default 500
|
||||
help
|
||||
The maximum number of LEDs that can be controlled.
|
||||
endmenu
|
||||
|
12
firmware/components/led-manager/include/color.h
Normal file
12
firmware/components/led-manager/include/color.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t red;
|
||||
uint8_t green;
|
||||
uint8_t blue;
|
||||
} rgb_t;
|
||||
|
||||
void interpolate_color(const rgb_t start_color, const rgb_t end_color, float fraction, rgb_t *out_color);
|
@@ -1,23 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
enum
|
||||
{
|
||||
EVENT_LED_ON,
|
||||
EVENT_LED_OFF,
|
||||
EVENT_LED_DAY,
|
||||
EVENT_LED_NIGHT,
|
||||
EVENT_LED_REFRESH
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int value;
|
||||
} led_event_data_t;
|
||||
|
||||
uint64_t wled_init();
|
||||
|
||||
uint64_t register_handler();
|
||||
|
||||
uint64_t send_event(uint32_t event, led_event_data_t *payload);
|
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "color.h"
|
||||
#include "esp_check.h"
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -14,14 +15,6 @@ typedef enum
|
||||
LED_MODE_BLINK
|
||||
} led_mode_t;
|
||||
|
||||
// Structure for an RGB color
|
||||
typedef struct
|
||||
{
|
||||
uint8_t r;
|
||||
uint8_t g;
|
||||
uint8_t b;
|
||||
} rgb_t;
|
||||
|
||||
// This is the structure you pass from the outside to define a behavior
|
||||
typedef struct
|
||||
{
|
||||
@@ -31,28 +24,23 @@ typedef struct
|
||||
uint32_t off_time_ms; // Only relevant for BLINK
|
||||
} led_behavior_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
/**
|
||||
* @brief Initializes the status manager and the LED strip.
|
||||
*
|
||||
* @param gpio_num GPIO where the data line of the LEDs is connected.
|
||||
* @return esp_err_t ESP_OK on success.
|
||||
*/
|
||||
esp_err_t led_status_init(int gpio_num);
|
||||
__BEGIN_DECLS
|
||||
/**
|
||||
* @brief Initializes the status manager and the LED strip.
|
||||
*
|
||||
* @param gpio_num GPIO where the data line of the LEDs is connected.
|
||||
* @return esp_err_t ESP_OK on success.
|
||||
*/
|
||||
esp_err_t led_status_init(int gpio_num);
|
||||
|
||||
/**
|
||||
* @brief Sets the lighting behavior for a single LED.
|
||||
*
|
||||
* This function is thread-safe.
|
||||
*
|
||||
* @param index Index of the LED (0 to STATUS_LED_COUNT - 1).
|
||||
* @param behavior The structure with the desired behavior.
|
||||
* @return esp_err_t ESP_OK on success, ESP_ERR_INVALID_ARG on invalid index.
|
||||
*/
|
||||
esp_err_t led_status_set_behavior(uint8_t index, led_behavior_t behavior);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
/**
|
||||
* @brief Sets the lighting behavior for a single LED.
|
||||
*
|
||||
* This function is thread-safe.
|
||||
*
|
||||
* @param index Index of the LED (0 to STATUS_LED_COUNT - 1).
|
||||
* @param behavior The structure with the desired behavior.
|
||||
* @return esp_err_t ESP_OK on success, ESP_ERR_INVALID_ARG on invalid index.
|
||||
*/
|
||||
esp_err_t led_status_set_behavior(uint8_t index, led_behavior_t behavior);
|
||||
__END_DECLS
|
||||
|
18
firmware/components/led-manager/include/led_strip_ws2812.h
Normal file
18
firmware/components/led-manager/include/led_strip_ws2812.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "color.h"
|
||||
#include <esp_check.h>
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LED_STATE_OFF,
|
||||
LED_STATE_DAY,
|
||||
LED_STATE_NIGHT,
|
||||
LED_STATE_SIMULATION,
|
||||
} led_state_t;
|
||||
|
||||
__BEGIN_DECLS
|
||||
esp_err_t led_strip_init(void);
|
||||
esp_err_t led_strip_update(led_state_t state, rgb_t color);
|
||||
__END_DECLS
|
8
firmware/components/led-manager/src/color.c
Normal file
8
firmware/components/led-manager/src/color.c
Normal file
@@ -0,0 +1,8 @@
|
||||
#include "color.h"
|
||||
|
||||
void interpolate_color(const rgb_t start_color, const rgb_t end_color, float fraction, rgb_t *out_color)
|
||||
{
|
||||
out_color->r = start_color.r + (end_color.r - start_color.r) * fraction;
|
||||
out_color->g = start_color.g + (end_color.g - start_color.g) * fraction;
|
||||
out_color->b = start_color.b + (end_color.b - start_color.b) * fraction;
|
||||
}
|
@@ -1,112 +0,0 @@
|
||||
#include "led_manager.h"
|
||||
|
||||
#include "common/ColorSettingsMenu.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_log.h"
|
||||
#include "hal_esp32/PersistenceManager.h"
|
||||
#include "led_status.h"
|
||||
#include "led_strip.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
led_strip_handle_t led_strip;
|
||||
|
||||
static const int value = 125;
|
||||
static const uint32_t max_leds = 500;
|
||||
|
||||
ESP_EVENT_DECLARE_BASE(LED_EVENTS_BASE);
|
||||
ESP_EVENT_DEFINE_BASE(LED_EVENTS_BASE);
|
||||
|
||||
esp_event_loop_handle_t loop_handle;
|
||||
|
||||
const char *TAG = "led_manager";
|
||||
|
||||
uint64_t wled_init(void)
|
||||
{
|
||||
led_strip_config_t strip_config = {
|
||||
.strip_gpio_num = CONFIG_WLED_DIN_PIN,
|
||||
.max_leds = max_leds,
|
||||
.led_model = LED_MODEL_WS2812,
|
||||
.color_component_format = LED_STRIP_COLOR_COMPONENT_FMT_GRB,
|
||||
.flags =
|
||||
{
|
||||
.invert_out = false,
|
||||
},
|
||||
};
|
||||
|
||||
led_strip_rmt_config_t rmt_config = {
|
||||
.clk_src = RMT_CLK_SRC_DEFAULT,
|
||||
.resolution_hz = 0,
|
||||
.mem_block_symbols = 0,
|
||||
.flags =
|
||||
{
|
||||
.with_dma = true,
|
||||
},
|
||||
};
|
||||
|
||||
ESP_ERROR_CHECK(led_strip_new_rmt_device(&strip_config, &rmt_config, &led_strip));
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void event_handler(void *arg, esp_event_base_t base, int32_t id, void *event_data)
|
||||
{
|
||||
uint8_t red = 0;
|
||||
uint8_t green = 0;
|
||||
uint8_t blue = 0;
|
||||
|
||||
if (id != EVENT_LED_OFF)
|
||||
{
|
||||
auto persistenceManager = PersistenceManager();
|
||||
persistenceManager.Load();
|
||||
|
||||
auto mode = persistenceManager.GetValue("light_mode", 0);
|
||||
auto light_mode = (mode == 0) ? "day" : "night";
|
||||
red = persistenceManager.GetValue(std::string(ColorSettingsMenuOptions::RED) + light_mode, value);
|
||||
green = persistenceManager.GetValue(std::string(ColorSettingsMenuOptions::GREEN) + light_mode, value);
|
||||
blue = persistenceManager.GetValue(std::string(ColorSettingsMenuOptions::BLUE) + light_mode, value);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < max_leds; i++)
|
||||
{
|
||||
led_strip_set_pixel(led_strip, i, red, green, blue);
|
||||
}
|
||||
led_strip_refresh(led_strip);
|
||||
|
||||
led_behavior_t led2_behavior = {
|
||||
.mode = LED_MODE_SOLID, .color = {.r = red, .g = green, .b = blue}, .on_time_ms = 0, .off_time_ms = 0};
|
||||
led_status_set_behavior(2, led2_behavior);
|
||||
}
|
||||
|
||||
uint64_t register_handler(void)
|
||||
{
|
||||
esp_event_loop_args_t loop_args = {
|
||||
.queue_size = 2, .task_name = "led_manager", .task_priority = 5, .task_stack_size = 4096, .task_core_id = 1};
|
||||
esp_event_loop_create(&loop_args, &loop_handle);
|
||||
|
||||
esp_event_handler_register_with(loop_handle, LED_EVENTS_BASE, ESP_EVENT_ANY_ID, event_handler, NULL);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
uint64_t send_event(uint32_t event, led_event_data_t *payload)
|
||||
{
|
||||
if (payload == nullptr)
|
||||
{
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
esp_err_t err = esp_event_post_to(loop_handle, // Event loop handle
|
||||
LED_EVENTS_BASE, // Event base
|
||||
event, // Event ID (EVENT_LED_ON, EVENT_LED_OFF, etc.)
|
||||
payload, // Data pointer
|
||||
sizeof(led_event_data_t), // Data size
|
||||
portMAX_DELAY // Wait time
|
||||
);
|
||||
|
||||
if (err != ESP_OK)
|
||||
{
|
||||
ESP_LOGE("LED", "Failed to post event: %s", esp_err_to_name(err));
|
||||
return err;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
@@ -46,8 +46,8 @@ static void led_status_task(void *pvParameters)
|
||||
break;
|
||||
|
||||
case LED_MODE_SOLID:
|
||||
led_strip_set_pixel(led_strip, i, control->behavior.color.r, control->behavior.color.g,
|
||||
control->behavior.color.b);
|
||||
led_strip_set_pixel(led_strip, i, control->behavior.color.red, control->behavior.color.green,
|
||||
control->behavior.color.blue);
|
||||
break;
|
||||
|
||||
case LED_MODE_BLINK: {
|
||||
@@ -61,8 +61,8 @@ static void led_status_task(void *pvParameters)
|
||||
|
||||
if (control->is_on_in_blink)
|
||||
{
|
||||
led_strip_set_pixel(led_strip, i, control->behavior.color.r, control->behavior.color.g,
|
||||
control->behavior.color.b);
|
||||
led_strip_set_pixel(led_strip, i, control->behavior.color.red, control->behavior.color.green,
|
||||
control->behavior.color.blue);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -119,7 +119,7 @@ esp_err_t led_status_init(int gpio_num)
|
||||
}
|
||||
|
||||
// Start task
|
||||
xTaskCreate(led_status_task, "led_status_task", 2048, NULL, 5, NULL);
|
||||
xTaskCreate(led_status_task, "led_status_task", 2048, NULL, tskIDLE_PRIORITY + 1, NULL);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
111
firmware/components/led-manager/src/led_strip_ws2812.c
Normal file
111
firmware/components/led-manager/src/led_strip_ws2812.c
Normal file
@@ -0,0 +1,111 @@
|
||||
#include "led_strip_ws2812.h"
|
||||
#include "color.h"
|
||||
#include "led_status.h"
|
||||
#include <esp_log.h>
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/queue.h>
|
||||
#include <freertos/task.h>
|
||||
#include <led_strip.h>
|
||||
#include <sdkconfig.h>
|
||||
|
||||
static const char *TAG = "led_strip";
|
||||
|
||||
static led_strip_handle_t led_strip;
|
||||
static QueueHandle_t led_command_queue;
|
||||
|
||||
static const uint32_t MAX_LEDS = CONFIG_LED_STRIP_MAX_LEDS;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
led_state_t state;
|
||||
rgb_t color;
|
||||
} led_command_t;
|
||||
|
||||
static void set_all_pixels(const rgb_t color)
|
||||
{
|
||||
for (uint32_t i = 0; i < MAX_LEDS; i++)
|
||||
{
|
||||
led_strip_set_pixel(led_strip, i, color.red, color.green, color.blue);
|
||||
}
|
||||
led_strip_refresh(led_strip);
|
||||
|
||||
led_behavior_t led2_behavior = {.mode = LED_MODE_SOLID,
|
||||
.color = {.red = color.red, .green = color.green, .blue = color.blue}};
|
||||
led_status_set_behavior(2, led2_behavior);
|
||||
}
|
||||
|
||||
void led_strip_task(void *pvParameters)
|
||||
{
|
||||
led_state_t current_state = LED_STATE_OFF;
|
||||
led_command_t cmd;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
TickType_t wait_ticks = (current_state == LED_STATE_SIMULATION) ? pdMS_TO_TICKS(50) : portMAX_DELAY;
|
||||
if (xQueueReceive(led_command_queue, &cmd, wait_ticks) == pdPASS)
|
||||
{
|
||||
current_state = cmd.state;
|
||||
}
|
||||
|
||||
rgb_t color;
|
||||
switch (current_state)
|
||||
{
|
||||
case LED_STATE_OFF:
|
||||
color = (rgb_t){.red = 0, .green = 0, .blue = 0};
|
||||
break;
|
||||
default:
|
||||
color = cmd.color;
|
||||
break;
|
||||
}
|
||||
|
||||
set_all_pixels(color);
|
||||
}
|
||||
};
|
||||
|
||||
esp_err_t led_strip_init(void)
|
||||
{
|
||||
led_strip_config_t strip_config = {
|
||||
.strip_gpio_num = CONFIG_WLED_DIN_PIN,
|
||||
.max_leds = MAX_LEDS,
|
||||
.led_model = LED_MODEL_WS2812,
|
||||
.color_component_format = LED_STRIP_COLOR_COMPONENT_FMT_GRB,
|
||||
.flags = {.invert_out = false},
|
||||
};
|
||||
|
||||
led_strip_rmt_config_t rmt_config = {
|
||||
.clk_src = RMT_CLK_SRC_DEFAULT,
|
||||
.resolution_hz = 0,
|
||||
.mem_block_symbols = 0,
|
||||
.flags = {.with_dma = true},
|
||||
};
|
||||
|
||||
ESP_ERROR_CHECK(led_strip_new_rmt_device(&strip_config, &rmt_config, &led_strip));
|
||||
|
||||
led_command_queue = xQueueCreate(5, sizeof(led_command_t));
|
||||
if (led_command_queue == NULL)
|
||||
{
|
||||
ESP_LOGE(TAG, "Failed to create command queue");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
xTaskCreate(led_strip_task, "led_strip_task", 4096, NULL, tskIDLE_PRIORITY + 1, NULL);
|
||||
|
||||
ESP_LOGI(TAG, "LED strip initialized");
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t led_strip_update(led_state_t state, rgb_t color)
|
||||
{
|
||||
led_command_t cmd = {
|
||||
.state = state,
|
||||
.color = color,
|
||||
};
|
||||
|
||||
if (xQueueSend(led_command_queue, &cmd, pdMS_TO_TICKS(100)) != pdPASS)
|
||||
{
|
||||
ESP_LOGE(TAG, "Failed to send command to LED manager queue");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
Reference in New Issue
Block a user