607 lines
27 KiB
C++
607 lines
27 KiB
C++
#include "ATALights.h"
|
|
#include "freertos/FreeRTOS.h"
|
|
#include "freertos/task.h"
|
|
#include "freertos/semphr.h"
|
|
#include <Arduino.h>
|
|
#include <FastLED.h>
|
|
#include "Animations.h"
|
|
#include <functional>
|
|
#include "system.h"
|
|
#include "ColorPalettes.h"
|
|
#include "global.h"
|
|
//#include <crgb.h>
|
|
#include "PWM_Output.h"
|
|
#include "my_device.h"
|
|
#include "system.h"
|
|
#include "my_device.h"
|
|
|
|
#define FASTLED_CORE 0
|
|
static const char* tag = "strips";
|
|
|
|
uint32_t whiteTimeout = 0;
|
|
|
|
TaskHandle_t Animation_Task_Handle;
|
|
TaskHandle_t Ramp_Front_Light_Task_Handle;
|
|
LEDSTRIP_SETTINGS ledSettings[2];
|
|
volatile bool AnimationLooping = false;
|
|
ANIM_EVENT prevAnimEvent = {0};
|
|
QueueHandle_t animationQueue = xQueueCreate( 4, sizeof( ANIM_EVENT ) );
|
|
|
|
bool fillAnimationActive = false;
|
|
|
|
void RGB_Lights_Set_Animation(int animIndex, uint8_t red, uint8_t grn, uint8_t blu){
|
|
|
|
// Trigger to exit curring looping animation
|
|
if(AnimationLooping){
|
|
AnimationLooping = false;
|
|
xTaskNotifyGive( Animation_Task_Handle );
|
|
}
|
|
|
|
ANIM_EVENT event;
|
|
event.AnimationIndex = animIndex;
|
|
event.data.red = red;
|
|
event.data.grn = grn;
|
|
event.data.blu = blu;
|
|
event.data.wht = 0;
|
|
xQueueSend( animationQueue, &event, 25 );
|
|
}
|
|
|
|
void RGB_Animations_ON(){
|
|
RGB_Lights_Set_Animation(prevAnimEvent.AnimationIndex, prevAnimEvent.data.red, prevAnimEvent.data.grn, prevAnimEvent.data.blu);
|
|
}
|
|
|
|
void RGB_Animations_OFF(){
|
|
RGB_Lights_Set_Animation(OFF_INDEX, 0, 0, 0);
|
|
}
|
|
|
|
void RGB_Lights_Set_Brightness(uint8_t scale){
|
|
FastLED.setBrightness(scale);
|
|
}
|
|
|
|
// Set the white LEDs brightness (0-255)
|
|
void Lights_Set_White(uint8_t val){
|
|
//pwmOut[0]->setOutput(val / 2.5f);
|
|
}
|
|
|
|
void Init_RGB_Lights_Task(void){
|
|
ledSettings[0].leds = new CRGB[ledSettings[0].size];
|
|
Init_RGB_Strip(ledSettings[0].leds, ledSettings[0].pin, ledSettings[0].size, ledSettings[0].rgbOrder, ledSettings[0].chip, ledSettings[0].bright);
|
|
ESP_LOGD(tag, "Initializing Strip1: Pin: %d, size: %d, order: %s, chip: %s", ledSettings[0].pin, ledSettings[0].size, ledSettings[0].rgbOrder, ledSettings[0].chip);
|
|
|
|
|
|
ledSettings[1].leds = new CRGB[ledSettings[1].size];;
|
|
Init_RGB_Strip(ledSettings[1].leds, ledSettings[1].pin, ledSettings[1].size, ledSettings[1].rgbOrder, ledSettings[1].chip, ledSettings[1].bright);
|
|
ESP_LOGD(tag, "Initializing Strip2: Pin: %d, size: %d, order: %s, chip: %s", ledSettings[1].pin, ledSettings[1].size, ledSettings[1].rgbOrder, ledSettings[1].chip);
|
|
|
|
xTaskCreatePinnedToCore(RGB_Lights_Control_Task, "Lights_Task", 1024*6, NULL, 1, &Animation_Task_Handle, FASTLED_CORE);
|
|
ESP_LOGI(tag, "Lights Task Created...");
|
|
}
|
|
|
|
|
|
/*
|
|
void Init_Ramp_Front_Light_Task(void){
|
|
// Check if pwmOutputs[0] is available before creating the task
|
|
if(pwmOutputs[0] == nullptr) {
|
|
ESP_LOGE(tag, "Cannot create Ramp Front Light Task: pwmOutputs[0] is not initialized");
|
|
return;
|
|
}
|
|
|
|
// Create task with moderate stack size - 2KB should be sufficient
|
|
BaseType_t result = xTaskCreatePinnedToCore(Ramp_Front_Light_Control_Task, "Ramp_Front_Light_Task", 1024*2, NULL, 1, &Ramp_Front_Light_Task_Handle, (FASTLED_CORE ? 1 : 0));
|
|
|
|
if(result != pdPASS) {
|
|
ESP_LOGE(tag, "Failed to create Ramp Front Light Task, error: %d", result);
|
|
Ramp_Front_Light_Task_Handle = NULL;
|
|
} else {
|
|
ESP_LOGI(tag, "Ramp Front Light Task Created...");
|
|
}
|
|
}
|
|
*/
|
|
|
|
/*
|
|
#define RAMP_INTERVAL 25
|
|
#define FRONTLIGHT_TIMEOUT 20000
|
|
int startDelay = 0;
|
|
int rampTime = 0;
|
|
bool rampRestart = false;
|
|
float FrontLightMin = 0.0;
|
|
|
|
void Ramp_Front_Light_Control_Task(void *parameters)
|
|
{
|
|
float currPwmValue = 0.0;
|
|
float outValue = 0.0;
|
|
int timeCounter = 0;
|
|
|
|
while(1) {
|
|
|
|
if(rampRestart == false){
|
|
vTaskSuspend(NULL); // Wait to be triggered
|
|
}
|
|
rampRestart = false; // Clear the flag immediately
|
|
|
|
// Safety check: Ensure pwmOutputs[0] is initialized
|
|
if(pwmOutputs[0] == nullptr) {
|
|
ESP_LOGE(tag, "pwmOutputs[0] is null, cannot control front light");
|
|
rampRestart = false;
|
|
continue;
|
|
}
|
|
|
|
// Wait for start delay to finish
|
|
while(!rampRestart && fillAnimationActive && startDelay > 0){
|
|
vTaskDelay(10 / portTICK_PERIOD_MS);
|
|
startDelay -= 10;
|
|
}
|
|
|
|
if(rampRestart){
|
|
continue; // Restart if requested during delay
|
|
}
|
|
|
|
//currPwmValue = pwmOutputs[0]->getDuty(); // Get current PWM value
|
|
currPwmValue = FrontLightMin; // Always start from min value
|
|
pwmOutputs[0]->setOutput(currPwmValue); // Ensure starting point is set
|
|
|
|
// Ramp Up the Front Light linearly
|
|
timeCounter = 0; // Reset timer for ramp up
|
|
int rampMs = rampTime;
|
|
while(!rampRestart && fillAnimationActive && rampMs > 0){
|
|
timeCounter += RAMP_INTERVAL;
|
|
outValue = map(timeCounter, 0, rampTime, currPwmValue, 100);
|
|
pwmOutputs[0]->setOutput(outValue);
|
|
vTaskDelay(RAMP_INTERVAL / portTICK_PERIOD_MS);
|
|
rampMs -= RAMP_INTERVAL;
|
|
}
|
|
|
|
if(rampRestart){
|
|
continue; // Restart the ramp up if requested
|
|
}
|
|
|
|
// Max Wait fill animation to end or timeout
|
|
int frontLightTimeout = FRONTLIGHT_TIMEOUT;
|
|
while(!rampRestart && fillAnimationActive && frontLightTimeout > 0){
|
|
vTaskDelay(10 / portTICK_PERIOD_MS);
|
|
frontLightTimeout -= 10;
|
|
}
|
|
|
|
if(rampRestart){
|
|
pwmOutputs[0]->setOutput(0); // Ensure it's fully off
|
|
continue; // Restart the ramp up if requested
|
|
}
|
|
|
|
// Ramp Down the Front Light linearly
|
|
timeCounter = 0; // Reset timer for ramp down
|
|
rampMs = rampTime;
|
|
while(!rampRestart && fillAnimationActive && rampMs > 0){
|
|
timeCounter += RAMP_INTERVAL;
|
|
outValue = map(timeCounter, 0, rampTime, 100 , currPwmValue);
|
|
pwmOutputs[0]->setOutput(outValue);
|
|
vTaskDelay(RAMP_INTERVAL / portTICK_PERIOD_MS);
|
|
rampMs -= RAMP_INTERVAL;
|
|
}
|
|
|
|
// Cycle completed - ensure clean final state
|
|
if(!rampRestart){
|
|
pwmOutputs[0]->setOutput(FrontLightMin); // Ensure final state is minimum
|
|
fillAnimationActive = false; // Clear animation flag
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void Start_RampUp_Front_Light(int _rampTime, int _startDelay)
|
|
{
|
|
// Check if the task exists before trying to control it
|
|
if(Ramp_Front_Light_Task_Handle == NULL) {
|
|
ESP_LOGW(tag, "Cannot start front light ramp: task not created");
|
|
return;
|
|
}
|
|
|
|
rampTime = _rampTime;
|
|
startDelay = _startDelay;
|
|
fillAnimationActive = true;
|
|
rampRestart = true;
|
|
vTaskResume(Ramp_Front_Light_Task_Handle);
|
|
}
|
|
*/
|
|
|
|
void Animation_Loop_Exit(void){
|
|
if( Animation_Task_Handle ){
|
|
xTaskNotifyGive( Animation_Task_Handle );
|
|
}
|
|
}
|
|
|
|
|
|
EOrder GetEOrderByString(const String& rgbStr){
|
|
ESP_LOGI(tag, "EOrder is %s", rgbStr.c_str());
|
|
if (rgbStr.equalsIgnoreCase("RGB")) return RGB;
|
|
else if (rgbStr.equalsIgnoreCase("RBG")) return RBG;
|
|
else if (rgbStr.equalsIgnoreCase("GRB")) return GRB;
|
|
else if (rgbStr.equalsIgnoreCase("GBR")) return GBR;
|
|
else if (rgbStr.equalsIgnoreCase("BRG")) return BRG;
|
|
else if (rgbStr.equalsIgnoreCase("BGR")) return BGR;
|
|
else return RGB; // Default case
|
|
}
|
|
|
|
|
|
/*
|
|
void setPixel(LEDSTRIP_SETTINGS& strip, int pixelIndex, CRGB col){
|
|
int x = calcPixelIndex(strip, pixelIndex);
|
|
leds1[x] = col;
|
|
}
|
|
|
|
inline int calcPixelIndex(LEDSTRIP_SETTINGS& strip, int index) {
|
|
int x = (index + strip.shift) % strip.effSize;
|
|
x = (x < 0) ? (x + strip.effSize) : x;
|
|
return (x +strip.offset) % strip.effSize;
|
|
}
|
|
*/
|
|
|
|
inline void setPixel1(LEDSTRIP_SETTINGS& leds, int pixelIndex, const CRGB col) {
|
|
register uint16_t x = pixelIndex + ledSettings[0].shift;
|
|
// If strip.effSize is power of 2, use faster bit masking
|
|
if ((leds.effSize & (leds.effSize - 1)) == 0) {
|
|
x = (x < 0) ? ((x + leds.effSize) & (leds.effSize - 1)) : (x & (leds.effSize - 1));
|
|
leds.leds[(x + leds.offset) & (leds.effSize - 1)] = col;
|
|
} else {
|
|
// For non-power-of-2 sizes, still need modulo
|
|
x = (x < 0) ? ((x + ledSettings[0].effSize) % ledSettings[0].effSize) : (x % ledSettings[0].effSize);
|
|
ledSettings[0].leds[(x + ledSettings[0].offset) % ledSettings[0].effSize] = col;
|
|
}
|
|
}
|
|
|
|
|
|
inline void setPixel2(int pixelIndex, const CRGB col) {
|
|
register uint16_t x = pixelIndex + ledSettings[1].shift;
|
|
// If strip.effSize is power of 2, use faster bit masking
|
|
if ((ledSettings[1].effSize & (ledSettings[1].effSize - 1)) == 0) {
|
|
x = (x < 0) ? ((x + ledSettings[1].effSize) & (ledSettings[1].effSize - 1)) : (x & (ledSettings[1].effSize - 1));
|
|
ledSettings[1].leds[(x + ledSettings[1].offset) & (ledSettings[1].effSize - 1)] = col;
|
|
} else {
|
|
// For non-power-of-2 sizes, still need modulo
|
|
x = (x < 0) ? ((x + ledSettings[1].effSize) % ledSettings[1].effSize) : (x % ledSettings[1].effSize);
|
|
ledSettings[1].leds[(x + ledSettings[1].offset) % ledSettings[1].effSize] = col;
|
|
}
|
|
}
|
|
|
|
|
|
void Init_RGB_Strip(CRGB* leds, uint8_t pin, int size, const String& colorOrder, const String& chipType, uint8_t bright) {
|
|
// Validate inputs
|
|
if (!leds || size <= 0) {
|
|
ESP_LOGE(tag, "Invalid LED array or size");
|
|
return;
|
|
}
|
|
|
|
// Convert strings to uppercase once
|
|
String chipUpper = chipType;
|
|
String orderUpper = colorOrder;
|
|
chipUpper.toUpperCase();
|
|
orderUpper.toUpperCase();
|
|
|
|
// Validate pin (using AND for correct logic)
|
|
if (pin != 3 && pin != 9 && pin != 46) {
|
|
ESP_LOGW(tag, "Invalid pin %d, defaulting to 3", pin);
|
|
pin = 3;
|
|
}
|
|
|
|
EOrder rgbOrder = GetEOrderByString(orderUpper);
|
|
|
|
if(pin == 3){
|
|
// First level: Chip type selection
|
|
if (chipUpper == "WS2812B" || chipUpper == "SK6812") {
|
|
switch(rgbOrder) {
|
|
case RGB: FastLED.addLeds<WS2812B, 3, RGB>(leds, size); break;
|
|
case RBG: FastLED.addLeds<WS2812B, 3, RBG>(leds, size); break;
|
|
case GRB: FastLED.addLeds<WS2812B, 3, GRB>(leds, size); break;
|
|
case GBR: FastLED.addLeds<WS2812B, 3, GBR>(leds, size); break;
|
|
case BRG: FastLED.addLeds<WS2812B, 3, BRG>(leds, size); break;
|
|
case BGR: FastLED.addLeds<WS2812B, 3, BGR>(leds, size); break;
|
|
default: FastLED.addLeds<WS2812B, 3, GRB>(leds, size); break;
|
|
}
|
|
}
|
|
else if (chipUpper == "SK6812") {
|
|
switch(rgbOrder) {
|
|
case RGB: FastLED.addLeds<SK6812, 3, RGB>(leds, size); break;
|
|
case RBG: FastLED.addLeds<SK6812, 3, RBG>(leds, size); break;
|
|
case GRB: FastLED.addLeds<WS2815, 3, GRB>(leds, size); break;
|
|
case GBR: FastLED.addLeds<SK6812, 3, GBR>(leds, size); break;
|
|
case BRG: FastLED.addLeds<SK6812, 3, BRG>(leds, size); break;
|
|
case BGR: FastLED.addLeds<SK6812, 3, BGR>(leds, size); break;
|
|
default: FastLED.addLeds<SK6812, 3, GRB>(leds, size); break;
|
|
}
|
|
}
|
|
else if (chipUpper == "WS2811_400") {
|
|
switch(rgbOrder) {
|
|
case RGB: FastLED.addLeds<WS2811_400, 3, RGB>(leds, size); break;
|
|
case RBG: FastLED.addLeds<WS2811_400, 3, RBG>(leds, size); break;
|
|
case GRB: FastLED.addLeds<WS2811_400, 3, GRB>(leds, size); break;
|
|
case GBR: FastLED.addLeds<WS2811_400, 3, GBR>(leds, size); break;
|
|
case BRG: FastLED.addLeds<WS2811_400, 3, BRG>(leds, size); break;
|
|
case BGR: FastLED.addLeds<WS2811_400, 3, BGR>(leds, size); break;
|
|
default: FastLED.addLeds<WS2811_400, 3, GRB>(leds, size); break;
|
|
}
|
|
}
|
|
else if (chipUpper == "WS2815") {
|
|
switch(rgbOrder) {
|
|
case RGB: FastLED.addLeds<WS2815, 3, RGB>(leds, size); break;
|
|
case RBG: FastLED.addLeds<WS2815, 3, RBG>(leds, size); break;
|
|
case GRB: FastLED.addLeds<WS2815, 3, GRB>(leds, size); break;
|
|
case GBR: FastLED.addLeds<WS2815, 3, GBR>(leds, size); break;
|
|
case BRG: FastLED.addLeds<WS2815, 3, BRG>(leds, size); break;
|
|
case BGR: FastLED.addLeds<WS2815, 3, BGR>(leds, size); break;
|
|
default: FastLED.addLeds<WS2815, 3, GRB>(leds, size); break;
|
|
}
|
|
}
|
|
else {
|
|
// Default to WS2812B if unknown chip type
|
|
ESP_LOGW(tag, "Unknown LED chip type: %s, defaulting to WS2812B", chipType.c_str());
|
|
FastLED.addLeds<WS2812B, 3, GRB>(leds, size);
|
|
}
|
|
ESP_LOGI(tag, "Initialized %s LED strip with %d LEDs on pin %d", chipType.c_str(), size, pin);
|
|
}
|
|
else if(pin == 9){
|
|
// First level: Chip type selection
|
|
if (chipUpper == "WS2812B") {
|
|
switch(rgbOrder) {
|
|
case RGB: FastLED.addLeds<WS2812B, 9, RGB>(leds, size); break;
|
|
case RBG: FastLED.addLeds<WS2812B, 9, RBG>(leds, size); break;
|
|
case GRB: FastLED.addLeds<WS2812B, 9, GRB>(leds, size); break;
|
|
case GBR: FastLED.addLeds<WS2812B, 9, GBR>(leds, size); break;
|
|
case BRG: FastLED.addLeds<WS2812B, 9, BRG>(leds, size); break;
|
|
case BGR: FastLED.addLeds<WS2812B, 9, BGR>(leds, size); break;
|
|
default: FastLED.addLeds<WS2812B, 9, GRB>(leds, size); break;
|
|
}
|
|
}
|
|
else if (chipUpper == "SK6812") {
|
|
switch(rgbOrder) {
|
|
case RGB: FastLED.addLeds<SK6812, 9, RGB>(leds, size); break;
|
|
case RBG: FastLED.addLeds<SK6812, 9, RBG>(leds, size); break;
|
|
case GRB: FastLED.addLeds<WS2815, 9, GRB>(leds, size); break;
|
|
case GBR: FastLED.addLeds<SK6812, 9, GBR>(leds, size); break;
|
|
case BRG: FastLED.addLeds<SK6812, 9, BRG>(leds, size); break;
|
|
case BGR: FastLED.addLeds<SK6812, 9, BGR>(leds, size); break;
|
|
default: FastLED.addLeds<SK6812, 9, GRB>(leds, size); break;
|
|
}
|
|
}
|
|
else if (chipUpper == "WS2811_400") {
|
|
switch(rgbOrder) {
|
|
case RGB: FastLED.addLeds<WS2811_400, 9, RGB>(leds, size); break;
|
|
case RBG: FastLED.addLeds<WS2811_400, 9, RBG>(leds, size); break;
|
|
case GRB: FastLED.addLeds<WS2811_400, 9, GRB>(leds, size); break;
|
|
case GBR: FastLED.addLeds<WS2811_400, 9, GBR>(leds, size); break;
|
|
case BRG: FastLED.addLeds<WS2811_400, 9, BRG>(leds, size); break;
|
|
case BGR: FastLED.addLeds<WS2811_400, 9, BGR>(leds, size); break;
|
|
default: FastLED.addLeds<WS2811_400, 9, GRB>(leds, size); break;
|
|
}
|
|
}
|
|
else if (chipUpper == "WS2815") {
|
|
switch(rgbOrder) {
|
|
case RGB: FastLED.addLeds<WS2815, 9, RGB>(leds, size); break;
|
|
case RBG: FastLED.addLeds<WS2815, 9, RBG>(leds, size); break;
|
|
case GRB: FastLED.addLeds<WS2815, 9, GRB>(leds, size); break;
|
|
case GBR: FastLED.addLeds<WS2815, 9, GBR>(leds, size); break;
|
|
case BRG: FastLED.addLeds<WS2815, 9, BRG>(leds, size); break;
|
|
case BGR: FastLED.addLeds<WS2815, 9, BGR>(leds, size); break;
|
|
default: FastLED.addLeds<WS2815, 9, GRB>(leds, size); break;
|
|
}
|
|
}
|
|
else {
|
|
// Default to WS2812B if unknown chip type
|
|
ESP_LOGW(tag, "Unknown LED chip type: %s, defaulting to WS2812B", chipType.c_str());
|
|
FastLED.addLeds<WS2812B, 9, GRB>(leds, size);
|
|
}
|
|
ESP_LOGI(tag, "Initialized %s LED strip with %d LEDs on pin %d", chipType.c_str(), size, pin);
|
|
}
|
|
else if(pin == 46){
|
|
// First level: Chip type selection
|
|
if (chipUpper == "WS2812B" || chipUpper == "SK6812") {
|
|
switch(rgbOrder) {
|
|
case RGB: FastLED.addLeds<WS2812B, 46, RGB>(leds, size); break;
|
|
case RBG: FastLED.addLeds<WS2812B, 46, RBG>(leds, size); break;
|
|
case GRB: FastLED.addLeds<WS2812B, 46, GRB>(leds, size); break;
|
|
case GBR: FastLED.addLeds<WS2812B, 46, GBR>(leds, size); break;
|
|
case BRG: FastLED.addLeds<WS2812B, 46, BRG>(leds, size); break;
|
|
case BGR: FastLED.addLeds<WS2812B, 46, BGR>(leds, size); break;
|
|
default: FastLED.addLeds<WS2812B, 46, GRB>(leds, size); break;
|
|
}
|
|
}
|
|
else if (chipUpper == "SK6812") {
|
|
switch(rgbOrder) {
|
|
case RGB: FastLED.addLeds<SK6812, 46, RGB>(leds, size); break;
|
|
case RBG: FastLED.addLeds<SK6812, 46, RBG>(leds, size); break;
|
|
case GRB: FastLED.addLeds<WS2815, 46, GRB>(leds, size); break;
|
|
case GBR: FastLED.addLeds<SK6812, 46, GBR>(leds, size); break;
|
|
case BRG: FastLED.addLeds<SK6812, 46, BRG>(leds, size); break;
|
|
case BGR: FastLED.addLeds<SK6812, 46, BGR>(leds, size); break;
|
|
default: FastLED.addLeds<SK6812, 46, GRB>(leds, size); break;
|
|
}
|
|
}
|
|
else if (chipUpper == "WS2811_400") {
|
|
switch(rgbOrder) {
|
|
case RGB: FastLED.addLeds<WS2811_400, 46, RGB>(leds, size); break;
|
|
case RBG: FastLED.addLeds<WS2811_400, 46, RBG>(leds, size); break;
|
|
case GRB: FastLED.addLeds<WS2811_400, 46, GRB>(leds, size); break;
|
|
case GBR: FastLED.addLeds<WS2811_400, 46, GBR>(leds, size); break;
|
|
case BRG: FastLED.addLeds<WS2811_400, 46, BRG>(leds, size); break;
|
|
case BGR: FastLED.addLeds<WS2811_400, 46, BGR>(leds, size); break;
|
|
default: FastLED.addLeds<WS2811_400, 46, GRB>(leds, size); break;
|
|
}
|
|
}
|
|
else if (chipUpper == "WS2815") {
|
|
switch(rgbOrder) {
|
|
case RGB: FastLED.addLeds<WS2815, 46, RGB>(leds, size); break;
|
|
case RBG: FastLED.addLeds<WS2815, 46, RBG>(leds, size); break;
|
|
case GRB: FastLED.addLeds<WS2815, 46, GRB>(leds, size); break;
|
|
case GBR: FastLED.addLeds<WS2815, 46, GBR>(leds, size); break;
|
|
case BRG: FastLED.addLeds<WS2815, 46, BRG>(leds, size); break;
|
|
case BGR: FastLED.addLeds<WS2815, 46, BGR>(leds, size); break;
|
|
default: FastLED.addLeds<WS2815, 46, GRB>(leds, size); break;
|
|
}
|
|
}
|
|
else {
|
|
// Default to WS2812B if unknown chip type
|
|
ESP_LOGW(tag, "Unknown LED chip type: %s, defaulting to WS2812B", chipType.c_str());
|
|
FastLED.addLeds<WS2812B, 9, GRB>(leds, size);
|
|
}
|
|
ESP_LOGI(tag, "Initialized %s LED strip with %d LEDs on pin %d", chipType.c_str(), size, pin);
|
|
}
|
|
|
|
FastLED.setBrightness(bright);
|
|
}
|
|
|
|
|
|
void RGB_Lights_Control_Task(void *parameters){
|
|
|
|
ANIM_EVENT AnimEvent;
|
|
CRGB col;
|
|
COLOR_PACK colorPack;
|
|
CRGBPalette16 firePalette;
|
|
|
|
// Wait for other tasks to initialize (including front light task)
|
|
vTaskDelay(pdMS_TO_TICKS(500)); // wait for everything to settle
|
|
|
|
RGB_Lights_Set_Brightness(48);
|
|
RGB_Lights_Set_Animation(23, 0, 0, 0); // set comet rainbow animation
|
|
|
|
|
|
while (true) {
|
|
if (xQueueReceive(animationQueue, &AnimEvent, portMAX_DELAY) == pdTRUE) {
|
|
ESP_LOGI(tag, "New Animation Event: Index: %d", AnimEvent.AnimationIndex);
|
|
switch (AnimEvent.AnimationIndex) {
|
|
case -3: // Set Pixel by index
|
|
if (AnimEvent.data.data[7] >= 0 && AnimEvent.data.data[7] < ledSettings[0].size) {
|
|
ledSettings[0].leds[AnimEvent.data.data[7]] = CRGB(AnimEvent.data.red, AnimEvent.data.grn, AnimEvent.data.blu);
|
|
FastLED.show();
|
|
} else {
|
|
ESP_LOGW(tag, "Pixel index out of range: %d", AnimEvent.data.data[7]);
|
|
}
|
|
break;
|
|
case -2: // Fill Static Color
|
|
col = CRGB(AnimEvent.data.red, AnimEvent.data.grn, AnimEvent.data.blu);
|
|
fill_solid(ledSettings[0].leds, ledSettings[0].size, col);
|
|
FastLED.show();
|
|
ESP_LOGD(tag, "Static Color");
|
|
break;
|
|
case -1:
|
|
FastLED.clear();
|
|
FastLED.show();
|
|
ESP_LOGD(tag, "LEDs Off");
|
|
break;
|
|
case 0:
|
|
fill_solid(ledSettings[0].leds, ledSettings[0].size, CRGB::Black);
|
|
FastLED.show();
|
|
break;
|
|
case 1: case 2: case 3: case 4: case 5:{ // Timed Fill Animations
|
|
int timeDuration = AnimEvent.AnimationIndex * 1000;
|
|
int whiteDelay = timeDuration - 1000;
|
|
Anim_TimedFill_Flash(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, pwmOutputs[0], &sys_settings.pwmOutSettings[0], whiteDelay, 10000, CRGB::Black, CRGB::White, timeDuration, ledSettings[0].shift);
|
|
break;
|
|
}
|
|
case 6:
|
|
// RGB White and Dedicated White all on with timeout and brightness reduction
|
|
if (pwmOutputs[0] != nullptr) {
|
|
Anim_SolidWhite(AnimationLooping, ledSettings[0].leds, pwmOutputs[0], ledSettings[0].size, 240, 30000);
|
|
}
|
|
break;
|
|
case 7:
|
|
Anim_Rainbow(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, 60);
|
|
break;
|
|
case 8: case 9: case 10: case 11: case 12:
|
|
Anim_GradientRotate(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, gradient_colorPack[AnimEvent.AnimationIndex - 8], 80);
|
|
break;
|
|
case 13: case 14: case 15: case 16: case 17: { // Fire Animations
|
|
COLOR_PACK fp = fireColorPacks[AnimEvent.AnimationIndex - 13]; // copy const pack to mutable
|
|
createFirePalette(firePalette, fp);
|
|
Anim_Fire(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, 60, firePalette, ledSettings[0].shift);
|
|
break;
|
|
}
|
|
case 18: case 19: case 20:// Sparkle/Twinkle
|
|
Anim_Sparkle(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, tripple_colorPacks[0], 40, 20);
|
|
break;
|
|
case 21:
|
|
//Anim_ColorBreath(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, colorPack_RAINBOW, 7000, 90);
|
|
Anim_Morph(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, colorPack_RAINBOW, 20, 40);
|
|
break;
|
|
case 22: // Rain Animation
|
|
break;
|
|
|
|
|
|
// Comets
|
|
case 23:
|
|
Anim_Comets(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, colorPack_RAINBOW, 40, 85, RANDOM_DECAY, 1);
|
|
break;
|
|
case 24: case 25: case 26: case 27: case 28: case 29: case 30: case 31:
|
|
Anim_Comets(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, single_colorPacks[AnimEvent.AnimationIndex - 24], 40, 85, RANDOM_DECAY, 6);
|
|
break;
|
|
case 32: case 33: case 34: case 35: case 36: case 37: case 38: case 39: case 40:
|
|
Anim_Comets(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, double_colorPacks[AnimEvent.AnimationIndex - 32], 40, 85, RANDOM_DECAY, 3);
|
|
break;
|
|
case 41: case 42: case 43: case 44: case 45: case 46: case 47: case 48: case 49:
|
|
Anim_Comets(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, tripple_colorPacks[AnimEvent.AnimationIndex - 41], 40, 85, RANDOM_DECAY, 2);
|
|
break;
|
|
|
|
// Snakes
|
|
case 50:
|
|
Anim_Snakes(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, colorPack_RAINBOW, 50);
|
|
break;
|
|
case 51: case 52: case 53: case 54: case 55: case 56: case 57: case 58:
|
|
Anim_Snakes(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, single_colorPacks[AnimEvent.AnimationIndex - 51], 60, 6);
|
|
break;
|
|
case 59: case 60: case 61: case 62: case 63: case 64: case 65: case 66: case 67:
|
|
Anim_Snakes(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, double_colorPacks[AnimEvent.AnimationIndex - 59], 60, 3);
|
|
break;
|
|
case 68: case 69: case 70: case 71: case 72: case 73: case 74: case 75: case 76:
|
|
Anim_Snakes(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, tripple_colorPacks[AnimEvent.AnimationIndex - 68], 60, 2);
|
|
break;
|
|
|
|
// Sectors
|
|
case 77:
|
|
Anim_Color_Sectors(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, colorPack_RAINBOW, NO_GAPS, 1, 40, 90);
|
|
break;
|
|
case 78: case 79: case 80: case 81: case 82: case 83: case 84: case 85: case 86:
|
|
Anim_Color_Sectors(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, double_colorPacks[AnimEvent.AnimationIndex - 78], NO_GAPS, 3, 40, 90);
|
|
break;
|
|
case 87: case 88: case 89: case 90: case 91: case 92: case 93: case 94: case 95:
|
|
Anim_Color_Sectors(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, tripple_colorPacks[AnimEvent.AnimationIndex - 87], NO_GAPS, 2, 40, 90);
|
|
break;
|
|
|
|
// Dashes
|
|
case 96:
|
|
Anim_Color_Sectors(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, colorPack_RAINBOW, WITH_GAPS, 1, 40, 90);
|
|
break;
|
|
case 97:case 98:case 99: case 100: case 101: case 102: case 103: case 104:
|
|
Anim_Color_Sectors(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, single_colorPacks[AnimEvent.AnimationIndex - 97], WITH_GAPS, 6, 40, 90);
|
|
break;
|
|
case 105: case 106: case 107: case 108: case 109: case 110: case 111: case 112: case 113:
|
|
Anim_Color_Sectors(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, double_colorPacks[AnimEvent.AnimationIndex - 105], WITH_GAPS, 3, 40, 90);
|
|
break;
|
|
case 114: case 115: case 116: case 117: case 118: case 119: case 120: case 121: case 122:
|
|
Anim_Color_Sectors(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, tripple_colorPacks[AnimEvent.AnimationIndex - 114], WITH_GAPS, 2, 40, 90);
|
|
break;
|
|
|
|
default:
|
|
ESP_LOGW(tag, "Loop default");
|
|
break;
|
|
}
|
|
|
|
AnimationLooping = false;
|
|
prevAnimEvent = AnimEvent;
|
|
ESP_LOGD(tag, "Going to Queue to Wait");
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void createFirePalette(CRGBPalette16& palette, const COLOR_PACK& colorPack) {
|
|
for (uint8_t i = 0; i < 16; i++) {
|
|
if (i < 3) palette[i] = CRGB::Black;
|
|
else if (i < 7) palette[i] = colorPack.col[0];
|
|
else if (i < 10) palette[i] = colorPack.col[1];
|
|
else if (i < 15) palette[i] = colorPack.col[2];
|
|
else palette[i] = CRGB::White;
|
|
}
|
|
}
|
|
|
|
|
|
void loadColorPack(COLOR_PACK& dest, const COLOR_PACK& src) {
|
|
memcpy_P(&dest, &src, sizeof(COLOR_PACK));
|
|
}
|