mirror of
https://github.com/wled/WLED.git
synced 2025-04-23 22:37:18 +00:00
Configuration item for harmonic palettes
Comment cleanup
This commit is contained in:
parent
66d9e8c038
commit
41e51bbeb5
@ -420,8 +420,8 @@ typedef struct Segment {
|
||||
// perhaps this should be per segment, not static
|
||||
static CRGBPalette16 _randomPalette; // actual random palette
|
||||
static CRGBPalette16 _newRandomPalette; // target random palette
|
||||
static uint16_t _lastPaletteChange; // last random palette change time in millis()/1000
|
||||
static uint16_t _lastPaletteBlend; // blend palette according to set Transition Delay in millis()%0xFFFF
|
||||
static uint16_t _lastPaletteChange; // last random palette change time in millis()/1000
|
||||
static uint16_t _lastPaletteBlend; // blend palette according to set Transition Delay in millis()%0xFFFF
|
||||
#ifndef WLED_DISABLE_MODE_BLEND
|
||||
static bool _modeBlend; // mode/effect blending semaphore
|
||||
#endif
|
||||
|
@ -77,10 +77,10 @@ uint16_t Segment::_usedSegmentData = 0U; // amount of RAM all segments use for t
|
||||
uint16_t Segment::maxWidth = DEFAULT_LED_COUNT;
|
||||
uint16_t Segment::maxHeight = 1;
|
||||
|
||||
CRGBPalette16 Segment::_randomPalette = generateRandomPalette();
|
||||
CRGBPalette16 Segment::_newRandomPalette = generateRandomPalette();
|
||||
uint16_t Segment::_lastPaletteChange = 0; // perhaps it should be per segment
|
||||
uint16_t Segment::_lastPaletteBlend = 0; //in millis (lowest 16 bits only)
|
||||
CRGBPalette16 Segment::_randomPalette = generateRandomPalette(); // was CRGBPalette16(DEFAULT_COLOR);
|
||||
CRGBPalette16 Segment::_newRandomPalette = generateRandomPalette(); // was CRGBPalette16(DEFAULT_COLOR);
|
||||
uint16_t Segment::_lastPaletteChange = 0; // perhaps it should be per segment
|
||||
uint16_t Segment::_lastPaletteBlend = 0; //in millis (lowest 16 bits only)
|
||||
|
||||
#ifndef WLED_DISABLE_MODE_BLEND
|
||||
bool Segment::_modeBlend = false;
|
||||
@ -221,9 +221,9 @@ CRGBPalette16 IRAM_ATTR &Segment::loadPalette(CRGBPalette16 &targetPalette, uint
|
||||
switch (pal) {
|
||||
case 0: //default palette. Exceptions for specific effects above
|
||||
targetPalette = PartyColors_p; break;
|
||||
case 1: {//periodically replace palette with a random one
|
||||
case 1: //randomly generated palette
|
||||
targetPalette = _randomPalette; //random palette is generated at intervals in handleRandomPalette()
|
||||
break;}
|
||||
break;
|
||||
case 2: {//primary color only
|
||||
CRGB prim = gamma32(colors[0]);
|
||||
targetPalette = CRGBPalette16(prim); break;}
|
||||
@ -452,24 +452,21 @@ CRGBPalette16 IRAM_ATTR &Segment::currentPalette(CRGBPalette16 &targetPalette, u
|
||||
return targetPalette;
|
||||
}
|
||||
|
||||
// relies on WS2812FX::service() to call it max every 8ms or more (MIN_SHOW_DELAY)
|
||||
// relies on WS2812FX::service() to call it for each frame
|
||||
void Segment::handleRandomPalette() {
|
||||
// just do a blend; if the palettes are identical it will just compare 48 bytes (same as _randomPalette == _newRandomPalette)
|
||||
// this will slowly blend _newRandomPalette into _randomPalette every 15ms or 8ms (depending on MIN_SHOW_DELAY)
|
||||
// if palette transitions is enabled, blend it according to Transition Time (if longer than minimum given by service calls)
|
||||
|
||||
// is it time to generate a new palette?
|
||||
if ((millis()/1000U) - _lastPaletteChange > randomPaletteChangeTime) {
|
||||
_newRandomPalette = generateHarmonicRandomPalette(_randomPalette);
|
||||
_newRandomPalette = useHarmonicRandomPalette ? generateHarmonicRandomPalette(_randomPalette) : generateRandomPalette();
|
||||
_lastPaletteChange = millis()/1000U;
|
||||
_lastPaletteBlend = (uint16_t)(millis()&0xFFFF)-512; //starts blending immediately
|
||||
_lastPaletteBlend = (uint16_t)(millis() & 0xFFFF)-512; // starts blending immediately
|
||||
}
|
||||
|
||||
if (strip.paletteFade)
|
||||
{
|
||||
if ((millis() & 0xFFFF) - _lastPaletteBlend < strip.getTransition() >> 7) {//assumes that 128 updates are needed to blend a palette, so shift by 7 (can be more, can be less)
|
||||
return; //not time to fade yet, delay the update
|
||||
}
|
||||
_lastPaletteBlend = millis();
|
||||
// if palette transitions is enabled, blend it according to Transition Time (if longer than minimum given by service calls)
|
||||
if (strip.paletteFade) {
|
||||
// assumes that 128 updates are sufficient to blend a palette, so shift by 7 (can be more, can be less)
|
||||
// in reality there need to be 255 blends to fully blend two entirely different palettes
|
||||
if ((millis() & 0xFFFF) - _lastPaletteBlend < strip.getTransition() >> 7) return; // not yet time to fade, delay the update
|
||||
_lastPaletteBlend = millis();
|
||||
}
|
||||
nblendPaletteTowardPalette(_randomPalette, _newRandomPalette, 48);
|
||||
}
|
||||
|
@ -395,6 +395,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
||||
strip.setTransition(fadeTransition ? transitionDelayDefault : 0);
|
||||
CJSON(strip.paletteFade, light_tr["pal"]);
|
||||
CJSON(randomPaletteChangeTime, light_tr[F("rpc")]);
|
||||
CJSON(useHarmonicRandomPalette, light_tr[F("hrp")]);
|
||||
|
||||
JsonObject light_nl = light["nl"];
|
||||
CJSON(nightlightMode, light_nl["mode"]);
|
||||
@ -872,6 +873,7 @@ void serializeConfig() {
|
||||
light_tr["dur"] = transitionDelayDefault / 100;
|
||||
light_tr["pal"] = strip.paletteFade;
|
||||
light_tr[F("rpc")] = randomPaletteChangeTime;
|
||||
light_tr[F("hrp")] = useHarmonicRandomPalette;
|
||||
|
||||
JsonObject light_nl = light.createNestedObject("nl");
|
||||
light_nl["mode"] = nightlightMode;
|
||||
|
@ -91,12 +91,11 @@ void setRandomColor(byte* rgb)
|
||||
colorHStoRGB(lastRandomIndex*256,255,rgb);
|
||||
}
|
||||
|
||||
/*
|
||||
*generates a random palette based on harmonic color theory
|
||||
*takes a base palette as the input, it will choose one color of the base palette and keep it
|
||||
/*
|
||||
* generates a random palette based on harmonic color theory
|
||||
* takes a base palette as the input, it will choose one color of the base palette and keep it
|
||||
*/
|
||||
|
||||
CRGBPalette16 generateHarmonicRandomPalette(CRGBPalette16 &basepalette)
|
||||
CRGBPalette16 generateHarmonicRandomPalette(CRGBPalette16 &basepalette)
|
||||
{
|
||||
CHSV palettecolors[4]; //array of colors for the new palette
|
||||
uint8_t keepcolorposition = random8(4); //color position of current random palette to keep
|
||||
@ -104,7 +103,7 @@ CRGBPalette16 generateHarmonicRandomPalette(CRGBPalette16 &basepalette)
|
||||
palettecolors[keepcolorposition].hue += random8(10)-5; // +/- 5 randomness of base color
|
||||
//generate 4 saturation and brightness value numbers
|
||||
//only one saturation is allowed to be below 200 creating mostly vibrant colors
|
||||
//only one brightness value number is allowed below 200, creating mostly bright palettes
|
||||
//only one brightness value number is allowed below 200, creating mostly bright palettes
|
||||
|
||||
for (int i = 0; i < 3; i++) { //generate three high values
|
||||
palettecolors[i].saturation = random8(200,255);
|
||||
@ -114,8 +113,7 @@ CRGBPalette16 generateHarmonicRandomPalette(CRGBPalette16 &basepalette)
|
||||
palettecolors[3].saturation = random8(20,255);
|
||||
palettecolors[3].value = random8(80,255);
|
||||
|
||||
|
||||
//shuffle the arrays
|
||||
//shuffle the arrays
|
||||
for (int i = 3; i > 0; i--) {
|
||||
std::swap(palettecolors[i].saturation, palettecolors[random8(i + 1)].saturation);
|
||||
std::swap(palettecolors[i].value, palettecolors[random8(i + 1)].value);
|
||||
@ -151,17 +149,15 @@ CRGBPalette16 generateHarmonicRandomPalette(CRGBPalette16 &basepalette)
|
||||
harmonics[2] = basehue + 265 + random8(10);
|
||||
break;
|
||||
|
||||
case 4: // tetradic
|
||||
case 4: // tetradic
|
||||
harmonics[0] = basehue + 80 + random8(20);
|
||||
harmonics[1] = basehue + 170 + random8(20);
|
||||
harmonics[2] = basehue + random8(30)-15;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (random8() < 128) //50:50 chance of shuffeling hues or keep the color order
|
||||
{
|
||||
//shuffle the hues:
|
||||
if (random8() < 128) {
|
||||
//50:50 chance of shuffling hues or keep the color order
|
||||
for (int i = 2; i > 0; i--) {
|
||||
std::swap(harmonics[i], harmonics[random8(i + 1)]);
|
||||
}
|
||||
@ -170,36 +166,35 @@ CRGBPalette16 generateHarmonicRandomPalette(CRGBPalette16 &basepalette)
|
||||
//now set the hues
|
||||
int j = 0;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if(i==keepcolorposition) continue; //skip the base color
|
||||
if (i==keepcolorposition) continue; //skip the base color
|
||||
palettecolors[i].hue = harmonics[j];
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
bool makepastelpalette = false;
|
||||
if (random8() < 25) {//~10% chance of desaturated 'pastel' colors
|
||||
makepastelpalette = true;
|
||||
if (random8() < 25) { //~10% chance of desaturated 'pastel' colors
|
||||
makepastelpalette = true;
|
||||
}
|
||||
|
||||
//apply saturation & gamma correction
|
||||
CRGB RGBpalettecolors[4];
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if(makepastelpalette && palettecolors[i].saturation > 180) {
|
||||
if (makepastelpalette && palettecolors[i].saturation > 180) {
|
||||
palettecolors[i].saturation -= 160; //desaturate all four colors
|
||||
}
|
||||
RGBpalettecolors[i] = (CRGB)palettecolors[i]; //convert to RGB
|
||||
RGBpalettecolors[i] = gamma32((uint32_t)RGBpalettecolors[i]);
|
||||
RGBpalettecolors[i] = gamma32(((uint32_t)RGBpalettecolors[i]) & 0x00FFFFFFU); //strip alpha from CRGB
|
||||
}
|
||||
|
||||
return CRGBPalette16( RGBpalettecolors[0],
|
||||
RGBpalettecolors[1],
|
||||
RGBpalettecolors[2],
|
||||
RGBpalettecolors[3]);
|
||||
return CRGBPalette16(RGBpalettecolors[0],
|
||||
RGBpalettecolors[1],
|
||||
RGBpalettecolors[2],
|
||||
RGBpalettecolors[3]);
|
||||
}
|
||||
|
||||
CRGBPalette16 generateRandomPalette(void) //generate fully random palette
|
||||
{
|
||||
return CRGBPalette16(
|
||||
CHSV(random8(), random8(160, 255), random8(128, 255)),
|
||||
return CRGBPalette16(CHSV(random8(), random8(160, 255), random8(128, 255)),
|
||||
CHSV(random8(), random8(160, 255), random8(128, 255)),
|
||||
CHSV(random8(), random8(160, 255), random8(128, 255)),
|
||||
CHSV(random8(), random8(160, 255), random8(128, 255)));
|
||||
|
@ -848,6 +848,7 @@ Swap: <select id="xw${i}" name="XW${i}">
|
||||
Palette transitions: <input type="checkbox" name="PF"><br>
|
||||
</span>
|
||||
<i>Random Cycle</i> Palette Time: <input name="TP" type="number" class="m" min="1" max="255"> s<br>
|
||||
Use harmonic <i>Random Cycle</i> Palette: <input type="checkbox" name="TH"><br>
|
||||
<h3>Timed light</h3>
|
||||
Default Duration: <input name="TL" type="number" class="m" min="1" max="255" required> min<br>
|
||||
Default Target brightness: <input name="TB" type="number" class="m" min="0" max="255" required><br>
|
||||
|
@ -302,6 +302,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||
strip.paletteFade = request->hasArg(F("PF"));
|
||||
t = request->arg(F("TP")).toInt();
|
||||
randomPaletteChangeTime = MIN(255,MAX(1,t));
|
||||
useHarmonicRandomPalette = request->hasArg(F("TH"));
|
||||
|
||||
nightlightTargetBri = request->arg(F("TB")).toInt();
|
||||
t = request->arg(F("TL")).toInt();
|
||||
|
@ -542,15 +542,16 @@ WLED_GLOBAL bool wasConnected _INIT(false);
|
||||
WLED_GLOBAL byte lastRandomIndex _INIT(0); // used to save last random color so the new one is not the same
|
||||
|
||||
// transitions
|
||||
WLED_GLOBAL bool fadeTransition _INIT(true); // enable crossfading brightness/color
|
||||
WLED_GLOBAL bool modeBlending _INIT(true); // enable effect blending
|
||||
WLED_GLOBAL bool transitionActive _INIT(false);
|
||||
WLED_GLOBAL uint16_t transitionDelay _INIT(750); // global transition duration
|
||||
WLED_GLOBAL uint16_t transitionDelayDefault _INIT(750); // default transition time (stored in cfg.json)
|
||||
WLED_GLOBAL bool fadeTransition _INIT(true); // enable crossfading brightness/color
|
||||
WLED_GLOBAL bool modeBlending _INIT(true); // enable effect blending
|
||||
WLED_GLOBAL bool transitionActive _INIT(false);
|
||||
WLED_GLOBAL uint16_t transitionDelay _INIT(750); // global transition duration
|
||||
WLED_GLOBAL uint16_t transitionDelayDefault _INIT(750); // default transition time (stored in cfg.json)
|
||||
WLED_GLOBAL unsigned long transitionStartTime;
|
||||
WLED_GLOBAL float tperLast _INIT(0.0f); // crossfade transition progress, 0.0f - 1.0f
|
||||
WLED_GLOBAL bool jsonTransitionOnce _INIT(false); // flag to override transitionDelay (playlist, JSON API: "live" & "seg":{"i"} & "tt")
|
||||
WLED_GLOBAL uint8_t randomPaletteChangeTime _INIT(5); // amount of time [s] between random palette changes (min: 1s, max: 255s)
|
||||
WLED_GLOBAL float tperLast _INIT(0.0f); // crossfade transition progress, 0.0f - 1.0f
|
||||
WLED_GLOBAL bool jsonTransitionOnce _INIT(false); // flag to override transitionDelay (playlist, JSON API: "live" & "seg":{"i"} & "tt")
|
||||
WLED_GLOBAL uint8_t randomPaletteChangeTime _INIT(5); // amount of time [s] between random palette changes (min: 1s, max: 255s)
|
||||
WLED_GLOBAL bool useHarmonicRandomPalette _INIT(true); // use *harmonic* random palette generation (nicer looking) or truly random
|
||||
|
||||
// nightlight
|
||||
WLED_GLOBAL bool nightlightActive _INIT(false);
|
||||
|
@ -453,6 +453,7 @@ void getSettingsJS(byte subPage, char* dest)
|
||||
sappend('v',SET_F("TD"),transitionDelayDefault);
|
||||
sappend('c',SET_F("PF"),strip.paletteFade);
|
||||
sappend('v',SET_F("TP"),randomPaletteChangeTime);
|
||||
sappend('c',SET_F("TH"),useHarmonicRandomPalette);
|
||||
sappend('v',SET_F("BF"),briMultiplier);
|
||||
sappend('v',SET_F("TB"),nightlightTargetBri);
|
||||
sappend('v',SET_F("TL"),nightlightDelayMinsDefault);
|
||||
|
Loading…
x
Reference in New Issue
Block a user