Release of v0.8.3

Removed initLedsLast
Improved Fireworks
This commit is contained in:
cschwinne 2019-02-11 23:49:04 +01:00
parent 6e76fc0aa7
commit 9caca37ab1
12 changed files with 825 additions and 801 deletions

View File

@ -416,44 +416,6 @@ uint16_t WS2812FX::mode_twinkle(void) {
} }
/*
* fade out function
* fades out the current segment by dividing each pixel's intensity by 2
*/
void WS2812FX::fade_out(uint8_t rate) {
static const float rateMap[] = {1.1, 1.20, 1.5, 2.0, 4.0, 8.0, 16.0, 64.0};
if (rate > 7) rate = 7;
float mappedRate = rateMap[rate];
uint32_t color = SEGMENT.colors[1]; // target color
int w2 = (color >> 24) & 0xff;
int r2 = (color >> 16) & 0xff;
int g2 = (color >> 8) & 0xff;
int b2 = color & 0xff;
for(uint16_t i=SEGMENT.start; i <= SEGMENT.stop; i++) {
color = getPixelColor(i);
int w1 = (color >> 24) & 0xff;
int r1 = (color >> 16) & 0xff;
int g1 = (color >> 8) & 0xff;
int b1 = color & 0xff;
int wdelta = (w2 - w1) / mappedRate;
int rdelta = (r2 - r1) / mappedRate;
int gdelta = (g2 - g1) / mappedRate;
int bdelta = (b2 - b1) / mappedRate;
// if fade isn't complete, make sure delta is at least 1 (fixes rounding issues)
wdelta += (w2 == w1) ? 0 : (w2 > w1) ? 1 : -1;
rdelta += (r2 == r1) ? 0 : (r2 > r1) ? 1 : -1;
gdelta += (g2 == g1) ? 0 : (g2 > g1) ? 1 : -1;
bdelta += (b2 == b1) ? 0 : (b2 > b1) ? 1 : -1;
setPixelColor(i, r1 + rdelta, g1 + gdelta, b1 + bdelta, w1 + wdelta);
}
}
/* /*
* Dissolve function * Dissolve function
*/ */
@ -647,18 +609,12 @@ uint16_t WS2812FX::mode_android(void) {
* color1 = background color * color1 = background color
* color2 and color3 = colors of two adjacent leds * color2 and color3 = colors of two adjacent leds
*/ */
uint16_t WS2812FX::chase(uint32_t color1, uint32_t color2, uint32_t color3, uint8_t dopalette) { uint16_t WS2812FX::chase(uint32_t color1, uint32_t color2, uint32_t color3, bool dopalette) {
uint16_t a = SEGMENT_RUNTIME.counter_mode_step; uint16_t a = SEGMENT_RUNTIME.counter_mode_step;
uint16_t b = (a + 1) % SEGMENT_LENGTH; uint16_t b = (a + 1) % SEGMENT_LENGTH;
uint16_t c = (b + 1) % SEGMENT_LENGTH; uint16_t c = (b + 1) % SEGMENT_LENGTH;
switch (dopalette) if (dopalette) color1 = color_from_palette(SEGMENT.start + a, true, PALETTE_SOLID_WRAP, 1);
{
case 0: break;
case 1: color1 = color_from_palette(SEGMENT.start + a, true, PALETTE_SOLID_WRAP, 1); break;
case 2: color2 = color_from_palette(SEGMENT.start + b, true, PALETTE_SOLID_WRAP, 1); break;
case 3: color3 = color_from_palette(SEGMENT.start + c, true, PALETTE_SOLID_WRAP, 1); break;
}
setPixelColor(SEGMENT.start + a, color1); setPixelColor(SEGMENT.start + a, color1);
setPixelColor(SEGMENT.start + b, color2); setPixelColor(SEGMENT.start + b, color2);
@ -673,7 +629,7 @@ uint16_t WS2812FX::chase(uint32_t color1, uint32_t color2, uint32_t color3, uint
* Bicolor chase, more primary color. * Bicolor chase, more primary color.
*/ */
uint16_t WS2812FX::mode_chase_color(void) { uint16_t WS2812FX::mode_chase_color(void) {
return chase(SEGMENT.colors[1], SEGMENT.colors[0], SEGMENT.colors[0], 1); return chase(SEGMENT.colors[1], SEGMENT.colors[0], SEGMENT.colors[0], true);
} }
@ -684,7 +640,7 @@ uint16_t WS2812FX::mode_chase_random(void) {
if(SEGMENT_RUNTIME.counter_mode_step == 0) { if(SEGMENT_RUNTIME.counter_mode_step == 0) {
SEGMENT_RUNTIME.aux_param = get_random_wheel_index(SEGMENT_RUNTIME.aux_param); SEGMENT_RUNTIME.aux_param = get_random_wheel_index(SEGMENT_RUNTIME.aux_param);
} }
return chase(color_wheel(SEGMENT_RUNTIME.aux_param), SEGMENT.colors[0], SEGMENT.colors[0], 0); return chase(color_wheel(SEGMENT_RUNTIME.aux_param), SEGMENT.colors[0], SEGMENT.colors[0], false);
} }
@ -697,7 +653,7 @@ uint16_t WS2812FX::mode_chase_rainbow_white(void) {
uint32_t color2 = color_wheel(((n * 256 / SEGMENT_LENGTH) + (SEGMENT_RUNTIME.counter_mode_call & 0xFF)) & 0xFF); uint32_t color2 = color_wheel(((n * 256 / SEGMENT_LENGTH) + (SEGMENT_RUNTIME.counter_mode_call & 0xFF)) & 0xFF);
uint32_t color3 = color_wheel(((m * 256 / SEGMENT_LENGTH) + (SEGMENT_RUNTIME.counter_mode_call & 0xFF)) & 0xFF); uint32_t color3 = color_wheel(((m * 256 / SEGMENT_LENGTH) + (SEGMENT_RUNTIME.counter_mode_call & 0xFF)) & 0xFF);
return chase(SEGMENT.colors[0], color2, color3, 0); return chase(SEGMENT.colors[0], color2, color3, false);
} }
@ -924,7 +880,7 @@ uint16_t WS2812FX::mode_running_random(void) {
* K.I.T.T. * K.I.T.T.
*/ */
uint16_t WS2812FX::mode_larson_scanner(void) { uint16_t WS2812FX::mode_larson_scanner(void) {
fade_out((255-SEGMENT.intensity) / 32); fade_out(SEGMENT.intensity);
uint16_t index = 0; uint16_t index = 0;
if(SEGMENT_RUNTIME.counter_mode_step < SEGMENT_LENGTH) { if(SEGMENT_RUNTIME.counter_mode_step < SEGMENT_LENGTH) {
@ -943,7 +899,7 @@ uint16_t WS2812FX::mode_larson_scanner(void) {
* Firing comets from one end. * Firing comets from one end.
*/ */
uint16_t WS2812FX::mode_comet(void) { uint16_t WS2812FX::mode_comet(void) {
fade_out((255-SEGMENT.intensity) / 32); fade_out(SEGMENT.intensity);
uint16_t index = SEGMENT.start + SEGMENT_RUNTIME.counter_mode_step; uint16_t index = SEGMENT.start + SEGMENT_RUNTIME.counter_mode_step;
setPixelColor(index, color_from_palette(index, true, PALETTE_SOLID_WRAP, 0)); setPixelColor(index, color_from_palette(index, true, PALETTE_SOLID_WRAP, 0));
@ -956,50 +912,53 @@ uint16_t WS2812FX::mode_comet(void) {
/* /*
* Fireworks function. * Fireworks function.
*/ */
uint16_t WS2812FX::fireworks(uint32_t color) { uint16_t WS2812FX::mode_fireworks() {
uint32_t prevLed, thisLed, nextLed; fade_out(0);
if (SEGMENT_RUNTIME.counter_mode_call == 0) {
fade_out(3); SEGMENT_RUNTIME.aux_param = UINT16_MAX;
SEGMENT_RUNTIME.aux_param2 = UINT16_MAX;
// set brightness(i) = ((brightness(i-1)/4 + brightness(i+1))/4) + brightness(i)
for(uint16_t i=SEGMENT.start + 1; i <SEGMENT.stop; i++) {
prevLed = (getPixelColor(i-1) >> 2) & 0x3F3F3F3F;
thisLed = getPixelColor(i);
nextLed = (getPixelColor(i+1) >> 2) & 0x3F3F3F3F;
setPixelColor(i, prevLed + thisLed + nextLed);
} }
bool valid1 = (SEGMENT_RUNTIME.aux_param <= SEGMENT.stop && SEGMENT_RUNTIME.aux_param >= SEGMENT.start);
bool valid2 = (SEGMENT_RUNTIME.aux_param2 <= SEGMENT.stop && SEGMENT_RUNTIME.aux_param2 >= SEGMENT.start);
uint32_t sv1 = 0, sv2 = 0;
if (valid1) sv1 = getPixelColor(SEGMENT_RUNTIME.aux_param);
if (valid2) sv2 = getPixelColor(SEGMENT_RUNTIME.aux_param2);
blur(255-SEGMENT.speed);
if (valid1) setPixelColor(SEGMENT_RUNTIME.aux_param , sv1);
if (valid2) setPixelColor(SEGMENT_RUNTIME.aux_param2, sv2);
for(uint16_t i=0; i<max(1, SEGMENT_LENGTH/20); i++) { for(uint16_t i=0; i<max(1, SEGMENT_LENGTH/20); i++) {
if(random8((255 - SEGMENT.intensity)/8) == 0) { if(random8(129 - (SEGMENT.intensity >> 1)) == 0) {
uint16_t index = SEGMENT.start + random16(SEGMENT_LENGTH); uint16_t index = SEGMENT.start + random(SEGMENT_LENGTH);
if (color == SEGMENT.colors[0]) setPixelColor(index, color_from_palette(random8(), false, false, 0));
{ SEGMENT_RUNTIME.aux_param2 = SEGMENT_RUNTIME.aux_param;
setPixelColor(index, color_from_palette(index, true, PALETTE_SOLID_WRAP, 0)); SEGMENT_RUNTIME.aux_param = index;
} else
{
setPixelColor(index, color);
}
} }
} }
return SPEED_FORMULA_L; return 22;
} }
/* //Twinkling LEDs running. Inspired by https://github.com/kitesurfer1404/WS2812FX/blob/master/src/custom/Rain.h
* Firework sparks. uint16_t WS2812FX::mode_rain()
*/ {
uint16_t WS2812FX::mode_fireworks(void) { SEGMENT_RUNTIME.counter_mode_step += 22;
uint32_t color = SEGMENT.colors[0]; if (SEGMENT_RUNTIME.counter_mode_step > SPEED_FORMULA_L) {
return fireworks(color); SEGMENT_RUNTIME.counter_mode_step = 0;
} //shift all leds right
uint32_t ctemp = getPixelColor(SEGMENT.stop);
for(uint16_t i=SEGMENT.stop; i>SEGMENT.start; i--) {
/* setPixelColor(i, getPixelColor(i-1));
* Random colored firework sparks. }
*/ setPixelColor(SEGMENT.start, ctemp);
uint16_t WS2812FX::mode_fireworks_random(void) { SEGMENT_RUNTIME.aux_param++;
uint32_t color = color_wheel(random8()); SEGMENT_RUNTIME.aux_param2++;
return fireworks(color); if (SEGMENT_RUNTIME.aux_param == 0) SEGMENT_RUNTIME.aux_param = UINT16_MAX;
if (SEGMENT_RUNTIME.aux_param2 == 0) SEGMENT_RUNTIME.aux_param = UINT16_MAX;
if (SEGMENT_RUNTIME.aux_param == SEGMENT.stop +1) SEGMENT_RUNTIME.aux_param = SEGMENT.start;
if (SEGMENT_RUNTIME.aux_param2 == SEGMENT.stop +1) SEGMENT_RUNTIME.aux_param2 = SEGMENT.start;
}
return mode_fireworks();
} }
@ -1256,13 +1215,13 @@ uint16_t WS2812FX::mode_dual_color_wipe_out_in(void) {
/* /*
* Tricolor chase function * Tricolor chase function
*/ */
uint16_t WS2812FX::tricolor_chase(uint32_t color1, uint32_t color2, uint32_t color3) { uint16_t WS2812FX::tricolor_chase(uint32_t color1, uint32_t color2) {
uint16_t index = SEGMENT_RUNTIME.counter_mode_step % 6; uint16_t index = SEGMENT_RUNTIME.counter_mode_step % 6;
for(uint16_t i=0; i < SEGMENT_LENGTH; i++, index++) { for(uint16_t i=0; i < SEGMENT_LENGTH; i++, index++) {
if(index > 5) index = 0; if(index > 5) index = 0;
uint32_t color = color1; uint32_t color = color1;
if(index > 3) color = color_from_palette(i, true, PALETTE_SOLID_WRAP, 2); if(index > 3) color = color_from_palette(i, true, PALETTE_SOLID_WRAP, 1);
else if(index > 1) color = color2; else if(index > 1) color = color2;
setPixelColor(SEGMENT.stop - i, color); setPixelColor(SEGMENT.stop - i, color);
@ -1277,7 +1236,7 @@ uint16_t WS2812FX::tricolor_chase(uint32_t color1, uint32_t color2, uint32_t col
* Alternating white/red/black pixels running. PLACEHOLDER * Alternating white/red/black pixels running. PLACEHOLDER
*/ */
uint16_t WS2812FX::mode_circus_combustus(void) { uint16_t WS2812FX::mode_circus_combustus(void) {
return tricolor_chase(RED, WHITE, BLACK); return tricolor_chase(RED, WHITE);
} }
@ -1285,7 +1244,7 @@ uint16_t WS2812FX::mode_circus_combustus(void) {
* Tricolor chase mode * Tricolor chase mode
*/ */
uint16_t WS2812FX::mode_tricolor_chase(void) { uint16_t WS2812FX::mode_tricolor_chase(void) {
return tricolor_chase(SEGMENT.colors[1], SEGMENT.colors[0], SEGMENT.colors[2]); return tricolor_chase(SEGMENT.colors[2], SEGMENT.colors[0]);
} }
@ -1400,11 +1359,11 @@ uint16_t WS2812FX::mode_tricolor_fade(void)
*/ */
uint16_t WS2812FX::mode_multi_comet(void) uint16_t WS2812FX::mode_multi_comet(void)
{ {
fade_out((255-SEGMENT.intensity) / 32); fade_out(SEGMENT.intensity);
static uint16_t comets[] = {UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX}; static uint16_t comets[] = {UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX};
for(uint8_t i=0; i < 6; i++) { for(uint8_t i=0; i < 8; i++) {
if(comets[i] < SEGMENT_LENGTH) { if(comets[i] < SEGMENT_LENGTH) {
uint16_t index = SEGMENT.start + comets[i]; uint16_t index = SEGMENT.start + comets[i];
if (SEGMENT.colors[2] != 0) if (SEGMENT.colors[2] != 0)
@ -1438,7 +1397,7 @@ uint16_t WS2812FX::mode_dual_larson_scanner(void){
SEGMENT_RUNTIME.counter_mode_step++; SEGMENT_RUNTIME.counter_mode_step++;
} }
fade_out((255-SEGMENT.intensity) / 32); fade_out(SEGMENT.intensity);
uint16_t index = SEGMENT.start + SEGMENT_RUNTIME.counter_mode_step; uint16_t index = SEGMENT.start + SEGMENT_RUNTIME.counter_mode_step;
setPixelColor(index, color_from_palette(index, true, PALETTE_SOLID_WRAP, 0)); setPixelColor(index, color_from_palette(index, true, PALETTE_SOLID_WRAP, 0));
@ -1476,6 +1435,7 @@ uint16_t WS2812FX::mode_random_chase(void)
return SPEED_FORMULA_L; return SPEED_FORMULA_L;
} }
typedef struct Oscillator { typedef struct Oscillator {
int16_t pos; int16_t pos;
int8_t size; int8_t size;
@ -1605,13 +1565,13 @@ uint16_t WS2812FX::mode_pride_2015(void)
//eight colored dots, weaving in and out of sync with each other //eight colored dots, weaving in and out of sync with each other
uint16_t WS2812FX::mode_juggle(void){ uint16_t WS2812FX::mode_juggle(void){
fade_out((255-SEGMENT.intensity) / 32); fade_out(SEGMENT.intensity);
CRGB fastled_col; CRGB fastled_col;
byte dothue = 0; byte dothue = 0;
for ( byte i = 0; i < 8; i++) { for ( byte i = 0; i < 8; i++) {
uint16_t index = SEGMENT.start + beatsin16(i + 7, 0, SEGMENT_LENGTH -1); uint16_t index = SEGMENT.start + beatsin16(i + 7, 0, SEGMENT_LENGTH -1);
fastled_col = fastled_from_col(getPixelColor(index)); fastled_col = fastled_from_col(getPixelColor(index));
fastled_col |= CHSV(dothue, 220, 255); fastled_col |= (SEGMENT.palette==0)?CHSV(dothue, 220, 255):ColorFromPalette(currentPalette, dothue, 255);
setPixelColor(index, fastled_col.red, fastled_col.green, fastled_col.blue); setPixelColor(index, fastled_col.red, fastled_col.green, fastled_col.blue);
dothue += 32; dothue += 32;
} }
@ -2036,10 +1996,8 @@ uint16_t WS2812FX::mode_railway()
//Water ripple //Water ripple
//fade duration is random 2-5sec
//propagation velocity from speed //propagation velocity from speed
//drop rate from intensity //drop rate from intensity
//? smooth sine instead of shifting +2
uint16_t WS2812FX::mode_ripple() uint16_t WS2812FX::mode_ripple()
{ {
uint16_t maxripples = SEGMENT_LENGTH / 4; uint16_t maxripples = SEGMENT_LENGTH / 4;

View File

@ -118,7 +118,7 @@
#define FX_MODE_LARSON_SCANNER 40 #define FX_MODE_LARSON_SCANNER 40
#define FX_MODE_COMET 41 #define FX_MODE_COMET 41
#define FX_MODE_FIREWORKS 42 #define FX_MODE_FIREWORKS 42
#define FX_MODE_FIREWORKS_RANDOM 43 #define FX_MODE_RAIN 43
#define FX_MODE_MERRY_CHRISTMAS 44 #define FX_MODE_MERRY_CHRISTMAS 44
#define FX_MODE_FIRE_FLICKER 45 #define FX_MODE_FIRE_FLICKER 45
#define FX_MODE_GRADIENT 46 #define FX_MODE_GRADIENT 46
@ -226,7 +226,7 @@ class WS2812FX {
_mode[FX_MODE_LARSON_SCANNER] = &WS2812FX::mode_larson_scanner; _mode[FX_MODE_LARSON_SCANNER] = &WS2812FX::mode_larson_scanner;
_mode[FX_MODE_COMET] = &WS2812FX::mode_comet; _mode[FX_MODE_COMET] = &WS2812FX::mode_comet;
_mode[FX_MODE_FIREWORKS] = &WS2812FX::mode_fireworks; _mode[FX_MODE_FIREWORKS] = &WS2812FX::mode_fireworks;
_mode[FX_MODE_FIREWORKS_RANDOM] = &WS2812FX::mode_fireworks_random; _mode[FX_MODE_RAIN] = &WS2812FX::mode_rain;
_mode[FX_MODE_MERRY_CHRISTMAS] = &WS2812FX::mode_merry_christmas; _mode[FX_MODE_MERRY_CHRISTMAS] = &WS2812FX::mode_merry_christmas;
_mode[FX_MODE_FIRE_FLICKER] = &WS2812FX::mode_fire_flicker; _mode[FX_MODE_FIRE_FLICKER] = &WS2812FX::mode_fire_flicker;
_mode[FX_MODE_GRADIENT] = &WS2812FX::mode_gradient; _mode[FX_MODE_GRADIENT] = &WS2812FX::mode_gradient;
@ -267,7 +267,6 @@ class WS2812FX {
_mode[FX_MODE_RIPPLE] = &WS2812FX::mode_ripple; _mode[FX_MODE_RIPPLE] = &WS2812FX::mode_ripple;
_brightness = DEFAULT_BRIGHTNESS; _brightness = DEFAULT_BRIGHTNESS;
_running = false;
_num_segments = 1; _num_segments = 1;
_segments[0].mode = DEFAULT_MODE; _segments[0].mode = DEFAULT_MODE;
_segments[0].colors[0] = DEFAULT_COLOR; _segments[0].colors[0] = DEFAULT_COLOR;
@ -283,6 +282,7 @@ class WS2812FX {
ablMilliampsMax = 750; ablMilliampsMax = 750;
currentMilliamps = 0; currentMilliamps = 0;
_locked = NULL; _locked = NULL;
_modeUsesLock = false;
_cronixieDigits = new byte[6]; _cronixieDigits = new byte[6];
bus = new NeoPixelWrapper(); bus = new NeoPixelWrapper();
RESET_RUNTIME; RESET_RUNTIME;
@ -291,6 +291,7 @@ class WS2812FX {
void void
init(bool supportWhite, uint16_t countPixels, bool skipFirst), init(bool supportWhite, uint16_t countPixels, bool skipFirst),
service(void), service(void),
blur(uint8_t),
fade_out(uint8_t r), fade_out(uint8_t r),
setMode(uint8_t m), setMode(uint8_t m),
setSpeed(uint8_t s), setSpeed(uint8_t s),
@ -362,11 +363,10 @@ class WS2812FX {
theater_chase(uint32_t, uint32_t, bool), theater_chase(uint32_t, uint32_t, bool),
running_base(bool), running_base(bool),
dissolve(uint32_t), dissolve(uint32_t),
chase(uint32_t, uint32_t, uint32_t, uint8_t), chase(uint32_t, uint32_t, uint32_t, bool),
gradient_base(bool), gradient_base(bool),
running(uint32_t, uint32_t), running(uint32_t, uint32_t),
fireworks(uint32_t), tricolor_chase(uint32_t, uint32_t);
tricolor_chase(uint32_t, uint32_t, uint32_t);
// builtin modes // builtin modes
uint16_t uint16_t
@ -413,7 +413,7 @@ class WS2812FX {
mode_larson_scanner(void), mode_larson_scanner(void),
mode_comet(void), mode_comet(void),
mode_fireworks(void), mode_fireworks(void),
mode_fireworks_random(void), mode_rain(void),
mode_merry_christmas(void), mode_merry_christmas(void),
mode_halloween(void), mode_halloween(void),
mode_fire_flicker(void), mode_fire_flicker(void),
@ -467,8 +467,8 @@ class WS2812FX {
void fill(uint32_t); void fill(uint32_t);
bool modeUsesLock(uint8_t); bool modeUsesLock(uint8_t);
boolean bool
_running, _modeUsesLock,
_rgbwMode, _rgbwMode,
_reverseMode, _reverseMode,
_cronixieMode, _cronixieMode,
@ -539,7 +539,7 @@ const char JSON_mode_names[] PROGMEM = R"=====({"effects":[
"Scanner", "Scanner",
"Lighthouse", "Lighthouse",
"Fireworks", "Fireworks",
"Fireworks Rnd", "Rain",
"Merry Christmas", "Merry Christmas",
"Fire Flicker", "Fire Flicker",
"Gradient", "Gradient",

View File

@ -51,36 +51,34 @@ void WS2812FX::init(bool supportWhite, uint16_t countPixels, bool skipFirst)
unlockAll(); unlockAll();
setBrightness(_brightness); setBrightness(_brightness);
_running = true;
} }
void WS2812FX::service() { void WS2812FX::service() {
if(_running || _triggered) { unsigned long now = millis(); // Be aware, millis() rolls over every 49 days
unsigned long now = millis(); // Be aware, millis() rolls over every 49 days bool doShow = false;
bool doShow = false; for(uint8_t i=0; i < _num_segments; i++)
for(uint8_t i=0; i < _num_segments; i++) {
_segment_index = i;
if(now > SEGMENT_RUNTIME.next_time || _triggered)
{ {
_segment_index = i; doShow = true;
if(now > SEGMENT_RUNTIME.next_time || _triggered) handle_palette();
{ uint16_t delay = (this->*_mode[SEGMENT.mode])();
doShow = true; SEGMENT_RUNTIME.next_time = now + max(delay, 5);
handle_palette(); SEGMENT_RUNTIME.counter_mode_call++;
uint16_t delay = (this->*_mode[SEGMENT.mode])();
SEGMENT_RUNTIME.next_time = now + max(delay, 5);
SEGMENT_RUNTIME.counter_mode_call++;
}
} }
if(doShow) {
show();
}
_triggered = false;
} }
if(doShow) {
show();
}
_triggered = false;
} }
bool WS2812FX::modeUsesLock(uint8_t m) bool WS2812FX::modeUsesLock(uint8_t m)
{ {
if (m < FX_MODE_FIRE_2012) return false; if (m == FX_MODE_FIRE_2012 || m == FX_MODE_COLORTWINKLE ||
if (m == FX_MODE_FIRE_2012 || m == FX_MODE_COLORTWINKLE || m == FX_MODE_METEOR || m == FX_MODE_METEOR_SMOOTH || m == FX_MODE_RIPPLE) return true; m == FX_MODE_METEOR || m == FX_MODE_METEOR_SMOOTH ||
m == FX_MODE_RIPPLE) return true;
return false; return false;
} }
@ -94,7 +92,7 @@ void WS2812FX::setPixelColor(uint16_t n, uint32_t c) {
void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w) void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w)
{ {
if (_locked[i] && !modeUsesLock(SEGMENT.mode)) return; if (_locked[i] && !_modeUsesLock) return;
if (_reverseMode) i = _length - 1 -i; if (_reverseMode) i = _length - 1 -i;
if (IS_REVERSE) i = SEGMENT.stop - (i - SEGMENT.start); //reverse just individual segment if (IS_REVERSE) i = SEGMENT.stop - (i - SEGMENT.start); //reverse just individual segment
byte tmpg = g; byte tmpg = g;
@ -257,6 +255,7 @@ void WS2812FX::setMode(uint8_t m) {
if (m > MODE_COUNT - 1) m = MODE_COUNT - 1; if (m > MODE_COUNT - 1) m = MODE_COUNT - 1;
_segments[0].mode = m; _segments[0].mode = m;
if (ua) unlockAll(); if (ua) unlockAll();
_modeUsesLock = modeUsesLock(_segments[0].mode);
setBrightness(_brightness); setBrightness(_brightness);
} }
@ -510,6 +509,68 @@ void WS2812FX::fill(uint32_t c) {
} }
} }
/*
* fade out function, higher rate = quicker fade
*/
void WS2812FX::fade_out(uint8_t rate) {
rate = (255-rate) >> 1;
float mappedRate = float(rate) +1.1;
uint32_t color = SEGMENT.colors[1]; // target color
int w2 = (color >> 24) & 0xff;
int r2 = (color >> 16) & 0xff;
int g2 = (color >> 8) & 0xff;
int b2 = color & 0xff;
for(uint16_t i=SEGMENT.start; i <= SEGMENT.stop; i++) {
color = getPixelColor(i);
int w1 = (color >> 24) & 0xff;
int r1 = (color >> 16) & 0xff;
int g1 = (color >> 8) & 0xff;
int b1 = color & 0xff;
int wdelta = (w2 - w1) / mappedRate;
int rdelta = (r2 - r1) / mappedRate;
int gdelta = (g2 - g1) / mappedRate;
int bdelta = (b2 - b1) / mappedRate;
// if fade isn't complete, make sure delta is at least 1 (fixes rounding issues)
wdelta += (w2 == w1) ? 0 : (w2 > w1) ? 1 : -1;
rdelta += (r2 == r1) ? 0 : (r2 > r1) ? 1 : -1;
gdelta += (g2 == g1) ? 0 : (g2 > g1) ? 1 : -1;
bdelta += (b2 == b1) ? 0 : (b2 > b1) ? 1 : -1;
setPixelColor(i, r1 + rdelta, g1 + gdelta, b1 + bdelta, w1 + wdelta);
}
}
/*
* blurs segment content, source: FastLED colorutils.cpp
*/
void WS2812FX::blur(uint8_t blur_amount)
{
uint8_t keep = 255 - blur_amount;
uint8_t seep = blur_amount >> 1;
CRGB carryover = CRGB::Black;
for(uint16_t i = SEGMENT.start; i <= SEGMENT.stop; i++)
{
CRGB cur = fastled_from_col(getPixelColor(i));
CRGB part = cur;
part.nscale8(seep);
cur.nscale8(keep);
cur += carryover;
if(i > SEGMENT.start) {
uint32_t c = getPixelColor(i-1);
uint8_t r = (c >> 16 & 0xFF);
uint8_t g = (c >> 8 & 0xFF);
uint8_t b = (c & 0xFF);
setPixelColor(i-1, qadd8(r, part.red), qadd8(g, part.green), qadd8(b, part.blue));
}
setPixelColor(i,cur.red, cur.green, cur.blue);
carryover = part;
}
}
/* /*
* Put a value 0 to 255 in to get a color value. * Put a value 0 to 255 in to get a color value.
* The colours are a transition r -> g -> b -> back to r * The colours are a transition r -> g -> b -> back to r

View File

@ -18,6 +18,9 @@
var nState = 0; var nState = 0;
var cv=0; var cv=0;
var lm=0; var lm=0;
var fxi=0;
var fpi=0;
var fxn=1;
aC=""; aC="";
bC=""; bC="";
dC=""; dC="";
@ -62,8 +65,8 @@
} else { } else {
uwv = false; uwv = false;
} }
Cf.TX.selectedIndex = this.responseXML.getElementsByTagName('fx')[0].childNodes[0].nodeValue; fxi = this.responseXML.getElementsByTagName('fx')[0].childNodes[0].nodeValue;
Cf.FP.selectedIndex = this.responseXML.getElementsByTagName('fp')[0].childNodes[0].nodeValue; fpi = this.responseXML.getElementsByTagName('fp')[0].childNodes[0].nodeValue;
d.Cf.SX.value = this.responseXML.getElementsByTagName('sx')[0].childNodes[0].nodeValue; d.Cf.SX.value = this.responseXML.getElementsByTagName('sx')[0].childNodes[0].nodeValue;
d.Cf.IX.value = this.responseXML.getElementsByTagName('ix')[0].childNodes[0].nodeValue; d.Cf.IX.value = this.responseXML.getElementsByTagName('ix')[0].childNodes[0].nodeValue;
nla = (this.responseXML.getElementsByTagName('nl')[0].innerHTML)!=0?true:false; nla = (this.responseXML.getElementsByTagName('nl')[0].innerHTML)!=0?true:false;
@ -80,7 +83,11 @@
d.documentElement.style.setProperty("--cFn",this.responseXML.getElementsByTagName('cf')[0].childNodes[0].nodeValue); d.documentElement.style.setProperty("--cFn",this.responseXML.getElementsByTagName('cf')[0].childNodes[0].nodeValue);
UCol(); UCol();
CV(parseInt(this.responseXML.getElementsByTagName('md')[0].childNodes[0].nodeValue)); CV(parseInt(this.responseXML.getElementsByTagName('md')[0].childNodes[0].nodeValue));
}firstload=false; }else{
Cf.TX.selectedIndex = fxi;
Cf.IX.selectedIndex = fpi;
}
firstload=false;
nState = 0; nState = 0;
nState = (this.responseXML.getElementsByTagName('nr')[0].innerHTML)!=0?1:0; nState = (this.responseXML.getElementsByTagName('nr')[0].innerHTML)!=0?1:0;
nState += (this.responseXML.getElementsByTagName('ns')[0].innerHTML)!=0?2:0; nState += (this.responseXML.getElementsByTagName('ns')[0].innerHTML)!=0?2:0;
@ -206,10 +213,10 @@
function SwFX(s) function SwFX(s)
{ {
var n=Cf.TX.selectedIndex+s; var n=Cf.TX.selectedIndex+s;
if (n==-1||n==79) return; if (n==-1||n==fxn) return;
Cf.TX.selectedIndex =n; Cf.TX.selectedIndex =n;
if (n < 0) Cf.TX.selectedIndex = 0; if (n < 0) Cf.TX.selectedIndex = 0;
if (n > 78) Cf.TX.selectedIndex = 65; if (n > fxn) Cf.TX.selectedIndex = Math.min(65,fxn-1);
GX(); GX();
} }
function TgHSB() function TgHSB()
@ -376,6 +383,9 @@
x += "<option value=\""+i+"\">"+l[i]+" ("+i+")</option>"; x += "<option value=\""+i+"\">"+l[i]+" ("+i+")</option>";
} }
el.innerHTML=x; el.innerHTML=x;
el.selectedIndex=fp?fpi:fxi;
if(!fp)fxn=l.length;
UV();
}) })
.catch(function () { .catch(function () {
el.innerHTML=e; el.innerHTML=e;

File diff suppressed because it is too large Load Diff

View File

@ -146,7 +146,6 @@ Palette blending:
<option value="3">None (not recommended)</option> <option value="3">None (not recommended)</option>
</select><br> </select><br>
Reverse LED order (rotate 180): <input type="checkbox" name="RV"><br> Reverse LED order (rotate 180): <input type="checkbox" name="RV"><br>
Init LEDs after WiFi: <input type="checkbox" name="EI"><br>
Skip first LED: <input type="checkbox" name="SL"><hr> Skip first LED: <input type="checkbox" name="SL"><hr>
<button type="button" onclick="B()">Back</button><button type="submit">Save</button> <button type="button" onclick="B()">Back</button><button type="submit">Save</button>
</form> </form>

View File

@ -37,7 +37,7 @@
#else #else
#ifdef ARDUINO_ARCH_ESP32 #ifdef ARDUINO_ARCH_ESP32
#include <WiFi.h> #include <WiFi.h>
#include "../webserver/WebServer.h" //> //if you get an error here please update to ESP32 arduino core 1.0.0 #include "../webserver/WebServer.h" //if you get an error here please update to ESP32 arduino core 1.0.0
#else #else
#include <ESP8266WebServer.h> #include <ESP8266WebServer.h>
#include <ESP8266WiFi.h> #include <ESP8266WiFi.h>
@ -351,6 +351,7 @@ public:
if (len > 0) { if (len > 0) {
packetBuffer[len] = 0; packetBuffer[len] = 0;
} }
espalexaUdp.flush();
String request = packetBuffer; String request = packetBuffer;
EA_DEBUGLN(request); EA_DEBUGLN(request);

View File

@ -78,8 +78,8 @@
//version code in format yymmddb (b = daily build) //version code in format yymmddb (b = daily build)
#define VERSION 1902101 #define VERSION 1902112
char versionString[] = "0.8.3-dev"; char versionString[] = "0.8.3";
//AP and OTA default passwords (for maximum change them!) //AP and OTA default passwords (for maximum change them!)
@ -141,7 +141,6 @@ bool enableSecTransition = true; //also enable transition for secon
uint16_t transitionDelay = 900; //default crossfade duration in ms uint16_t transitionDelay = 900; //default crossfade duration in ms
bool reverseMode = false; //flip entire LED strip (reverses all effect directions) bool reverseMode = false; //flip entire LED strip (reverses all effect directions)
bool initLedsLast = false; //turn on LEDs only after WiFi connected/AP open
bool skipFirstLed = false; //ignore first LED in strip (useful if you need the LED as signal repeater) bool skipFirstLed = false; //ignore first LED in strip (useful if you need the LED as signal repeater)
byte briMultiplier = 100; //% of brightness to set (to limit power, if you set it to 50 and set bri to 255, actual brightness will be 127) byte briMultiplier = 100; //% of brightness to set (to limit power, if you set it to 50 and set bri to 255, actual brightness will be 127)

View File

@ -158,7 +158,7 @@ void saveSettingsToEEPROM()
EEPROM.write(394, abs(utcOffsetSecs) & 0xFF); EEPROM.write(394, abs(utcOffsetSecs) & 0xFF);
EEPROM.write(395, (abs(utcOffsetSecs) >> 8) & 0xFF); EEPROM.write(395, (abs(utcOffsetSecs) >> 8) & 0xFF);
EEPROM.write(396, (utcOffsetSecs<0)); //is negative EEPROM.write(396, (utcOffsetSecs<0)); //is negative
EEPROM.write(397, initLedsLast); //397 was initLedsLast
EEPROM.write(398, (ledCount >> 8) & 0xFF); EEPROM.write(398, (ledCount >> 8) & 0xFF);
EEPROM.write(399, !enableSecTransition); EEPROM.write(399, !enableSecTransition);
@ -461,7 +461,7 @@ void loadSettingsFromEEPROM(bool first)
strip.colorOrder = EEPROM.read(383); strip.colorOrder = EEPROM.read(383);
irEnabled = EEPROM.read(385); irEnabled = EEPROM.read(385);
strip.ablMilliampsMax = EEPROM.read(387) + ((EEPROM.read(388) << 8) & 0xFF00); strip.ablMilliampsMax = EEPROM.read(387) + ((EEPROM.read(388) << 8) & 0xFF00);
} else if (lastEEPROMversion > 1) //ABL is off by default when updating from version older than 0.8.3 } else if (lastEEPROMversion > 1) //ABL is off by default when updating from version older than 0.8.2
{ {
strip.ablMilliampsMax = 65000; strip.ablMilliampsMax = 65000;
} else { } else {
@ -495,7 +495,6 @@ void loadSettingsFromEEPROM(bool first)
wifiLock = EEPROM.read(393); wifiLock = EEPROM.read(393);
utcOffsetSecs = EEPROM.read(394) + ((EEPROM.read(395) << 8) & 0xFF00); utcOffsetSecs = EEPROM.read(394) + ((EEPROM.read(395) << 8) & 0xFF00);
if (EEPROM.read(396)) utcOffsetSecs = -utcOffsetSecs; //negative if (EEPROM.read(396)) utcOffsetSecs = -utcOffsetSecs; //negative
initLedsLast = EEPROM.read(397);
enableSecTransition = !EEPROM.read(399); enableSecTransition = !EEPROM.read(399);
//favorite setting (preset) memory (25 slots/ each 20byte) //favorite setting (preset) memory (25 slots/ each 20byte)

View File

@ -239,7 +239,6 @@ void getSettingsJS(byte subPage)
sappend('c',"TW",nightlightFade); sappend('c',"TW",nightlightFade);
sappend('i',"PB",strip.paletteBlend); sappend('i',"PB",strip.paletteBlend);
sappend('c',"RV",reverseMode); sappend('c',"RV",reverseMode);
sappend('c',"EI",initLedsLast);
sappend('c',"SL",skipFirstLed); sappend('c',"SL",skipFirstLed);
} }

View File

@ -113,7 +113,6 @@ void handleSettingsSet(byte subPage)
t = server.arg("PB").toInt(); t = server.arg("PB").toInt();
if (t >= 0 && t < 4) strip.paletteBlend = t; if (t >= 0 && t < 4) strip.paletteBlend = t;
initLedsLast = server.hasArg("EI");
reverseMode = server.hasArg("RV"); reverseMode = server.hasArg("RV");
strip.setReverseMode(reverseMode); strip.setReverseMode(reverseMode);
skipFirstLed = server.hasArg("SL"); skipFirstLed = server.hasArg("SL");

View File

@ -14,7 +14,7 @@ void wledInit()
Serial.begin(115200); Serial.begin(115200);
Serial.setTimeout(50); Serial.setTimeout(50);
if (!EEPROM.read(397)) strip.init(EEPROM.read(372),ledCount,EEPROM.read(2204)); //quick init strip.init(EEPROM.read(372),ledCount,EEPROM.read(2204)); //init LEDs quickly
#ifdef USEFS #ifdef USEFS
SPIFFS.begin(); SPIFFS.begin();
@ -22,7 +22,7 @@ void wledInit()
DEBUG_PRINTLN("Load EEPROM"); DEBUG_PRINTLN("Load EEPROM");
loadSettingsFromEEPROM(true); loadSettingsFromEEPROM(true);
if (!initLedsLast) initStrip(); beginStrip();
DEBUG_PRINT("CSSID: "); DEBUG_PRINT("CSSID: ");
DEBUG_PRINT(clientSSID); DEBUG_PRINT(clientSSID);
userBeginPreConnection(); userBeginPreConnection();
@ -77,12 +77,12 @@ void wledInit()
mqttInit = initMQTT(); mqttInit = initMQTT();
} }
if (!initLedsLast) strip.service(); strip.service();
//HTTP server page init //HTTP server page init
initServer(); initServer();
if (!initLedsLast) strip.service(); strip.service();
//init Alexa hue emulation //init Alexa hue emulation
if (alexaEnabled && !onlyAP) alexaInit(); if (alexaEnabled && !onlyAP) alexaInit();
@ -105,7 +105,7 @@ void wledInit()
} }
#endif #endif
if (!initLedsLast) strip.service(); strip.service();
// Set up mDNS responder: // Set up mDNS responder:
if (strlen(cmDNS) > 0 && !onlyAP) if (strlen(cmDNS) > 0 && !onlyAP)
{ {
@ -115,7 +115,7 @@ void wledInit()
MDNS.addService("http", "tcp", 80); MDNS.addService("http", "tcp", 80);
MDNS.addService("wled", "tcp", 80); MDNS.addService("wled", "tcp", 80);
} }
if (!initLedsLast) strip.service(); strip.service();
initBlynk(blynkApiKey); initBlynk(blynkApiKey);
initE131(); initE131();
@ -125,7 +125,6 @@ void wledInit()
e131Enabled = false; e131Enabled = false;
} }
if (initLedsLast) initStrip();
userBegin(); userBegin();
if (macroBoot>0) applyMacro(macroBoot); if (macroBoot>0) applyMacro(macroBoot);
@ -133,10 +132,9 @@ void wledInit()
} }
void initStrip() void beginStrip()
{ {
// Initialize NeoPixel Strip and button // Initialize NeoPixel Strip and button
if (initLedsLast) strip.init(useRGBW,ledCount,skipFirstLed);
strip.setReverseMode(reverseMode); strip.setReverseMode(reverseMode);
strip.setColor(0); strip.setColor(0);
strip.setBrightness(255); strip.setBrightness(255);
@ -196,13 +194,10 @@ void initCon()
while(!con) while(!con)
{ {
yield(); yield();
if (!initLedsLast) handleTransitions();
{ handleButton();
handleTransitions(); handleOverlays();
handleButton(); if (briT) strip.service();
handleOverlays();
if (briT) strip.service();
}
if (millis()-lastTry > 499) { if (millis()-lastTry > 499) {
con = (WiFi.status() == WL_CONNECTED); con = (WiFi.status() == WL_CONNECTED);
lastTry = millis(); lastTry = millis();
@ -277,7 +272,7 @@ void getBuildInfo()
oappend("\r\nstrip-pin: gpio"); oappend("\r\nstrip-pin: gpio");
oappendi(LEDPIN); oappendi(LEDPIN);
oappend("\r\nbrand: wled"); oappend("\r\nbrand: wled");
oappend("\r\nbuild-type: dev\r\n"); oappend("\r\nbuild-type: src\r\n");
} }