starting status WLEDs behavior
Signed-off-by: Peter Siegmund <developer@mars3142.org>
This commit is contained in:
2
firmware/.gitignore
vendored
2
firmware/.gitignore
vendored
@@ -1,5 +1,6 @@
|
|||||||
# esp-idf
|
# esp-idf
|
||||||
build/
|
build/
|
||||||
|
build-release/
|
||||||
managed_components/
|
managed_components/
|
||||||
sdkconfig
|
sdkconfig
|
||||||
sdkconfig.old
|
sdkconfig.old
|
||||||
@@ -16,7 +17,6 @@ cmake_install.cmake
|
|||||||
install_manifest.txt
|
install_manifest.txt
|
||||||
CMakeFiles/
|
CMakeFiles/
|
||||||
CTestTestfile.cmake
|
CTestTestfile.cmake
|
||||||
Makefile
|
|
||||||
CMakeScripts
|
CMakeScripts
|
||||||
compile_commands.json
|
compile_commands.json
|
||||||
|
|
||||||
|
15
firmware/.vscode/launch.json
vendored
Normal file
15
firmware/.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"type": "gdbtarget",
|
||||||
|
"request": "attach",
|
||||||
|
"name": "Eclipse CDT GDB Adapter"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "espidf",
|
||||||
|
"name": "Launch",
|
||||||
|
"request": "launch"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
2
firmware/Makefile
Normal file
2
firmware/Makefile
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
release:
|
||||||
|
idf.py -B build-release -DSDKCONFIG_DEFAULTS="sdkconfig.defaults;sdkconfig.release" fullclean build
|
@@ -1,4 +1,4 @@
|
|||||||
# Definiere die Quelldateien in einer Variable
|
# Define the source files in a variable
|
||||||
set(SOURCE_FILES
|
set(SOURCE_FILES
|
||||||
src/common/InactivityTracker.cpp
|
src/common/InactivityTracker.cpp
|
||||||
src/common/Menu.cpp
|
src/common/Menu.cpp
|
||||||
|
@@ -6,6 +6,7 @@ if (DEFINED ENV{IDF_PATH})
|
|||||||
PRIV_REQUIRES
|
PRIV_REQUIRES
|
||||||
u8g2
|
u8g2
|
||||||
esp_event
|
esp_event
|
||||||
|
esp_timer
|
||||||
persistence-manager
|
persistence-manager
|
||||||
)
|
)
|
||||||
return()
|
return()
|
||||||
|
@@ -1,3 +1,51 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
void led_status_init();
|
#include "driver/rmt_tx.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// Number of LEDs to be controlled
|
||||||
|
#define STATUS_LED_COUNT 3
|
||||||
|
|
||||||
|
// Possible lighting modes
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
LED_MODE_OFF,
|
||||||
|
LED_MODE_SOLID,
|
||||||
|
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
|
||||||
|
{
|
||||||
|
led_mode_t mode;
|
||||||
|
rgb_t color;
|
||||||
|
uint32_t on_time_ms = 0; // Only relevant for BLINK
|
||||||
|
uint32_t off_time_ms = 0; // Only relevant for BLINK
|
||||||
|
} led_behavior_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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);
|
||||||
|
@@ -18,20 +18,26 @@ const char *TAG = "LED";
|
|||||||
|
|
||||||
uint64_t wled_init(void)
|
uint64_t wled_init(void)
|
||||||
{
|
{
|
||||||
led_strip_config_t strip_config = {.strip_gpio_num = CONFIG_WLED_DIN_PIN,
|
led_strip_config_t strip_config = {
|
||||||
|
.strip_gpio_num = CONFIG_WLED_DIN_PIN,
|
||||||
.max_leds = 64,
|
.max_leds = 64,
|
||||||
.led_model = LED_MODEL_WS2812,
|
.led_model = LED_MODEL_WS2812,
|
||||||
.color_component_format = LED_STRIP_COLOR_COMPONENT_FMT_GRB,
|
.color_component_format = LED_STRIP_COLOR_COMPONENT_FMT_GRB,
|
||||||
.flags = {
|
.flags =
|
||||||
|
{
|
||||||
.invert_out = false,
|
.invert_out = false,
|
||||||
}};
|
},
|
||||||
|
};
|
||||||
|
|
||||||
led_strip_rmt_config_t rmt_config = {.clk_src = RMT_CLK_SRC_DEFAULT,
|
led_strip_rmt_config_t rmt_config = {
|
||||||
|
.clk_src = RMT_CLK_SRC_DEFAULT,
|
||||||
.resolution_hz = 0,
|
.resolution_hz = 0,
|
||||||
.mem_block_symbols = 0,
|
.mem_block_symbols = 0,
|
||||||
.flags = {
|
.flags =
|
||||||
|
{
|
||||||
.with_dma = true,
|
.with_dma = true,
|
||||||
}};
|
},
|
||||||
|
};
|
||||||
|
|
||||||
ESP_ERROR_CHECK(led_strip_new_rmt_device(&strip_config, &rmt_config, &led_strip));
|
ESP_ERROR_CHECK(led_strip_new_rmt_device(&strip_config, &rmt_config, &led_strip));
|
||||||
|
|
||||||
@@ -74,12 +80,12 @@ uint64_t send_event(uint32_t event, led_event_data_t *payload)
|
|||||||
return ESP_ERR_INVALID_ARG;
|
return ESP_ERR_INVALID_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t err = esp_event_post_to(loop_handle, // Event-Loop Handle
|
esp_err_t err = esp_event_post_to(loop_handle, // Event loop handle
|
||||||
LED_EVENTS_BASE, // Event Base
|
LED_EVENTS_BASE, // Event base
|
||||||
event, // Event ID (EVENT_LED_ON, EVENT_LED_OFF, etc.)
|
event, // Event ID (EVENT_LED_ON, EVENT_LED_OFF, etc.)
|
||||||
payload, // Daten-Pointer
|
payload, // Data pointer
|
||||||
sizeof(led_event_data_t), // Datengröße
|
sizeof(led_event_data_t), // Data size
|
||||||
portMAX_DELAY // Wartezeit
|
portMAX_DELAY // Wait time
|
||||||
);
|
);
|
||||||
|
|
||||||
if (err != ESP_OK)
|
if (err != ESP_OK)
|
||||||
|
@@ -1,7 +1,145 @@
|
|||||||
#include "led_status.h"
|
#include "led_status.h"
|
||||||
|
|
||||||
void led_status_init()
|
#include "esp_log.h"
|
||||||
|
#include "esp_timer.h" // For high-resolution timestamps
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/semphr.h"
|
||||||
|
#include "freertos/task.h"
|
||||||
|
#include "led_strip.h"
|
||||||
|
|
||||||
|
static const char *TAG = "LED_STATUS";
|
||||||
|
|
||||||
|
// Internal control structure for each LED
|
||||||
|
typedef struct
|
||||||
{
|
{
|
||||||
// This function is intentionally left empty for the native implementation.
|
led_behavior_t behavior; // The desired behavior (target state)
|
||||||
// It serves as a placeholder to maintain compatibility with the HAL interface.
|
uint64_t last_toggle_time_us; // Timestamp of the last toggle (in microseconds)
|
||||||
|
bool is_on_in_blink; // Current state in blink mode (actual state)
|
||||||
|
} led_control_t;
|
||||||
|
|
||||||
|
// --- Module variables ---
|
||||||
|
static led_strip_handle_t led_strip;
|
||||||
|
static led_control_t led_controls[STATUS_LED_COUNT];
|
||||||
|
static SemaphoreHandle_t mutex; // To protect the led_controls array
|
||||||
|
|
||||||
|
// The core: The task that controls the LEDs
|
||||||
|
static void led_status_task(void *pvParameters)
|
||||||
|
{
|
||||||
|
ESP_LOGI(TAG, "Led Status Task started.");
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
uint64_t now_us = esp_timer_get_time();
|
||||||
|
|
||||||
|
// Take the mutex to safely access the control data
|
||||||
|
if (xSemaphoreTake(mutex, portMAX_DELAY) == pdTRUE)
|
||||||
|
{
|
||||||
|
|
||||||
|
for (int i = 0; i < STATUS_LED_COUNT; i++)
|
||||||
|
{
|
||||||
|
led_control_t *control = &led_controls[i];
|
||||||
|
|
||||||
|
switch (control->behavior.mode)
|
||||||
|
{
|
||||||
|
case LED_MODE_OFF:
|
||||||
|
led_strip_set_pixel(led_strip, i, 0, 0, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LED_MODE_SOLID:
|
||||||
|
led_strip_set_pixel(led_strip, i, control->behavior.color.r, control->behavior.color.g,
|
||||||
|
control->behavior.color.b);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LED_MODE_BLINK: {
|
||||||
|
uint32_t duration_ms =
|
||||||
|
control->is_on_in_blink ? control->behavior.on_time_ms : control->behavior.off_time_ms;
|
||||||
|
if ((now_us - control->last_toggle_time_us) / 1000 >= duration_ms)
|
||||||
|
{
|
||||||
|
control->is_on_in_blink = !control->is_on_in_blink; // Toggle state
|
||||||
|
control->last_toggle_time_us = now_us; // Update timestamp
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
led_strip_set_pixel(led_strip, i, 0, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Release the mutex
|
||||||
|
xSemaphoreGive(mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the physical LED strip with the new values
|
||||||
|
led_strip_refresh(led_strip);
|
||||||
|
|
||||||
|
// Delay task for 20ms before the next iteration
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(20));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialization function
|
||||||
|
esp_err_t led_status_init(int gpio_num)
|
||||||
|
{
|
||||||
|
// LED strip configuration (e.g., for WS2812)
|
||||||
|
led_strip_config_t strip_config = {
|
||||||
|
.strip_gpio_num = gpio_num,
|
||||||
|
.max_leds = STATUS_LED_COUNT,
|
||||||
|
.led_model = LED_MODEL_WS2812,
|
||||||
|
.color_component_format = LED_STRIP_COLOR_COMPONENT_FMT_GRBW,
|
||||||
|
.flags =
|
||||||
|
{
|
||||||
|
.invert_out = false,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
led_strip_rmt_config_t rmt_config = {
|
||||||
|
.clk_src = RMT_CLK_SRC_DEFAULT,
|
||||||
|
.resolution_hz = 10 * 1000 * 1000, // 10MHz
|
||||||
|
.mem_block_symbols = 0,
|
||||||
|
.flags =
|
||||||
|
{
|
||||||
|
.with_dma = false,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK(led_strip_new_rmt_device(&strip_config, &rmt_config, &led_strip));
|
||||||
|
ESP_LOGI(TAG, "LED strip initialized.");
|
||||||
|
|
||||||
|
// Create mutex
|
||||||
|
mutex = xSemaphoreCreateMutex();
|
||||||
|
if (mutex == NULL)
|
||||||
|
{
|
||||||
|
ESP_LOGE(TAG, "Could not create mutex.");
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start task
|
||||||
|
xTaskCreate(led_status_task, "led_status_task", 2048, NULL, 5, NULL);
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to set the behavior
|
||||||
|
esp_err_t led_status_set_behavior(uint8_t index, led_behavior_t behavior)
|
||||||
|
{
|
||||||
|
if (index >= STATUS_LED_COUNT)
|
||||||
|
{
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xSemaphoreTake(mutex, portMAX_DELAY) == pdTRUE)
|
||||||
|
{
|
||||||
|
led_controls[index].behavior = behavior;
|
||||||
|
// Reset internal state variables to start the new pattern cleanly
|
||||||
|
led_controls[index].is_on_in_blink = false;
|
||||||
|
led_controls[index].last_toggle_time_us = esp_timer_get_time();
|
||||||
|
xSemaphoreGive(mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
@@ -1,7 +1,9 @@
|
|||||||
#include "app_task.h"
|
#include "app_task.h"
|
||||||
#include "esp_event.h"
|
#include "esp_event.h"
|
||||||
|
#include "esp_log.h"
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "led_manager.h"
|
#include "led_manager.h"
|
||||||
|
#include "led_status.h"
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@@ -10,6 +12,22 @@ extern "C"
|
|||||||
#endif
|
#endif
|
||||||
void app_main(void)
|
void app_main(void)
|
||||||
{
|
{
|
||||||
|
led_status_init(CONFIG_STATUS_WLED_PIN);
|
||||||
|
|
||||||
|
// LED 0: solid red
|
||||||
|
led_behavior_t led0_solid_red = {.mode = LED_MODE_SOLID, .color = {.r = 50, .g = 0, .b = 0}};
|
||||||
|
led_status_set_behavior(0, led0_solid_red);
|
||||||
|
|
||||||
|
// LED 1: fast blinking green (200ms an, 200ms aus)
|
||||||
|
led_behavior_t led1_blink_green = {
|
||||||
|
.mode = LED_MODE_BLINK, .color = {.r = 0, .g = 50, .b = 0}, .on_time_ms = 200, .off_time_ms = 200};
|
||||||
|
led_status_set_behavior(1, led1_blink_green);
|
||||||
|
|
||||||
|
// LED 2: slow blinking blue (1000ms an, 500ms aus)
|
||||||
|
led_behavior_t led2_blink_blue = {
|
||||||
|
.mode = LED_MODE_BLINK, .color = {.r = 0, .g = 0, .b = 50}, .on_time_ms = 1000, .off_time_ms = 500};
|
||||||
|
led_status_set_behavior(2, led2_blink_blue);
|
||||||
|
|
||||||
xTaskCreatePinnedToCore(app_task, "main_loop", 4096, NULL, tskIDLE_PRIORITY + 1, NULL, portNUM_PROCESSORS - 1);
|
xTaskCreatePinnedToCore(app_task, "main_loop", 4096, NULL, tskIDLE_PRIORITY + 1, NULL, portNUM_PROCESSORS - 1);
|
||||||
|
|
||||||
wled_init();
|
wled_init();
|
||||||
|
Reference in New Issue
Block a user