diff --git a/main/peripherals/led_strip.cpp b/main/peripherals/led_strip.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cdade0ed3ee9599f243d57dc78633b30b85b6ffb --- /dev/null +++ b/main/peripherals/led_strip.cpp @@ -0,0 +1,83 @@ +#include "led_strip.h" + + +uint8_t strips_cfged = 0; +strand_t leds[8]; + +uint8_t render_frequency = 50; + +qthing::led_color_t dummy_handler(uint8_t strip, uint16_t led, qthing::led_color_t last_color) { + return(last_color); +} + +qthing::led_color_handler_t led_handler = dummy_handler; + +void render_loop(void *ignored) { + digitalLeds_initStrands(leds, strips_cfged); + TickType_t lastWakeTime = xTaskGetTickCount(); + + while (true) { + for (uint8_t strip = 0; strip < strips_cfged; strip++) { + for (uint16_t led = 0; led < leds[strip].numPixels; led++) { + pixelColor_t last = leds[strip].pixels[led]; + qthing::led_color_t last_led = {last.r, last.g, last.b, last.w}; + qthing::led_color_t pixel = led_handler(strip, led, last_led); + leds[strip].pixels[led] = pixelFromRGBW(pixel.r, pixel.g, pixel.b, pixel.w); + } + } + + for (uint8_t i = 0; i < strips_cfged; i++) digitalLeds_updatePixels(&leds[i]); + vTaskDelayUntil(&lastWakeTime, 1000 / render_frequency / portTICK_PERIOD_MS); + } +} + +namespace qthing { + void add_ledstrip(gpio_num_t gpio, uint16_t num_leds, qthing::led_strip_types_t led_type) { + + int led_type_translated = 0; + + switch (led_type) { + case qthing::led_strip_types_t::LED_WS2812_V1: led_type_translated = led_types::LED_WS2812_V1; break; + case qthing::led_strip_types_t::LED_WS2812B_V1: led_type_translated = led_types::LED_WS2812B_V1; break; + case qthing::led_strip_types_t::LED_WS2812B_V2: led_type_translated = led_types::LED_WS2812B_V2; break; + case qthing::led_strip_types_t::LED_WS2812B_V3: led_type_translated = led_types::LED_WS2812B_V3; break; + case qthing::led_strip_types_t::LED_WS2813_V1: led_type_translated = led_types::LED_WS2813_V1; break; + case qthing::led_strip_types_t::LED_WS2813_V2: led_type_translated = led_types::LED_WS2813_V2; break; + case qthing::led_strip_types_t::LED_WS2813_V3: led_type_translated = led_types::LED_WS2813_V3; break; + case qthing::led_strip_types_t::LED_SK6812_V1: led_type_translated = led_types::LED_SK6812_V1; break; + case qthing::led_strip_types_t::LED_SK6812W_V1: led_type_translated = led_types::LED_SK6812W_V1; break; + } + + leds[strips_cfged] = { + .rmtChannel = strips_cfged, + .gpioNum = gpio, + .ledType = led_type_translated, + .brightLimit = 255, + .numPixels = num_leds, + .pixels = nullptr, + ._stateVars = nullptr + }; + + gpio_pad_select_gpio(gpio); + gpio_set_direction(gpio, GPIO_MODE_OUTPUT); + gpio_set_level(gpio, 0); + + strips_cfged++; + } + + void set_led_strip_fps(uint8_t fps) { + render_frequency = fps; + } + + void enable_leds(uint8_t led_strip_fps) { + set_led_strip_fps(led_strip_fps); + + // pin this to app cpu as it may consume a lot of cycles + // also assign prio of 2 since arduino's main-loop uses 1 if linked into app + xTaskCreatePinnedToCore(render_loop, "render_loop", 10000, NULL, 2, NULL, 1); + } + + void set_color_handler(led_color_handler_t led_color_handler) { + led_handler = led_color_handler; + } +} \ No newline at end of file diff --git a/main/peripherals/led_strip.h b/main/peripherals/led_strip.h new file mode 100644 index 0000000000000000000000000000000000000000..66350fd79b139f9f33e288a51348e64a12479e46 --- /dev/null +++ b/main/peripherals/led_strip.h @@ -0,0 +1,10 @@ +# pragma once + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + +#include "driver/gpio.h" + +#include "esp32_digital_led_lib.h" + +#include <qthing.h> diff --git a/main/qthing.h b/main/qthing.h index 7761cb8e2c8cedb0995aee824a2ca57065df8b28..f9679c8858b80e2079a5dac99d5968ce8d779626 100644 --- a/main/qthing.h +++ b/main/qthing.h @@ -64,4 +64,33 @@ void enable_lcd(const std::string& topic, uint8_t rs, uint8_t en, uint8_t d4, ui void add_wlan_connection_status_handler(connection_status_callback_t handler); void add_mqtt_connection_status_handler(connection_status_callback_t handler); +// LED strips +namespace qthing { + enum led_strip_types_t { + LED_WS2812_V1, + LED_WS2812B_V1, + LED_WS2812B_V2, + LED_WS2812B_V3, + LED_WS2813_V1, + LED_WS2813_V2, + LED_WS2813_V3, + LED_SK6812_V1, + LED_SK6812W_V1, + }; + + typedef union { + struct __attribute__ ((packed)) { + uint8_t r, g, b, w; + }; + uint32_t num; + } led_color_t; + + typedef std::function<led_color_t(uint8_t, uint16_t, led_color_t)> led_color_handler_t; + + void enable_leds(uint8_t led_strip_fps = 50); + void add_ledstrip(gpio_num_t gpio, uint16_t num_leds, qthing::led_strip_types_t led_type); + void set_color_handler(led_color_handler_t led_color_handler); + void set_led_strip_fps(uint8_t fps); +} + #endif