mirror of
https://github.com/wled/WLED.git
synced 2025-04-23 14:27:18 +00:00
Remove conditional fade/blend
- transitions always enabled (use delay 0 to disable) - optimisation in on/off fade - fix for palette/color blend when blending style is not fade - various tweaks and optimisations
This commit is contained in:
parent
c6805271e9
commit
a3a8fa1cef
@ -1,5 +1,8 @@
|
||||
## WLED changelog
|
||||
|
||||
#### Build 2404050
|
||||
- Blending styles (with help from @tkadauke)
|
||||
|
||||
#### Build 2403280
|
||||
- Individual color channel control for JSON API (fixes #3860)
|
||||
- "col":[int|string|object|array, int|string|object|array, int|string|object|array]
|
||||
|
@ -96,7 +96,7 @@ void setup() {
|
||||
jsonTransitionOnce = true;
|
||||
strip.setTransition(0); //no transition
|
||||
effectCurrent = FX_MODE_COLOR_WIPE;
|
||||
resetTimebase(); //make sure wipe starts from beginning
|
||||
strip.resetTimebase(); //make sure wipe starts from beginning
|
||||
|
||||
//set wipe direction
|
||||
Segment& seg = strip.getSegment(0);
|
||||
|
@ -1,111 +0,0 @@
|
||||
/*
|
||||
* This file allows you to add own functionality to WLED more easily
|
||||
* See: https://github.com/Aircoookie/WLED/wiki/Add-own-functionality
|
||||
* EEPROM bytes 2750+ are reserved for your custom use case. (if you extend #define EEPSIZE in wled_eeprom.h)
|
||||
* bytes 2400+ are currently ununsed, but might be used for future wled features
|
||||
*/
|
||||
|
||||
//Use userVar0 and userVar1 (API calls &U0=,&U1=, uint16_t)
|
||||
|
||||
byte wipeState = 0; //0: inactive 1: wiping 2: solid
|
||||
unsigned long timeStaticStart = 0;
|
||||
uint16_t previousUserVar0 = 0;
|
||||
|
||||
//comment this out if you want the turn off effect to be just fading out instead of reverse wipe
|
||||
#define STAIRCASE_WIPE_OFF
|
||||
|
||||
//gets called once at boot. Do all initialization that doesn't depend on network here
|
||||
void userSetup()
|
||||
{
|
||||
//setup PIR sensor here, if needed
|
||||
}
|
||||
|
||||
//gets called every time WiFi is (re-)connected. Initialize own network interfaces here
|
||||
void userConnected()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//loop. You can use "if (WLED_CONNECTED)" to check for successful connection
|
||||
void userLoop()
|
||||
{
|
||||
//userVar0 (U0 in HTTP API):
|
||||
//has to be set to 1 if movement is detected on the PIR that is the same side of the staircase as the ESP8266
|
||||
//has to be set to 2 if movement is detected on the PIR that is the opposite side
|
||||
//can be set to 0 if no movement is detected. Otherwise LEDs will turn off after a configurable timeout (userVar1 seconds)
|
||||
|
||||
if (userVar0 > 0)
|
||||
{
|
||||
if ((previousUserVar0 == 1 && userVar0 == 2) || (previousUserVar0 == 2 && userVar0 == 1)) wipeState = 3; //turn off if other PIR triggered
|
||||
previousUserVar0 = userVar0;
|
||||
|
||||
if (wipeState == 0) {
|
||||
startWipe();
|
||||
wipeState = 1;
|
||||
} else if (wipeState == 1) { //wiping
|
||||
uint32_t cycleTime = 360 + (255 - effectSpeed)*75; //this is how long one wipe takes (minus 25 ms to make sure we switch in time)
|
||||
if (millis() + strip.timebase > (cycleTime - 25)) { //wipe complete
|
||||
effectCurrent = FX_MODE_STATIC;
|
||||
timeStaticStart = millis();
|
||||
colorUpdated(CALL_MODE_NOTIFICATION);
|
||||
wipeState = 2;
|
||||
}
|
||||
} else if (wipeState == 2) { //static
|
||||
if (userVar1 > 0) //if U1 is not set, the light will stay on until second PIR or external command is triggered
|
||||
{
|
||||
if (millis() - timeStaticStart > userVar1*1000) wipeState = 3;
|
||||
}
|
||||
} else if (wipeState == 3) { //switch to wipe off
|
||||
#ifdef STAIRCASE_WIPE_OFF
|
||||
effectCurrent = FX_MODE_COLOR_WIPE;
|
||||
strip.timebase = 360 + (255 - effectSpeed)*75 - millis(); //make sure wipe starts fully lit
|
||||
colorUpdated(CALL_MODE_NOTIFICATION);
|
||||
wipeState = 4;
|
||||
#else
|
||||
turnOff();
|
||||
#endif
|
||||
} else { //wiping off
|
||||
if (millis() + strip.timebase > (725 + (255 - effectSpeed)*150)) turnOff(); //wipe complete
|
||||
}
|
||||
} else {
|
||||
wipeState = 0; //reset for next time
|
||||
if (previousUserVar0) {
|
||||
#ifdef STAIRCASE_WIPE_OFF
|
||||
userVar0 = previousUserVar0;
|
||||
wipeState = 3;
|
||||
#else
|
||||
turnOff();
|
||||
#endif
|
||||
}
|
||||
previousUserVar0 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void startWipe()
|
||||
{
|
||||
bri = briLast; //turn on
|
||||
transitionDelayTemp = 0; //no transition
|
||||
effectCurrent = FX_MODE_COLOR_WIPE;
|
||||
resetTimebase(); //make sure wipe starts from beginning
|
||||
|
||||
//set wipe direction
|
||||
Segment& seg = strip.getSegment(0);
|
||||
bool doReverse = (userVar0 == 2);
|
||||
seg.setOption(1, doReverse);
|
||||
|
||||
colorUpdated(CALL_MODE_NOTIFICATION);
|
||||
}
|
||||
|
||||
void turnOff()
|
||||
{
|
||||
#ifdef STAIRCASE_WIPE_OFF
|
||||
transitionDelayTemp = 0; //turn off immediately after wipe completed
|
||||
#else
|
||||
transitionDelayTemp = 4000; //fade out slowly
|
||||
#endif
|
||||
bri = 0;
|
||||
stateUpdated(CALL_MODE_NOTIFICATION);
|
||||
wipeState = 0;
|
||||
userVar0 = 0;
|
||||
previousUserVar0 = 0;
|
||||
}
|
@ -1211,8 +1211,9 @@ static const char _data_FX_MODE_COMET[] PROGMEM = "Lighthouse@!,Fade rate;!,!;!"
|
||||
*/
|
||||
uint16_t mode_fireworks() {
|
||||
if (SEGLEN == 1) return mode_static();
|
||||
const uint16_t width = SEGMENT.is2D() ? SEGMENT.virtualWidth() : SEGMENT.virtualLength();
|
||||
const uint16_t height = SEGMENT.virtualHeight();
|
||||
const unsigned width = SEGMENT.is2D() ? SEGMENT.virtualWidth() : SEGMENT.virtualLength();
|
||||
const unsigned height = SEGMENT.virtualHeight();
|
||||
const unsigned dimension = width * height;
|
||||
|
||||
if (SEGENV.call == 0) {
|
||||
SEGENV.aux0 = UINT16_MAX;
|
||||
@ -1220,19 +1221,19 @@ uint16_t mode_fireworks() {
|
||||
}
|
||||
SEGMENT.fade_out(128);
|
||||
|
||||
bool valid1 = (SEGENV.aux0 < width*height);
|
||||
bool valid2 = (SEGENV.aux1 < width*height);
|
||||
uint8_t x = SEGENV.aux0%width, y = SEGENV.aux0/width; // 2D coordinates stored in upper and lower byte
|
||||
bool valid1 = (SEGENV.aux0 < dimension);
|
||||
bool valid2 = (SEGENV.aux1 < dimension);
|
||||
unsigned x = SEGENV.aux0%width, y = SEGENV.aux0/width; // 2D coordinates stored in upper and lower byte
|
||||
uint32_t sv1 = 0, sv2 = 0;
|
||||
if (valid1) sv1 = SEGMENT.is2D() ? SEGMENT.getPixelColorXY(x, y) : SEGMENT.getPixelColor(SEGENV.aux0); // get spark color
|
||||
if (valid2) sv2 = SEGMENT.is2D() ? SEGMENT.getPixelColorXY(x, y) : SEGMENT.getPixelColor(SEGENV.aux1);
|
||||
if (!SEGENV.step) SEGMENT.blur(16);
|
||||
if (!SEGENV.step) SEGMENT.blur(dimension > 100 ? 16 : 8);
|
||||
if (valid1) { if (SEGMENT.is2D()) SEGMENT.setPixelColorXY(x, y, sv1); else SEGMENT.setPixelColor(SEGENV.aux0, sv1); } // restore spark color after blur
|
||||
if (valid2) { if (SEGMENT.is2D()) SEGMENT.setPixelColorXY(x, y, sv2); else SEGMENT.setPixelColor(SEGENV.aux1, sv2); } // restore old spark color after blur
|
||||
|
||||
for (int i=0; i<max(1, width/20); i++) {
|
||||
for (unsigned i=0; i<max(1U, width/20); i++) {
|
||||
if (random8(129 - (SEGMENT.intensity >> 1)) == 0) {
|
||||
uint16_t index = random16(width*height);
|
||||
unsigned index = random16(dimension);
|
||||
x = index % width;
|
||||
y = index / width;
|
||||
uint32_t col = SEGMENT.color_from_palette(random8(), false, false, 0);
|
||||
@ -2066,41 +2067,41 @@ uint16_t mode_fire_2012() {
|
||||
struct virtualStrip {
|
||||
static void runStrip(uint16_t stripNr, byte* heat, uint32_t it) {
|
||||
|
||||
const uint8_t ignition = max(3,SEGLEN/10); // ignition area: 10% of segment length or minimum 3 pixels
|
||||
const unsigned ignition = max(3,SEGLEN/10); // ignition area: 10% of segment length or minimum 3 pixels
|
||||
|
||||
// Step 1. Cool down every cell a little
|
||||
for (int i = 0; i < SEGLEN; i++) {
|
||||
uint8_t cool = (it != SEGENV.step) ? random8((((20 + SEGMENT.speed/3) * 16) / SEGLEN)+2) : random8(4);
|
||||
uint8_t minTemp = (i<ignition) ? (ignition-i)/4 + 16 : 0; // should not become black in ignition area
|
||||
uint8_t temp = qsub8(heat[i], cool);
|
||||
for (unsigned i = 0; i < SEGLEN; i++) {
|
||||
unsigned cool = (it != SEGENV.step) ? random8((((20 + SEGMENT.speed/3) * 16) / SEGLEN)+2) : random8(4);
|
||||
unsigned minTemp = (i<ignition) ? (ignition-i)/4 + 16 : 0; // should not become black in ignition area
|
||||
unsigned temp = qsub8(heat[i], cool);
|
||||
heat[i] = temp<minTemp ? minTemp : temp;
|
||||
}
|
||||
|
||||
if (it != SEGENV.step) {
|
||||
// Step 2. Heat from each cell drifts 'up' and diffuses a little
|
||||
for (int k = SEGLEN -1; k > 1; k--) {
|
||||
for (unsigned k = SEGLEN -1; k > 1; k--) {
|
||||
heat[k] = (heat[k - 1] + (heat[k - 2]<<1) ) / 3; // heat[k-2] multiplied by 2
|
||||
}
|
||||
|
||||
// Step 3. Randomly ignite new 'sparks' of heat near the bottom
|
||||
if (random8() <= SEGMENT.intensity) {
|
||||
uint8_t y = random8(ignition);
|
||||
uint8_t boost = (17+SEGMENT.custom3) * (ignition - y/2) / ignition; // integer math!
|
||||
unsigned y = random8(ignition);
|
||||
unsigned boost = (17+SEGMENT.custom3) * (ignition - y/2) / ignition; // integer math!
|
||||
heat[y] = qadd8(heat[y], random8(96+2*boost,207+boost));
|
||||
}
|
||||
}
|
||||
|
||||
// Step 4. Map from heat cells to LED colors
|
||||
for (int j = 0; j < SEGLEN; j++) {
|
||||
SEGMENT.setPixelColor(indexToVStrip(j, stripNr), ColorFromPalette(SEGPALETTE, MIN(heat[j],240), 255, NOBLEND));
|
||||
SEGMENT.setPixelColor(indexToVStrip(j, stripNr), ColorFromPalette(SEGPALETTE, MIN(heat[j],240), 255, LINEARBLEND_NOWRAP));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
for (int stripNr=0; stripNr<strips; stripNr++)
|
||||
for (unsigned stripNr=0; stripNr<strips; stripNr++)
|
||||
virtualStrip::runStrip(stripNr, &heat[stripNr * SEGLEN], it);
|
||||
|
||||
if (SEGMENT.is2D()) SEGMENT.blur(32);
|
||||
if (SEGMENT.is2D()) SEGMENT.blur((SEGMENT.virtualWidth()*SEGMENT.virtualHeight()) > 100 ? 32 : 0);
|
||||
|
||||
if (it != SEGENV.step)
|
||||
SEGENV.step = it;
|
||||
@ -4856,9 +4857,9 @@ static const char _data_FX_MODE_FLOWSTRIPE[] PROGMEM = "Flow Stripe@Hue speed,Ef
|
||||
uint16_t mode_2DBlackHole(void) { // By: Stepko https://editor.soulmatelights.com/gallery/1012 , Modified by: Andrew Tuline
|
||||
if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up
|
||||
|
||||
const uint16_t cols = SEGMENT.virtualWidth();
|
||||
const uint16_t rows = SEGMENT.virtualHeight();
|
||||
uint16_t x, y;
|
||||
const unsigned cols = SEGMENT.virtualWidth();
|
||||
const unsigned rows = SEGMENT.virtualHeight();
|
||||
unsigned x, y;
|
||||
|
||||
SEGMENT.fadeToBlackBy(16 + (SEGMENT.speed>>3)); // create fading trails
|
||||
unsigned long t = strip.now/128; // timebase
|
||||
@ -4877,7 +4878,7 @@ uint16_t mode_2DBlackHole(void) { // By: Stepko https://editor.soulma
|
||||
// central white dot
|
||||
SEGMENT.setPixelColorXY(cols/2, rows/2, WHITE);
|
||||
// blur everything a bit
|
||||
SEGMENT.blur(16);
|
||||
SEGMENT.blur(sqrt16(cols*rows) > 100 ? 16 : 0);
|
||||
|
||||
return FRAMETIME;
|
||||
} // mode_2DBlackHole()
|
||||
@ -6436,8 +6437,8 @@ static const char _data_FX_MODE_2DSWIRL[] PROGMEM = "Swirl@!,Sensitivity,Blur;,B
|
||||
uint16_t mode_2DWaverly(void) {
|
||||
if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up
|
||||
|
||||
const uint16_t cols = SEGMENT.virtualWidth();
|
||||
const uint16_t rows = SEGMENT.virtualHeight();
|
||||
const unsigned cols = SEGMENT.virtualWidth();
|
||||
const unsigned rows = SEGMENT.virtualHeight();
|
||||
|
||||
um_data_t *um_data;
|
||||
if (!usermods.getUMData(&um_data, USERMOD_ID_AUDIOREACTIVE)) {
|
||||
@ -6449,21 +6450,21 @@ uint16_t mode_2DWaverly(void) {
|
||||
SEGMENT.fadeToBlackBy(SEGMENT.speed);
|
||||
|
||||
long t = strip.now / 2;
|
||||
for (int i = 0; i < cols; i++) {
|
||||
uint16_t thisVal = (1 + SEGMENT.intensity/64) * inoise8(i * 45 , t , t)/2;
|
||||
for (unsigned i = 0; i < cols; i++) {
|
||||
unsigned thisVal = (1 + SEGMENT.intensity/64) * inoise8(i * 45 , t , t)/2;
|
||||
// use audio if available
|
||||
if (um_data) {
|
||||
thisVal /= 32; // reduce intensity of inoise8()
|
||||
thisVal *= volumeSmth;
|
||||
}
|
||||
uint16_t thisMax = map(thisVal, 0, 512, 0, rows);
|
||||
unsigned thisMax = map(thisVal, 0, 512, 0, rows);
|
||||
|
||||
for (int j = 0; j < thisMax; j++) {
|
||||
for (unsigned j = 0; j < thisMax; j++) {
|
||||
SEGMENT.addPixelColorXY(i, j, ColorFromPalette(SEGPALETTE, map(j, 0, thisMax, 250, 0), 255, LINEARBLEND));
|
||||
SEGMENT.addPixelColorXY((cols - 1) - i, (rows - 1) - j, ColorFromPalette(SEGPALETTE, map(j, 0, thisMax, 250, 0), 255, LINEARBLEND));
|
||||
}
|
||||
}
|
||||
SEGMENT.blur(16);
|
||||
SEGMENT.blur(sqrt16(cols*rows) > 100 ? 16 : 0);
|
||||
|
||||
return FRAMETIME;
|
||||
} // mode_2DWaverly()
|
||||
|
@ -601,7 +601,7 @@ typedef struct Segment {
|
||||
inline void setPixelColor(float i, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0, bool aa = true) { setPixelColor(i, RGBW32(r,g,b,w), aa); }
|
||||
inline void setPixelColor(float i, CRGB c, bool aa = true) { setPixelColor(i, RGBW32(c.r,c.g,c.b,0), aa); }
|
||||
#ifndef WLED_DISABLE_MODE_BLEND
|
||||
inline void setClippingRect(int startX, int stopX, int startY = 0, int stopY = 1) { _clipStart = startX; _clipStop = stopX; _clipStartY = startY; _clipStopY = stopY; };
|
||||
static inline void setClippingRect(int startX, int stopX, int startY = 0, int stopY = 1) { _clipStart = startX; _clipStop = stopX; _clipStartY = startY; _clipStopY = stopY; };
|
||||
#endif
|
||||
bool isPixelClipped(int i);
|
||||
uint32_t getPixelColor(int i);
|
||||
@ -708,9 +708,7 @@ class WS2812FX { // 96 bytes
|
||||
public:
|
||||
|
||||
WS2812FX() :
|
||||
paletteFade(0),
|
||||
paletteBlend(0),
|
||||
cctBlending(0),
|
||||
now(millis()),
|
||||
timebase(0),
|
||||
isMatrix(false),
|
||||
@ -792,6 +790,7 @@ class WS2812FX { // 96 bytes
|
||||
addEffect(uint8_t id, mode_ptr mode_fn, const char *mode_name), // add effect to the list; defined in FX.cpp
|
||||
setupEffectData(void); // add default effects to the list; defined in FX.cpp
|
||||
|
||||
inline void resetTimebase() { timebase = 0U - millis(); }
|
||||
inline void restartRuntime() { for (Segment &seg : _segments) seg.markForReset(); }
|
||||
inline void setTransitionMode(bool t) { for (Segment &seg : _segments) seg.startTransition(t ? _transitionDur : 0); }
|
||||
inline void setColor(uint8_t slot, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0) { setColor(slot, RGBW32(r,g,b,w)); }
|
||||
@ -806,7 +805,6 @@ class WS2812FX { // 96 bytes
|
||||
inline void resume(void) { _suspend = false; } // will resume strip.service() execution
|
||||
|
||||
bool
|
||||
paletteFade,
|
||||
checkSegmentAlignment(void),
|
||||
hasRGBWBus(void),
|
||||
hasCCTBus(void),
|
||||
@ -822,7 +820,6 @@ class WS2812FX { // 96 bytes
|
||||
|
||||
uint8_t
|
||||
paletteBlend,
|
||||
cctBlending,
|
||||
getActiveSegmentsNum(void),
|
||||
getFirstSelectedSegId(void),
|
||||
getLastActiveSegmentId(void),
|
||||
|
@ -176,10 +176,10 @@ bool IRAM_ATTR Segment::isPixelXYClipped(int x, int y) {
|
||||
if (_clipStart != _clipStop && blendingStyle > BLEND_STYLE_FADE) {
|
||||
const bool invertX = _clipStart > _clipStop;
|
||||
const bool invertY = _clipStartY > _clipStopY;
|
||||
const unsigned startX = invertX ? _clipStop : _clipStart;
|
||||
const unsigned stopX = invertX ? _clipStart : _clipStop;
|
||||
const unsigned startY = invertY ? _clipStopY : _clipStartY;
|
||||
const unsigned stopY = invertY ? _clipStartY : _clipStopY;
|
||||
const int startX = invertX ? _clipStop : _clipStart;
|
||||
const int stopX = invertX ? _clipStart : _clipStop;
|
||||
const int startY = invertY ? _clipStopY : _clipStartY;
|
||||
const int stopY = invertY ? _clipStartY : _clipStopY;
|
||||
if (blendingStyle == BLEND_STYLE_FAIRY_DUST) {
|
||||
const unsigned width = stopX - startX; // assumes full segment width (faster than virtualWidth())
|
||||
const unsigned len = width * (stopY - startY); // assumes full segment height (faster than virtualHeight())
|
||||
@ -295,7 +295,7 @@ void Segment::setPixelColorXY(float x, float y, uint32_t col, bool aa)
|
||||
// returns RGBW values of pixel
|
||||
uint32_t IRAM_ATTR Segment::getPixelColorXY(uint16_t x, uint16_t y) {
|
||||
if (!isActive()) return 0; // not active
|
||||
if (x >= virtualWidth() || y >= virtualHeight() || x<0 || y<0) return 0; // if pixel would fall out of virtual segment just exit
|
||||
if (x >= virtualWidth() || y >= virtualHeight() || x<0 || y<0 || isPixelXYClipped(x,y)) return 0; // if pixel would fall out of virtual segment just exit
|
||||
if (reverse ) x = virtualWidth() - x - 1;
|
||||
if (reverse_y) y = virtualHeight() - y - 1;
|
||||
if (transpose) { uint16_t t = x; x = y; y = t; } // swap X & Y if segment transposed
|
||||
|
@ -293,21 +293,17 @@ void Segment::startTransition(uint16_t dur) {
|
||||
_t->_briT = on ? opacity : 0;
|
||||
_t->_cctT = cct;
|
||||
#ifndef WLED_DISABLE_MODE_BLEND
|
||||
if (modeBlending) {
|
||||
swapSegenv(_t->_segT);
|
||||
_t->_modeT = mode;
|
||||
_t->_segT._dataLenT = 0;
|
||||
_t->_segT._dataT = nullptr;
|
||||
if (_dataLen > 0 && data) {
|
||||
_t->_segT._dataT = (byte *)malloc(_dataLen);
|
||||
if (_t->_segT._dataT) {
|
||||
//DEBUG_PRINTF_P(PSTR("-- Allocated duplicate data (%d) for %p: %p\n"), _dataLen, this, _t->_segT._dataT);
|
||||
memcpy(_t->_segT._dataT, data, _dataLen);
|
||||
_t->_segT._dataLenT = _dataLen;
|
||||
}
|
||||
swapSegenv(_t->_segT);
|
||||
_t->_modeT = mode;
|
||||
_t->_segT._dataLenT = 0;
|
||||
_t->_segT._dataT = nullptr;
|
||||
if (_dataLen > 0 && data) {
|
||||
_t->_segT._dataT = (byte *)malloc(_dataLen);
|
||||
if (_t->_segT._dataT) {
|
||||
//DEBUG_PRINTF_P(PSTR("-- Allocated duplicate data (%d) for %p: %p\n"), _dataLen, this, _t->_segT._dataT);
|
||||
memcpy(_t->_segT._dataT, data, _dataLen);
|
||||
_t->_segT._dataLenT = _dataLen;
|
||||
}
|
||||
} else {
|
||||
for (size_t i=0; i<NUM_COLORS; i++) _t->_segT._colorT[i] = colors[i];
|
||||
}
|
||||
#else
|
||||
for (size_t i=0; i<NUM_COLORS; i++) _t->_colorT[i] = colors[i];
|
||||
@ -435,7 +431,7 @@ uint8_t IRAM_ATTR Segment::currentBri(bool useCct) {
|
||||
uint8_t IRAM_ATTR Segment::currentMode() {
|
||||
#ifndef WLED_DISABLE_MODE_BLEND
|
||||
uint16_t prog = progress();
|
||||
if (modeBlending && prog < 0xFFFFU) return _t->_modeT;
|
||||
if (prog < 0xFFFFU) return _t->_modeT;
|
||||
#endif
|
||||
return mode;
|
||||
}
|
||||
@ -445,7 +441,7 @@ uint32_t IRAM_ATTR Segment::currentColor(uint8_t slot) {
|
||||
uint32_t prog = progress();
|
||||
if (prog == 0xFFFFU) return colors[slot];
|
||||
#ifndef WLED_DISABLE_MODE_BLEND
|
||||
if (blendingStyle > BLEND_STYLE_FADE) return _modeBlend ? _t->_segT._colorT[slot] : colors[slot]; // not fade/blend transition, each effect uses its color
|
||||
if (blendingStyle > BLEND_STYLE_FADE && mode != _t->_modeT) return _modeBlend ? _t->_segT._colorT[slot] : colors[slot]; // not fade/blend transition, each effect uses its color
|
||||
return color_blend(_t->_segT._colorT[slot], colors[slot], prog, true);
|
||||
#else
|
||||
return color_blend(_t->_colorT[slot], colors[slot], prog, true);
|
||||
@ -456,10 +452,10 @@ CRGBPalette16 IRAM_ATTR &Segment::currentPalette(CRGBPalette16 &targetPalette, u
|
||||
loadPalette(targetPalette, pal);
|
||||
uint16_t prog = progress();
|
||||
#ifndef WLED_DISABLE_MODE_BLEND
|
||||
if (prog < 0xFFFFU && blendingStyle > BLEND_STYLE_FADE && _modeBlend) targetPalette = _t->_palT; // not fade/blend transition, each effect uses its palette
|
||||
if (prog < 0xFFFFU && blendingStyle > BLEND_STYLE_FADE && _modeBlend && mode != _t->_modeT) targetPalette = _t->_palT; // not fade/blend transition, each effect uses its palette
|
||||
else
|
||||
#endif
|
||||
if (strip.paletteFade && prog < 0xFFFFU) {
|
||||
if (prog < 0xFFFFU) {
|
||||
// blend palettes
|
||||
// there are about 255 blend passes of 48 "blends" to completely blend two palettes (in _dur time)
|
||||
// minimum blend time is 100ms maximum is 65535ms
|
||||
@ -473,19 +469,16 @@ CRGBPalette16 IRAM_ATTR &Segment::currentPalette(CRGBPalette16 &targetPalette, u
|
||||
// relies on WS2812FX::service() to call it for each frame
|
||||
void Segment::handleRandomPalette() {
|
||||
// is it time to generate a new palette?
|
||||
if ((uint16_t)(millis() / 1000U) - _lastPaletteChange > randomPaletteChangeTime){
|
||||
_newRandomPalette = useHarmonicRandomPalette ? generateHarmonicRandomPalette(_randomPalette) : generateRandomPalette();
|
||||
_lastPaletteChange = (uint16_t)(millis() / 1000U);
|
||||
_lastPaletteBlend = (uint16_t)millis() - 512; // starts blending immediately
|
||||
if ((uint16_t)(millis()/1000U) - _lastPaletteChange > randomPaletteChangeTime) {
|
||||
_newRandomPalette = useHarmonicRandomPalette ? generateHarmonicRandomPalette(_randomPalette) : generateRandomPalette();
|
||||
_lastPaletteChange = (uint16_t)(millis()/1000U);
|
||||
_lastPaletteBlend = (uint16_t)(millis())-512; // starts blending immediately
|
||||
}
|
||||
|
||||
// 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 ((uint16_t)((uint16_t)millis() - _lastPaletteBlend) < strip.getTransition() >> 7) return; // not yet time to fade, delay the update
|
||||
_lastPaletteBlend = (uint16_t)millis();
|
||||
}
|
||||
// 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 ((uint16_t)millis() - _lastPaletteBlend < strip.getTransition() >> 7) return; // not yet time to fade, delay the update
|
||||
_lastPaletteBlend = (uint16_t)millis();
|
||||
nblendPaletteTowardPalette(_randomPalette, _newRandomPalette, 48);
|
||||
}
|
||||
|
||||
@ -549,7 +542,7 @@ bool Segment::setColor(uint8_t slot, uint32_t c) { //returns true if changed
|
||||
if (slot == 0 && c == BLACK) return false; // on/off segment cannot have primary color black
|
||||
if (slot == 1 && c != BLACK) return false; // on/off segment cannot have secondary color non black
|
||||
}
|
||||
if (fadeTransition) startTransition(strip.getTransition()); // start transition prior to change
|
||||
startTransition(strip.getTransition()); // start transition prior to change
|
||||
colors[slot] = c;
|
||||
stateChanged = true; // send UDP/WS broadcast
|
||||
return true;
|
||||
@ -562,21 +555,21 @@ void Segment::setCCT(uint16_t k) {
|
||||
k = (k - 1900) >> 5;
|
||||
}
|
||||
if (cct == k) return;
|
||||
if (fadeTransition) startTransition(strip.getTransition()); // start transition prior to change
|
||||
startTransition(strip.getTransition()); // start transition prior to change
|
||||
cct = k;
|
||||
stateChanged = true; // send UDP/WS broadcast
|
||||
}
|
||||
|
||||
void Segment::setOpacity(uint8_t o) {
|
||||
if (opacity == o) return;
|
||||
if (fadeTransition) startTransition(strip.getTransition()); // start transition prior to change
|
||||
startTransition(strip.getTransition()); // start transition prior to change
|
||||
opacity = o;
|
||||
stateChanged = true; // send UDP/WS broadcast
|
||||
}
|
||||
|
||||
void Segment::setOption(uint8_t n, bool val) {
|
||||
bool prevOn = on;
|
||||
if (fadeTransition && n == SEG_OPTION_ON && val != prevOn) startTransition(strip.getTransition()); // start transition prior to change
|
||||
if (n == SEG_OPTION_ON && val != prevOn) startTransition(strip.getTransition()); // start transition prior to change
|
||||
if (val) options |= 0x01 << n;
|
||||
else options &= ~(0x01 << n);
|
||||
if (!(n == SEG_OPTION_SELECTED || n == SEG_OPTION_RESET)) stateChanged = true; // send UDP/WS broadcast
|
||||
@ -589,7 +582,7 @@ void Segment::setMode(uint8_t fx, bool loadDefaults) {
|
||||
// if we have a valid mode & is not reserved
|
||||
if (fx != mode) {
|
||||
#ifndef WLED_DISABLE_MODE_BLEND
|
||||
if (modeBlending) startTransition(strip.getTransition()); // set effect transitions
|
||||
startTransition(strip.getTransition()); // set effect transitions
|
||||
#endif
|
||||
mode = fx;
|
||||
// load default values from effect string
|
||||
@ -620,7 +613,7 @@ void Segment::setPalette(uint8_t pal) {
|
||||
if (pal < 245 && pal > GRADIENT_PALETTE_COUNT+13) pal = 0; // built in palettes
|
||||
if (pal > 245 && (strip.customPalettes.size() == 0 || 255U-pal > strip.customPalettes.size()-1)) pal = 0; // custom palettes
|
||||
if (pal != palette) {
|
||||
if (strip.paletteFade) startTransition(strip.getTransition());
|
||||
startTransition(strip.getTransition());
|
||||
palette = pal;
|
||||
stateChanged = true; // send UDP/WS broadcast
|
||||
}
|
||||
@ -688,8 +681,8 @@ bool IRAM_ATTR Segment::isPixelClipped(int i) {
|
||||
#ifndef WLED_DISABLE_MODE_BLEND
|
||||
if (_clipStart != _clipStop && blendingStyle > BLEND_STYLE_FADE) {
|
||||
bool invert = _clipStart > _clipStop;
|
||||
unsigned start = invert ? _clipStop : _clipStart;
|
||||
unsigned stop = invert ? _clipStart : _clipStop;
|
||||
int start = invert ? _clipStop : _clipStart;
|
||||
int stop = invert ? _clipStart : _clipStop;
|
||||
if (blendingStyle == BLEND_STYLE_FAIRY_DUST) {
|
||||
unsigned len = stop - start;
|
||||
if (len < 2) return false;
|
||||
@ -888,6 +881,8 @@ uint32_t IRAM_ATTR Segment::getPixelColor(int i)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (isPixelClipped(i)) return 0; // handle clipping on 1D
|
||||
|
||||
if (reverse) i = virtualLength() - i - 1;
|
||||
i *= groupLength();
|
||||
i += start;
|
||||
@ -1234,8 +1229,8 @@ void WS2812FX::service() {
|
||||
// would need to be allocated for each effect and then blended together for each pixel.
|
||||
[[maybe_unused]] uint8_t tmpMode = seg.currentMode(); // this will return old mode while in transition
|
||||
#ifndef WLED_DISABLE_MODE_BLEND
|
||||
seg.setClippingRect(0, 0); // disable clipping
|
||||
if (modeBlending && seg.mode != tmpMode) {
|
||||
Segment::setClippingRect(0, 0); // disable clipping (just in case)
|
||||
if (seg.mode != tmpMode) { // could try seg.isInTransition() to allow color and palette to follow blending styles
|
||||
// set clipping rectangle
|
||||
// new mode is run inside clipping area and old mode outside clipping area
|
||||
unsigned p = seg.progress();
|
||||
@ -1245,48 +1240,48 @@ void WS2812FX::service() {
|
||||
unsigned dh = p * h / 0xFFFFU + 1;
|
||||
switch (blendingStyle) {
|
||||
case BLEND_STYLE_FAIRY_DUST: // fairy dust (must set entire segment, see isPixelXYClipped())
|
||||
seg.setClippingRect(0, w, 0, h);
|
||||
Segment::setClippingRect(0, w, 0, h);
|
||||
break;
|
||||
case BLEND_STYLE_SWIPE_RIGHT: // left-to-right
|
||||
seg.setClippingRect(0, dw, 0, h);
|
||||
Segment::setClippingRect(0, dw, 0, h);
|
||||
break;
|
||||
case BLEND_STYLE_SWIPE_LEFT: // right-to-left
|
||||
seg.setClippingRect(w - dw, w, 0, h);
|
||||
Segment::setClippingRect(w - dw, w, 0, h);
|
||||
break;
|
||||
case BLEND_STYLE_PINCH_OUT: // corners
|
||||
seg.setClippingRect((w + dw)/2, (w - dw)/2, (h + dh)/2, (h - dh)/2); // inverted!!
|
||||
Segment::setClippingRect((w + dw)/2, (w - dw)/2, (h + dh)/2, (h - dh)/2); // inverted!!
|
||||
break;
|
||||
case BLEND_STYLE_INSIDE_OUT: // outward
|
||||
seg.setClippingRect((w - dw)/2, (w + dw)/2, (h - dh)/2, (h + dh)/2);
|
||||
Segment::setClippingRect((w - dw)/2, (w + dw)/2, (h - dh)/2, (h + dh)/2);
|
||||
break;
|
||||
case BLEND_STYLE_SWIPE_DOWN: // top-to-bottom (2D)
|
||||
seg.setClippingRect(0, w, 0, dh);
|
||||
Segment::setClippingRect(0, w, 0, dh);
|
||||
break;
|
||||
case BLEND_STYLE_SWIPE_UP: // bottom-to-top (2D)
|
||||
seg.setClippingRect(0, w, h - dh, h);
|
||||
Segment::setClippingRect(0, w, h - dh, h);
|
||||
break;
|
||||
case BLEND_STYLE_OPEN_H: // horizontal-outward (2D) same look as INSIDE_OUT on 1D
|
||||
seg.setClippingRect((w - dw)/2, (w + dw)/2, 0, h);
|
||||
Segment::setClippingRect((w - dw)/2, (w + dw)/2, 0, h);
|
||||
break;
|
||||
case BLEND_STYLE_OPEN_V: // vertical-outward (2D)
|
||||
seg.setClippingRect(0, w, (h - dh)/2, (h + dh)/2);
|
||||
Segment::setClippingRect(0, w, (h - dh)/2, (h + dh)/2);
|
||||
break;
|
||||
case BLEND_STYLE_PUSH_TL: // TL-to-BR (2D)
|
||||
seg.setClippingRect(0, dw, 0, dh);
|
||||
Segment::setClippingRect(0, dw, 0, dh);
|
||||
break;
|
||||
case BLEND_STYLE_PUSH_TR: // TR-to-BL (2D)
|
||||
seg.setClippingRect(w - dw, w, 0, dh);
|
||||
Segment::setClippingRect(w - dw, w, 0, dh);
|
||||
break;
|
||||
case BLEND_STYLE_PUSH_BR: // BR-to-TL (2D)
|
||||
seg.setClippingRect(w - dw, w, h - dh, h);
|
||||
Segment::setClippingRect(w - dw, w, h - dh, h);
|
||||
break;
|
||||
case BLEND_STYLE_PUSH_BL: // BL-to-TR (2D)
|
||||
seg.setClippingRect(0, dw, h - dh, h);
|
||||
Segment::setClippingRect(0, dw, h - dh, h);
|
||||
break;
|
||||
}
|
||||
}
|
||||
delay = (*_mode[seg.mode])(); // run new/current mode
|
||||
if (modeBlending && seg.mode != tmpMode) {
|
||||
if (seg.mode != tmpMode) { // could try seg.isInTransition() to allow color and palette to follow blending styles
|
||||
Segment::tmpsegd_t _tmpSegData;
|
||||
Segment::modeBlend(true); // set semaphore
|
||||
seg.swapSegenv(_tmpSegData); // temporarily store new mode state (and swap it with transitional state)
|
||||
@ -1301,13 +1296,14 @@ void WS2812FX::service() {
|
||||
#endif
|
||||
seg.call++;
|
||||
if (seg.isInTransition() && delay > FRAMETIME) delay = FRAMETIME; // force faster updates during transition
|
||||
BusManager::setSegmentCCT(oldCCT); // restore old CCT for ABL adjustments
|
||||
BusManager::setSegmentCCT(oldCCT); // restore old CCT for ABL adjustments
|
||||
}
|
||||
|
||||
seg.next_time = nowUp + delay;
|
||||
}
|
||||
_segment_index++;
|
||||
}
|
||||
Segment::setClippingRect(0, 0); // disable clipping for overlays
|
||||
_virtualSegmentLength = 0;
|
||||
_isServicing = false;
|
||||
_triggered = false;
|
||||
|
@ -391,14 +391,14 @@ BusPwm::BusPwm(BusConfig &bc)
|
||||
uint8_t numPins = NUM_PWM_PINS(bc.type);
|
||||
_frequency = bc.frequency ? bc.frequency : WLED_PWM_FREQ;
|
||||
|
||||
#ifdef ESP8266
|
||||
#ifdef ESP8266
|
||||
// duty cycle resolution (_depth) can be extracted from this formula: 1MHz > _frequency * 2^_depth
|
||||
if (_frequency > 1760) _depth = 8;
|
||||
else if (_frequency > 880) _depth = 9;
|
||||
else _depth = 10; // WLED_PWM_FREQ <= 880Hz
|
||||
analogWriteRange((1<<_depth)-1);
|
||||
analogWriteFreq(_frequency);
|
||||
#else
|
||||
#else
|
||||
_ledcStart = pinManager.allocateLedc(numPins);
|
||||
if (_ledcStart == 255) { //no more free LEDC channels
|
||||
deallocatePins(); return;
|
||||
@ -408,7 +408,7 @@ BusPwm::BusPwm(BusConfig &bc)
|
||||
else if (_frequency > 39062) _depth = 10;
|
||||
else if (_frequency > 19531) _depth = 11;
|
||||
else _depth = 12; // WLED_PWM_FREQ <= 19531Hz
|
||||
#endif
|
||||
#endif
|
||||
|
||||
for (unsigned i = 0; i < numPins; i++) {
|
||||
uint8_t currentPin = bc.pins[i];
|
||||
|
@ -173,10 +173,11 @@ class Bus {
|
||||
type == TYPE_FW1906 || type == TYPE_WS2805 ) return true;
|
||||
return false;
|
||||
}
|
||||
static int16_t getCCT() { return _cct; }
|
||||
static inline int16_t getCCT() { return _cct; }
|
||||
static void setCCT(int16_t cct) {
|
||||
_cct = cct;
|
||||
}
|
||||
static inline uint8_t getCCTBlend() { return _cctBlend; }
|
||||
static void setCCTBlend(uint8_t b) {
|
||||
if (b > 100) b = 100;
|
||||
_cctBlend = (b * 127) / 100;
|
||||
|
@ -111,8 +111,8 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
||||
CJSON(correctWB, hw_led["cct"]);
|
||||
CJSON(cctFromRgb, hw_led[F("cr")]);
|
||||
CJSON(cctICused, hw_led[F("ic")]);
|
||||
CJSON(strip.cctBlending, hw_led[F("cb")]);
|
||||
Bus::setCCTBlend(strip.cctBlending);
|
||||
uint8_t cctBlending = hw_led[F("cb")] | Bus::getCCTBlend();
|
||||
Bus::setCCTBlend(cctBlending);
|
||||
strip.setTargetFps(hw_led["fps"]); //NOP if 0, default 42 FPS
|
||||
CJSON(useGlobalLedBuffer, hw_led[F("ld")]);
|
||||
|
||||
@ -408,12 +408,9 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
||||
}
|
||||
|
||||
JsonObject light_tr = light["tr"];
|
||||
CJSON(fadeTransition, light_tr["mode"]);
|
||||
CJSON(modeBlending, light_tr["fx"]);
|
||||
int tdd = light_tr["dur"] | -1;
|
||||
if (tdd >= 0) transitionDelay = transitionDelayDefault = tdd * 100;
|
||||
strip.setTransition(fadeTransition ? transitionDelayDefault : 0);
|
||||
CJSON(strip.paletteFade, light_tr["pal"]);
|
||||
strip.setTransition(transitionDelayDefault);
|
||||
CJSON(randomPaletteChangeTime, light_tr[F("rpc")]);
|
||||
CJSON(useHarmonicRandomPalette, light_tr[F("hrp")]);
|
||||
|
||||
@ -777,7 +774,7 @@ void serializeConfig() {
|
||||
hw_led["cct"] = correctWB;
|
||||
hw_led[F("cr")] = cctFromRgb;
|
||||
hw_led[F("ic")] = cctICused;
|
||||
hw_led[F("cb")] = strip.cctBlending;
|
||||
hw_led[F("cb")] = Bus::getCCTBlend();
|
||||
hw_led["fps"] = strip.getTargetFps();
|
||||
hw_led[F("rgbwm")] = Bus::getGlobalAWMode(); // global auto white mode override
|
||||
hw_led[F("ld")] = useGlobalLedBuffer;
|
||||
@ -894,10 +891,7 @@ void serializeConfig() {
|
||||
light_gc["val"] = gammaCorrectVal;
|
||||
|
||||
JsonObject light_tr = light.createNestedObject("tr");
|
||||
light_tr["mode"] = fadeTransition;
|
||||
light_tr["fx"] = modeBlending;
|
||||
light_tr["dur"] = transitionDelayDefault / 100;
|
||||
light_tr["pal"] = strip.paletteFade;
|
||||
light_tr[F("rpc")] = randomPaletteChangeTime;
|
||||
light_tr[F("hrp")] = useHarmonicRandomPalette;
|
||||
|
||||
|
@ -834,12 +834,7 @@ Swap: <select id="xw${i}" name="XW${i}">
|
||||
Use Gamma value: <input name="GV" type="number" class="m" placeholder="2.8" min="1" max="3" step="0.1" required><br><br>
|
||||
Brightness factor: <input name="BF" type="number" class="m" min="1" max="255" required> %
|
||||
<h3>Transitions</h3>
|
||||
Enable transitions: <input type="checkbox" name="TF" onchange="gId('tran').style.display=this.checked?'inline':'none';"><br>
|
||||
<span id="tran">
|
||||
Effect blending: <input type="checkbox" name="EB"><br>
|
||||
Transition Time: <input name="TD" type="number" class="xl" min="0" max="65500"> ms<br>
|
||||
Palette transitions: <input type="checkbox" name="PF"><br>
|
||||
</span>
|
||||
Transition Time: <input name="TD" type="number" class="xl" min="0" max="65500"> ms<br>
|
||||
<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>
|
||||
|
@ -181,7 +181,6 @@ bool serveLiveLeds(AsyncWebServerRequest* request, uint32_t wsClient = 0);
|
||||
void setValuesFromSegment(uint8_t s);
|
||||
void setValuesFromMainSeg();
|
||||
void setValuesFromFirstSelectedSeg();
|
||||
void resetTimebase();
|
||||
void toggleOnOff();
|
||||
void applyBri();
|
||||
void applyFinalBri();
|
||||
|
@ -351,7 +351,7 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId)
|
||||
tr = root[F("transition")] | -1;
|
||||
if (tr >= 0) {
|
||||
transitionDelay = tr * 100;
|
||||
if (fadeTransition) strip.setTransition(transitionDelay);
|
||||
strip.setTransition(transitionDelay);
|
||||
}
|
||||
}
|
||||
|
||||
@ -364,7 +364,7 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId)
|
||||
tr = root[F("tt")] | -1;
|
||||
if (tr >= 0) {
|
||||
jsonTransitionOnce = true;
|
||||
if (fadeTransition) strip.setTransition(tr * 100);
|
||||
strip.setTransition(tr * 100);
|
||||
}
|
||||
|
||||
tr = root[F("tb")] | -1;
|
||||
@ -779,7 +779,7 @@ void serializeInfo(JsonObject root)
|
||||
|
||||
root[F("freeheap")] = ESP.getFreeHeap();
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
if (psramSafe && psramFound()) root[F("psram")] = ESP.getFreePsram();
|
||||
if (psramFound()) root[F("psram")] = ESP.getFreePsram();
|
||||
#endif
|
||||
root[F("uptime")] = millis()/1000 + rolloverMillis*4294967;
|
||||
|
||||
|
@ -47,12 +47,6 @@ void applyValuesToSelectedSegs()
|
||||
}
|
||||
|
||||
|
||||
void resetTimebase()
|
||||
{
|
||||
strip.timebase = 0 - millis();
|
||||
}
|
||||
|
||||
|
||||
void toggleOnOff()
|
||||
{
|
||||
if (bri == 0)
|
||||
@ -76,7 +70,7 @@ byte scaledBri(byte in)
|
||||
}
|
||||
|
||||
|
||||
//applies global brightness
|
||||
//applies global temporary brightness (briT) to strip
|
||||
void applyBri() {
|
||||
if (!realtimeMode || !arlsForceMaxBri)
|
||||
{
|
||||
@ -90,6 +84,7 @@ void applyFinalBri() {
|
||||
briOld = bri;
|
||||
briT = bri;
|
||||
applyBri();
|
||||
strip.trigger(); // force one last update
|
||||
}
|
||||
|
||||
|
||||
@ -122,7 +117,7 @@ void stateUpdated(byte callMode) {
|
||||
nightlightStartTime = millis();
|
||||
}
|
||||
if (briT == 0) {
|
||||
if (callMode != CALL_MODE_NOTIFICATION) resetTimebase(); //effect start from beginning
|
||||
if (callMode != CALL_MODE_NOTIFICATION) strip.resetTimebase(); //effect start from beginning
|
||||
}
|
||||
|
||||
if (bri > 0) briLast = bri;
|
||||
@ -133,31 +128,24 @@ void stateUpdated(byte callMode) {
|
||||
// notify usermods of state change
|
||||
usermods.onStateChange(callMode);
|
||||
|
||||
if (fadeTransition) {
|
||||
if (strip.getTransition() == 0) {
|
||||
jsonTransitionOnce = false;
|
||||
transitionActive = false;
|
||||
applyFinalBri();
|
||||
strip.trigger();
|
||||
return;
|
||||
}
|
||||
|
||||
if (transitionActive) {
|
||||
briOld = briT;
|
||||
tperLast = 0;
|
||||
} else
|
||||
strip.setTransitionMode(true); // force all segments to transition mode
|
||||
transitionActive = true;
|
||||
transitionStartTime = millis();
|
||||
} else {
|
||||
if (strip.getTransition() == 0) {
|
||||
jsonTransitionOnce = false;
|
||||
transitionActive = false;
|
||||
applyFinalBri();
|
||||
strip.trigger();
|
||||
return;
|
||||
}
|
||||
|
||||
if (transitionActive) {
|
||||
briOld = briT;
|
||||
tperLast = 0;
|
||||
} else
|
||||
strip.setTransitionMode(true); // force all segments to transition mode
|
||||
transitionActive = true;
|
||||
transitionStartTime = millis();
|
||||
}
|
||||
|
||||
|
||||
void updateInterfaces(uint8_t callMode)
|
||||
{
|
||||
void updateInterfaces(uint8_t callMode) {
|
||||
if (!interfaceUpdateCallMode || millis() - lastInterfaceUpdate < INTERFACE_UPDATE_COOLDOWN) return;
|
||||
|
||||
sendDataWs();
|
||||
@ -178,8 +166,7 @@ void updateInterfaces(uint8_t callMode)
|
||||
}
|
||||
|
||||
|
||||
void handleTransitions()
|
||||
{
|
||||
void handleTransitions() {
|
||||
//handle still pending interface update
|
||||
updateInterfaces(interfaceUpdateCallMode);
|
||||
|
||||
@ -198,7 +185,6 @@ void handleTransitions()
|
||||
if (tper - tperLast < 0.004f) return;
|
||||
tperLast = tper;
|
||||
briT = briOld + ((bri - briOld) * tper);
|
||||
|
||||
applyBri();
|
||||
}
|
||||
}
|
||||
@ -211,8 +197,7 @@ void colorUpdated(byte callMode) {
|
||||
}
|
||||
|
||||
|
||||
void handleNightlight()
|
||||
{
|
||||
void handleNightlight() {
|
||||
unsigned long now = millis();
|
||||
if (now < 100 && lastNlUpdate > 0) lastNlUpdate = 0; // take care of millis() rollover
|
||||
if (now - lastNlUpdate < 100) return; // allow only 10 NL updates per second
|
||||
@ -292,7 +277,6 @@ void handleNightlight()
|
||||
}
|
||||
|
||||
//utility for FastLED to use our custom timer
|
||||
uint32_t get_millisecond_timer()
|
||||
{
|
||||
uint32_t get_millisecond_timer() {
|
||||
return strip.now;
|
||||
}
|
||||
|
@ -146,7 +146,7 @@ void handlePlaylist() {
|
||||
}
|
||||
|
||||
jsonTransitionOnce = true;
|
||||
strip.setTransition(fadeTransition ? playlistEntries[playlistIndex].tr * 100 : 0);
|
||||
strip.setTransition(playlistEntries[playlistIndex].tr * 100);
|
||||
playlistEntryDur = playlistEntries[playlistIndex].dur;
|
||||
applyPresetFromPlaylist(playlistEntries[playlistIndex].preset);
|
||||
}
|
||||
|
@ -128,8 +128,8 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||
correctWB = request->hasArg(F("CCT"));
|
||||
cctFromRgb = request->hasArg(F("CR"));
|
||||
cctICused = request->hasArg(F("IC"));
|
||||
strip.cctBlending = request->arg(F("CB")).toInt();
|
||||
Bus::setCCTBlend(strip.cctBlending);
|
||||
uint8_t cctBlending = request->arg(F("CB")).toInt();
|
||||
Bus::setCCTBlend(cctBlending);
|
||||
Bus::setGlobalAWMode(request->arg(F("AW")).toInt());
|
||||
strip.setTargetFps(request->arg(F("FR")).toInt());
|
||||
useGlobalLedBuffer = request->hasArg(F("LD"));
|
||||
@ -313,11 +313,8 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||
gammaCorrectCol = false;
|
||||
}
|
||||
|
||||
fadeTransition = request->hasArg(F("TF"));
|
||||
modeBlending = request->hasArg(F("EB"));
|
||||
t = request->arg(F("TD")).toInt();
|
||||
if (t >= 0) transitionDelayDefault = t;
|
||||
strip.paletteFade = request->hasArg(F("PF"));
|
||||
t = request->arg(F("TP")).toInt();
|
||||
randomPaletteChangeTime = MIN(255,MAX(1,t));
|
||||
useHarmonicRandomPalette = request->hasArg(F("TH"));
|
||||
@ -1124,7 +1121,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
|
||||
|
||||
pos = req.indexOf(F("TT="));
|
||||
if (pos > 0) transitionDelay = getNumVal(&req, pos);
|
||||
if (fadeTransition) strip.setTransition(transitionDelay);
|
||||
strip.setTransition(transitionDelay);
|
||||
|
||||
//set time (unix timestamp)
|
||||
pos = req.indexOf(F("ST="));
|
||||
|
@ -225,10 +225,8 @@ void parseNotifyPacket(uint8_t *udpIn) {
|
||||
|
||||
// set transition time before making any segment changes
|
||||
if (version > 3) {
|
||||
if (fadeTransition) {
|
||||
jsonTransitionOnce = true;
|
||||
strip.setTransition(((udpIn[17] << 0) & 0xFF) + ((udpIn[18] << 8) & 0xFF00));
|
||||
}
|
||||
jsonTransitionOnce = true;
|
||||
strip.setTransition(((udpIn[17] << 0) & 0xFF) + ((udpIn[18] << 8) & 0xFF00));
|
||||
}
|
||||
|
||||
//apply colors from notification to main segment, only if not syncing full segments
|
||||
|
@ -538,10 +538,10 @@ void WLED::beginStrip()
|
||||
} else {
|
||||
// fix for #3196
|
||||
if (bootPreset > 0) {
|
||||
bool oldTransition = fadeTransition; // workaround if transitions are enabled
|
||||
fadeTransition = false; // ignore transitions temporarily
|
||||
uint16_t oldTransition = strip.getTransition(); // workaround if transitions are enabled
|
||||
strip.setTransition(0); // ignore transitions temporarily
|
||||
strip.setColor(0, BLACK); // set all segments black
|
||||
fadeTransition = oldTransition; // restore transitions
|
||||
strip.setTransition(oldTransition); // restore transitions
|
||||
col[0] = col[1] = col[2] = col[3] = 0; // needed for colorUpdated()
|
||||
}
|
||||
briLast = briS; bri = 0;
|
||||
|
@ -545,8 +545,6 @@ 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 uint8_t blendingStyle _INIT(0); // effect blending/transitionig style
|
||||
WLED_GLOBAL bool transitionActive _INIT(false);
|
||||
WLED_GLOBAL uint16_t transitionDelay _INIT(750); // global transition duration
|
||||
|
@ -220,7 +220,7 @@ void loadSettingsFromEEPROM()
|
||||
|
||||
if (lastEEPROMversion > 7)
|
||||
{
|
||||
strip.paletteFade = EEPROM.read(374);
|
||||
//strip.paletteFade = EEPROM.read(374);
|
||||
strip.paletteBlend = EEPROM.read(382);
|
||||
|
||||
for (int i = 0; i < 8; ++i)
|
||||
|
@ -357,7 +357,7 @@ void getSettingsJS(byte subPage, char* dest)
|
||||
sappend('c',SET_F("CCT"),correctWB);
|
||||
sappend('c',SET_F("IC"),cctICused);
|
||||
sappend('c',SET_F("CR"),cctFromRgb);
|
||||
sappend('v',SET_F("CB"),strip.cctBlending);
|
||||
sappend('v',SET_F("CB"),Bus::getCCTBlend());
|
||||
sappend('v',SET_F("FR"),strip.getTargetFps());
|
||||
sappend('v',SET_F("AW"),Bus::getGlobalAWMode());
|
||||
sappend('c',SET_F("LD"),useGlobalLedBuffer);
|
||||
@ -445,10 +445,7 @@ void getSettingsJS(byte subPage, char* dest)
|
||||
sappend('c',SET_F("GB"),gammaCorrectBri);
|
||||
sappend('c',SET_F("GC"),gammaCorrectCol);
|
||||
dtostrf(gammaCorrectVal,3,1,nS); sappends('s',SET_F("GV"),nS);
|
||||
sappend('c',SET_F("TF"),fadeTransition);
|
||||
sappend('c',SET_F("EB"),modeBlending);
|
||||
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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user