diff --git a/CMakeLists.txt b/CMakeLists.txt index e3fbd3c..3c79c3f 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -98,6 +98,7 @@ else () target_link_libraries(${PROJECT_NAME} PRIVATE ImGui insa + led-manager SDL3::SDL3 SDL3_image::SDL3_image SDL3_ttf::SDL3_ttf diff --git a/components/insa/CMakeLists.txt b/components/insa/CMakeLists.txt index e5a8995..29c7b32 100644 --- a/components/insa/CMakeLists.txt +++ b/components/insa/CMakeLists.txt @@ -19,6 +19,7 @@ if (DEFINED ENV{IDF_PATH}) INCLUDE_DIRS "include" PRIV_REQUIRES u8g2 + led-manager ) return() endif () @@ -36,4 +37,5 @@ target_include_directories(${PROJECT_NAME} PUBLIC include) target_link_libraries(${PROJECT_NAME} PRIVATE u8g2 + led-manager ) \ No newline at end of file diff --git a/components/insa/src/ui/LightMenu.cpp b/components/insa/src/ui/LightMenu.cpp index db271c2..a6249ba 100644 --- a/components/insa/src/ui/LightMenu.cpp +++ b/components/insa/src/ui/LightMenu.cpp @@ -1,5 +1,6 @@ #include "ui/LightMenu.h" +#include "led_manager.h" #include "ui/LightSettingsMenu.h" /** @@ -8,8 +9,8 @@ */ namespace LightMenuItem { -constexpr uint8_t ACTIVATE = 0; ///< ID for the light activation toggle -constexpr uint8_t MODE = 1; ///< ID for the light mode selection +constexpr uint8_t ACTIVATE = 0; ///< ID for the light activation toggle +constexpr uint8_t MODE = 1; ///< ID for the light mode selection constexpr uint8_t LED_SETTINGS = 2; ///< ID for the LED settings menu item } // namespace LightMenuItem @@ -17,7 +18,7 @@ namespace LightMenuOptions { constexpr std::string LIGHT_ACTIVE = "light_active"; constexpr std::string LIGHT_MODE = "light_mode"; -} +} // namespace LightMenuOptions LightMenu::LightMenu(menu_options_t *options) : Menu(options), m_options(options) { @@ -31,7 +32,7 @@ LightMenu::LightMenu(menu_options_t *options) : Menu(options), m_options(options // Create mode selection options (Day/Night modes) std::vector values; - values.emplace_back("Tag"); // Day mode + values.emplace_back("Tag"); // Day mode values.emplace_back("Nacht"); // Night mode int mode_value = 0; if (m_options && m_options->persistenceManager) @@ -56,6 +57,16 @@ void LightMenu::onButtonPressed(const MenuItem &menuItem, const ButtonType butto if (button == ButtonType::SELECT) { toggle(menuItem); + if (getItem(menuItem.getId()).getValue() == "1") + { + led_event_data_t payload = {.value = 42}; + send_event(EVENT_LED_ON, &payload); + } + else + { + led_event_data_t payload = {.value = 0}; + send_event(EVENT_LED_OFF, &payload); + } if (m_options && m_options->persistenceManager) { const auto value = getItem(menuItem.getId()).getValue() == "1"; diff --git a/components/led-manager/CMakeLists.txt b/components/led-manager/CMakeLists.txt new file mode 100644 index 0000000..116fb00 --- /dev/null +++ b/components/led-manager/CMakeLists.txt @@ -0,0 +1,21 @@ +if (DEFINED ENV{IDF_PATH}) + idf_component_register(SRCS + src/hal_esp32/led_manager.cpp + INCLUDE_DIRS "include" + PRIV_REQUIRES + u8g2 + esp_event + ) + return() +endif () + +cmake_minimum_required(VERSION 3.30) +project(led-manager) + +add_library(${PROJECT_NAME} STATIC + src/hal_native/led_manager.cpp +) + +include_directories(include) + +target_include_directories(${PROJECT_NAME} PUBLIC include) diff --git a/components/led-manager/idf_component.yml b/components/led-manager/idf_component.yml new file mode 100755 index 0000000..74aa711 --- /dev/null +++ b/components/led-manager/idf_component.yml @@ -0,0 +1,2 @@ +dependencies: + espressif/led_strip: '~3.0.1' diff --git a/components/led-manager/include/led_manager.h b/components/led-manager/include/led_manager.h new file mode 100644 index 0000000..0dafcb1 --- /dev/null +++ b/components/led-manager/include/led_manager.h @@ -0,0 +1,22 @@ +#pragma once + +#include "stdint.h" + +enum +{ + EVENT_LED_ON, + EVENT_LED_OFF, + EVENT_LED_DAY, + EVENT_LED_NIGHT, +}; + +typedef struct +{ + int value; +} led_event_data_t; + +uint64_t wled_init(void); + +uint64_t register_handler(void); + +uint64_t send_event(uint32_t event, led_event_data_t *payload); diff --git a/components/led-manager/src/hal_esp32/led_manager.cpp b/components/led-manager/src/hal_esp32/led_manager.cpp new file mode 100644 index 0000000..0ff21c4 --- /dev/null +++ b/components/led-manager/src/hal_esp32/led_manager.cpp @@ -0,0 +1,92 @@ +#include "led_manager.h" + +#include "esp_event.h" +#include "esp_log.h" +#include "led_strip.h" +#include "sdkconfig.h" + +led_strip_handle_t led_strip; + +static const uint32_t value = 5; + +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"; + +uint64_t wled_init(void) +{ + led_strip_config_t strip_config = {.strip_gpio_num = CONFIG_WLED_DIN_PIN, + .max_leds = 64, + .led_model = LED_MODEL_WS2812, + .color_component_format = LED_STRIP_COLOR_COMPONENT_FMT_RGB, + .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)); + + for (uint32_t i = 0; i < 64; i++) + { + led_strip_set_pixel(led_strip, i, 0, 0, 0); + } + led_strip_refresh(led_strip); + + return ESP_OK; +} + +void event_handler(void *arg, esp_event_base_t base, int32_t id, void *event_data) +{ + if (id == EVENT_LED_ON || id == EVENT_LED_OFF) + { + auto brightness = (id == EVENT_LED_ON) ? value : 0; + for (uint32_t i = 0; i < 64; i++) + { + led_strip_set_pixel(led_strip, i, brightness, brightness, brightness); + } + led_strip_refresh(led_strip); + } +} + +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, // Daten-Pointer + sizeof(led_event_data_t), // Datengröße + portMAX_DELAY // Wartezeit + ); + + if (err != ESP_OK) + { + ESP_LOGE("LED", "Failed to post event: %s", esp_err_to_name(err)); + return err; + } + + return ESP_OK; +} diff --git a/components/led-manager/src/hal_native/led_manager.cpp b/components/led-manager/src/hal_native/led_manager.cpp new file mode 100644 index 0000000..97a3030 --- /dev/null +++ b/components/led-manager/src/hal_native/led_manager.cpp @@ -0,0 +1,16 @@ +#include "led_manager.h" + +uint64_t wled_init(void) +{ + return 0; +} + +uint64_t register_handler(void) +{ + return 0; +} + +uint64_t send_event(uint32_t event, led_event_data_t *payload) +{ + return 0; +} diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index b9e8eaf..ebef052 100755 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -1,14 +1,16 @@ idf_component_register(SRCS - "main.cpp" - "app_task.cpp" - "PersistenceManager.cpp" - "button_handling.c" - "hal/u8g2_esp32_hal.c" + main.cpp + app_task.cpp + PersistenceManager.cpp + button_handling.c + hal/u8g2_esp32_hal.c INCLUDE_DIRS "." PRIV_REQUIRES insa + led-manager u8g2 driver esp_timer + esp_event nvs_flash ) diff --git a/main/Kconfig.projbuild b/main/Kconfig.projbuild new file mode 100644 index 0000000..7f8acea --- /dev/null +++ b/main/Kconfig.projbuild @@ -0,0 +1,7 @@ +menu "Warnemuende Lighthouse" + config WLED_DIN_PIN + int "WLED Data In Pin" + default 14 + help + The number of the WLED data in pin. +endmenu diff --git a/main/main.cpp b/main/main.cpp index 5ffc5ac..71b47e2 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -1,5 +1,7 @@ #include "app_task.h" +#include "esp_event.h" #include "freertos/FreeRTOS.h" +#include "led_manager.h" #include "sdkconfig.h" #ifdef __cplusplus @@ -9,6 +11,9 @@ extern "C" void app_main(void) { xTaskCreatePinnedToCore(app_task, "main_loop", 4096, NULL, tskIDLE_PRIORITY + 1, NULL, portNUM_PROCESSORS - 1); + + wled_init(); + register_handler(); } #ifdef __cplusplus }