#ifndef LIGHTING_H #define LIGHTING_H #include #include "pins_arduino.h" // Timer group and timer number configuration #define TIMER_GROUP TIMER_GROUP_0 #define TIMER_NUM TIMER_0 #define NUM_LEDS 120 #define BRIGHTNESS 64 #define UPDATES_PER_SECOND 100 #define LED_TYPE APA102 #define COLOR_ORDER BGR CRGB leds[NUM_LEDS]; CRGBPalette16 currentPalette; TBlendType currentBlending; extern CRGBPalette16 myRedWhiteBluePalette; extern const TProgmemPalette16 myRedWhiteBluePalette_p PROGMEM; void SetupLights(){ FastLED.addLeds(leds, NUM_LEDS); // APA102 setup // FastLED.addLeds(leds, NUM_LEDS); // Uncomment for WS2812 FastLED.setBrightness( BRIGHTNESS ); pinMode (LightingSDA, OUTPUT); pinMode (LightingSCL, OUTPUT); currentPalette = RainbowColors_p; currentBlending = LINEARBLEND; } void FillLEDsFromPaletteColors( uint8_t colorIndex) { uint8_t brightness = 255; for( int i = 0; i < NUM_LEDS; i++) { leds[i] = ColorFromPalette( currentPalette, colorIndex, brightness, currentBlending); colorIndex += 3; } } // This function fills the palette with totally random colors. void SetupTotallyRandomPalette() { for( int i = 0; i < 16; i++) { currentPalette[i] = CHSV( random8(), 255, random8()); } } // This function sets up a palette of black and white stripes, // using code. Since the palette is effectively an array of // sixteen CRGB colors, the various fill_* functions can be used // to set them up. void SetupBlackAndWhiteStripedPalette() { // 'black out' all 16 palette entries... fill_solid( currentPalette, 16, CRGB::Black); // and set every fourth one to white. currentPalette[0] = CRGB::White; currentPalette[4] = CRGB::White; currentPalette[8] = CRGB::White; currentPalette[12] = CRGB::White; } // This function sets up a palette of purple and green stripes. void SetupPurpleAndGreenPalette() { CRGB purple = CHSV( HUE_PURPLE, 255, 255); CRGB green = CHSV( HUE_GREEN, 255, 255); CRGB black = CRGB::Black; currentPalette = CRGBPalette16( green, green, black, black, purple, purple, black, black, green, green, black, black, purple, purple, black, black ); } // This example shows how to set up a static color palette // which is stored in PROGMEM (flash), which is almost always more // plentiful than RAM. A static PROGMEM palette like this // takes up 64 bytes of flash. const TProgmemPalette16 myRedWhiteBluePalette_p PROGMEM = { CRGB::Red, CRGB::Gray, // 'white' is too bright compared to red and blue CRGB::Blue, CRGB::Black, CRGB::Red, CRGB::Gray, CRGB::Blue, CRGB::Black, CRGB::Red, CRGB::Red, CRGB::Gray, CRGB::Gray, CRGB::Blue, CRGB::Blue, CRGB::Black, CRGB::Black }; void ChangePalettePeriodically() { uint8_t secondHand = (millis() / 1000) % 60; static uint8_t lastSecond = 99; if( lastSecond != secondHand) { lastSecond = secondHand; if( secondHand == 0) { currentPalette = RainbowColors_p; currentBlending = LINEARBLEND; } if( secondHand == 10) { currentPalette = RainbowStripeColors_p; currentBlending = NOBLEND; } if( secondHand == 15) { currentPalette = RainbowStripeColors_p; currentBlending = LINEARBLEND; } if( secondHand == 20) { SetupPurpleAndGreenPalette(); currentBlending = LINEARBLEND; } if( secondHand == 25) { SetupTotallyRandomPalette(); currentBlending = LINEARBLEND; } if( secondHand == 30) { SetupBlackAndWhiteStripedPalette(); currentBlending = NOBLEND; } if( secondHand == 35) { SetupBlackAndWhiteStripedPalette(); currentBlending = LINEARBLEND; } if( secondHand == 40) { currentPalette = CloudColors_p; currentBlending = LINEARBLEND; } if( secondHand == 45) { currentPalette = PartyColors_p; currentBlending = LINEARBLEND; } if( secondHand == 50) { currentPalette = myRedWhiteBluePalette_p; currentBlending = NOBLEND; } if( secondHand == 55) { currentPalette = myRedWhiteBluePalette_p; currentBlending = LINEARBLEND; } } } void switchLights(){ ChangePalettePeriodically(); static uint8_t startIndex = 0; startIndex = startIndex + 1; /* motion speed */ FillLEDsFromPaletteColors( startIndex); FastLED.show(); FastLED.delay(1000 / UPDATES_PER_SECOND); } // Lighting effect states enum LightEffect { LIGHT_IDLE, LIGHT_GREEN_BLINK, LIGHT_RED_BLINK, LIGHT_CRAZY }; volatile LightEffect currentLightMode = LIGHT_IDLE; unsigned long lightEffectStart = 0; const unsigned long effectDuration = 1000; // Duration of blink effects in ms void lightTask(void *pvParameters) { static LightEffect lastMode = LIGHT_IDLE; unsigned long now = millis(); while (true) { now = millis(); // Handle temporary effects if (currentLightMode != LIGHT_IDLE) { if (currentLightMode != lastMode) { lightEffectStart = now; lastMode = currentLightMode; } switch (currentLightMode) { case LIGHT_GREEN_BLINK: fill_solid(leds, NUM_LEDS, CRGB::Green); break; case LIGHT_RED_BLINK: fill_solid(leds, NUM_LEDS, CRGB::Red); break; case LIGHT_CRAZY: for (int i = 0; i < NUM_LEDS; i++) { leds[i] = CHSV(random8(), 255, 255); } break; default: break; } FastLED.show(); // End effect after duration if (now - lightEffectStart > effectDuration) { currentLightMode = LIGHT_IDLE; lastMode = LIGHT_IDLE; fill_solid(leds, NUM_LEDS, CRGB::Black); FastLED.show(); } } else { // Idle mode palette animation (optional) static uint8_t index = 0; fill_rainbow(leds, NUM_LEDS, index++); FastLED.show(); vTaskDelay(pdMS_TO_TICKS(50)); } vTaskDelay(pdMS_TO_TICKS(10)); } } #endif