Files
EspLedController/main/led.cpp
T

160 lines
4.6 KiB
C++

#include "led.h"
// system includes
#include <array>
// esp-idf includes
#include <driver/ledc.h>
// Arduino includes
#include <Arduino.h>
// 3rdparty lib includes
#include <FastLED.h>
#include <espchrono.h>
#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<CRGB, 5> 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);
}