#include "led.h" // system includes #include // esp-idf includes #include // Arduino includes #include // 3rdparty lib includes #include #include #define LEDC_CHANNEL_0 0 #define LEDC_CHANNEL_1 0 #define LEDC_CHANNEL_2 0 #define LEDC_TIMER_13_BIT 13 #define LEDC_BASE_FREQ 5000 namespace { std::array leds; CRGBPalette16 currentPalette; TBlendType currentBlending; extern CRGBPalette16 myRedWhiteBluePalette; extern const TProgmemPalette16 myRedWhiteBluePalette_p; void ledcAnalogWrite(uint8_t channel, uint32_t value, uint32_t valueMax = 255); } namespace { void ledcAnalogWrite(uint8_t channel, uint32_t value, uint32_t valueMax) { // calculate duty, 8191 from 2 ^ 13 - 1 uint32_t duty = (8191 / valueMax) * min(value, valueMax); // write duty to LEDC ledcWrite(channel, duty); } void FillLEDsFromPaletteColors( uint8_t colorIndex) { uint8_t brightness = 255; for( int i = 0; i < leds.size(); ++i) { leds[i] = ColorFromPalette( currentPalette, colorIndex, brightness, currentBlending); colorIndex += 3; } } void SetupTotallyRandomPalette() { for( int i = 0; i < 16; ++i) { currentPalette[i] = CHSV( random8(), 255, random8()); } } 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; } 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 ); } const TProgmemPalette16 myRedWhiteBluePalette_p = { 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() { constexpr auto millis = []() -> unsigned int { return espchrono::millis_clock::now().time_since_epoch().count(); }; 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 led_setup() { currentPalette = RainbowColors_p; currentBlending = LINEARBLEND; ledcSetup(LEDC_CHANNEL_0, LEDC_BASE_FREQ, LEDC_TIMER_13_BIT); ledcSetup(LEDC_CHANNEL_1, LEDC_BASE_FREQ, LEDC_TIMER_13_BIT); ledcSetup(LEDC_CHANNEL_2, LEDC_BASE_FREQ, LEDC_TIMER_13_BIT); ledcAttachPin(27, LEDC_CHANNEL_0); ledcAttachPin(33, LEDC_CHANNEL_1); ledcAttachPin(32, LEDC_CHANNEL_2); } void led_update() { ChangePalettePeriodically(); static uint8_t startIndex = 0; startIndex = startIndex + 1; /* motion speed */ FillLEDsFromPaletteColors( startIndex); ledcAnalogWrite(LEDC_CHANNEL_0, leds[0].red); ledcAnalogWrite(LEDC_CHANNEL_1, leds[0].green); ledcAnalogWrite(LEDC_CHANNEL_2, leds[0].blue); }