(SEGENV.data);
+ }
+
+ for(int i = 0; i < SEGENV.aux1; i++) {
+ //Update values of wave
+ waves[i].update(SEGLEN, SEGMENT.speed);
+
+ if(!(waves[i].stillAlive())) {
+ //If a wave dies, reinitialize it starts over.
+ waves[i].init(SEGLEN, col_to_crgb(color_from_palette(random8(), false, false, random(0, 3))));
+ }
+ }
+
+ //Loop through LEDs to determine color
+ for(int i = 0; i < SEGLEN; i++) {
+ CRGB mixedRgb = CRGB(BACKLIGHT, BACKLIGHT, BACKLIGHT);
+
+ //For each LED we must check each wave if it is "active" at this position.
+ //If there are multiple waves active on a LED we multiply their values.
+ for(int j = 0; j < SEGENV.aux1; j++) {
+ CRGB rgb = waves[j].getColorForLED(i);
+
+ if(rgb != CRGB(0)) {
+ mixedRgb += rgb;
+ }
+ }
+
+ setPixelColor(i, mixedRgb[0], mixedRgb[1], mixedRgb[2], BACKLIGHT);
+ }
+
+ return FRAMETIME;
+}
\ No newline at end of file
diff --git a/wled00/FX.h b/wled00/FX.h
index f368e5674..27329a0af 100644
--- a/wled00/FX.h
+++ b/wled00/FX.h
@@ -62,16 +62,15 @@
/* each segment uses 52 bytes of SRAM memory, so if you're application fails because of
insufficient memory, decreasing MAX_NUM_SEGMENTS may help */
#ifdef ESP8266
- #define MAX_NUM_SEGMENTS 12
+ #define MAX_NUM_SEGMENTS 12
+ /* How many color transitions can run at once */
+ #define MAX_NUM_TRANSITIONS 8
+ /* How much data bytes all segments combined may allocate */
+ #define MAX_SEGMENT_DATA 2048
#else
- #define MAX_NUM_SEGMENTS 16
-#endif
-
-/* How much data bytes all segments combined may allocate */
-#ifdef ESP8266
-#define MAX_SEGMENT_DATA 2048
-#else
-#define MAX_SEGMENT_DATA 8192
+ #define MAX_NUM_SEGMENTS 16
+ #define MAX_NUM_TRANSITIONS 16
+ #define MAX_SEGMENT_DATA 8192
#endif
#define LED_SKIP_AMOUNT 1
@@ -79,7 +78,7 @@
#define NUM_COLORS 3 /* number of colors per segment */
#define SEGMENT _segments[_segment_index]
-#define SEGCOLOR(x) gamma32(_segments[_segment_index].colors[x])
+#define SEGCOLOR(x) _colors_t[x]
#define SEGENV _segment_runtimes[_segment_index]
#define SEGLEN _virtualSegmentLength
#define SEGACT SEGMENT.stop
@@ -119,7 +118,6 @@
#define IS_REVERSE ((SEGMENT.options & REVERSE ) == REVERSE )
#define IS_SELECTED ((SEGMENT.options & SELECTED ) == SELECTED )
-
#define MODE_COUNT 118
#define FX_MODE_STATIC 0
@@ -160,7 +158,7 @@
#define FX_MODE_TRAFFIC_LIGHT 35
#define FX_MODE_COLOR_SWEEP_RANDOM 36
#define FX_MODE_RUNNING_COLOR 37
-#define FX_MODE_RUNNING_RED_BLUE 38
+#define FX_MODE_AURORA 38
#define FX_MODE_RUNNING_RANDOM 39
#define FX_MODE_LARSON_SCANNER 40
#define FX_MODE_COMET 41
@@ -241,11 +239,14 @@
#define FX_MODE_TV_SIMULATOR 116
#define FX_MODE_DYNAMIC_SMOOTH 117
+
class WS2812FX {
typedef uint16_t (WS2812FX::*mode_ptr)(void);
// pre show callback
typedef void (*show_callback) (void);
+
+ static WS2812FX* instance;
// segment parameters
public:
@@ -260,14 +261,40 @@ class WS2812FX {
uint8_t grouping, spacing;
uint8_t opacity;
uint32_t colors[NUM_COLORS];
- void setOption(uint8_t n, bool val)
+ bool setColor(uint8_t slot, uint32_t c, uint8_t segn) { //returns true if changed
+ if (slot >= NUM_COLORS || segn >= MAX_NUM_SEGMENTS) return false;
+ if (c == colors[slot]) return false;
+ ColorTransition::startTransition(opacity, colors[slot], instance->_transitionDur, segn, slot);
+ colors[slot] = c; return true;
+ }
+ void setOpacity(uint8_t o, uint8_t segn) {
+ if (segn >= MAX_NUM_SEGMENTS) return;
+ if (opacity == o) return;
+ ColorTransition::startTransition(opacity, colors[0], instance->_transitionDur, segn, 0);
+ opacity = o;
+ }
+ /*uint8_t actualOpacity() { //respects On/Off state
+ if (!getOption(SEG_OPTION_ON)) return 0;
+ return opacity;
+ }*/
+ void setOption(uint8_t n, bool val, uint8_t segn = 255)
{
+ //bool prevOn = false;
+ //if (n == SEG_OPTION_ON) prevOn = getOption(SEG_OPTION_ON);
if (val) {
options |= 0x01 << n;
} else
{
options &= ~(0x01 << n);
}
+ //transitions on segment on/off don't work correctly at this point
+ /*if (n == SEG_OPTION_ON && segn < MAX_NUM_SEGMENTS && getOption(SEG_OPTION_ON) != prevOn) {
+ if (getOption(SEG_OPTION_ON)) {
+ ColorTransition::startTransition(0, colors[0], instance->_transitionDur, segn, 0);
+ } else {
+ ColorTransition::startTransition(opacity, colors[0], instance->_transitionDur, segn, 0);
+ }
+ }*/
}
bool getOption(uint8_t n)
{
@@ -310,10 +337,10 @@ class WS2812FX {
bool allocateData(uint16_t len){
if (data && _dataLen == len) return true; //already allocated
deallocateData();
- if (WS2812FX::_usedSegmentData + len > MAX_SEGMENT_DATA) return false; //not enough memory
+ if (WS2812FX::instance->_usedSegmentData + len > MAX_SEGMENT_DATA) return false; //not enough memory
data = new (std::nothrow) byte[len];
if (!data) return false; //allocation failed
- WS2812FX::_usedSegmentData += len;
+ WS2812FX::instance->_usedSegmentData += len;
_dataLen = len;
memset(data, 0, len);
return true;
@@ -321,7 +348,7 @@ class WS2812FX {
void deallocateData(){
delete[] data;
data = nullptr;
- WS2812FX::_usedSegmentData -= _dataLen;
+ WS2812FX::instance->_usedSegmentData -= _dataLen;
_dataLen = 0;
}
@@ -351,7 +378,86 @@ class WS2812FX {
bool _requiresReset = false;
} segment_runtime;
+ typedef struct ColorTransition { // 12 bytes
+ uint32_t colorOld = 0;
+ uint32_t transitionStart;
+ uint16_t transitionDur;
+ uint8_t segment = 0xFF; //lower 6 bits: the segment this transition is for (255 indicates transition not in use/available) upper 2 bits: color channel
+ uint8_t briOld = 0;
+ static void startTransition(uint8_t oldBri, uint32_t oldCol, uint16_t dur, uint8_t segn, uint8_t slot) {
+ if (segn >= MAX_NUM_SEGMENTS || slot >= NUM_COLORS || dur == 0) return;
+ if (instance->_brightness == 0) return; //do not need transitions if master bri is off
+ uint8_t tIndex = 0xFF; //none found
+ uint16_t tProgression = 0;
+ uint8_t s = segn + (slot << 6); //merge slot and segment into one byte
+
+ for (uint8_t i = 0; i < MAX_NUM_TRANSITIONS; i++) {
+ uint8_t tSeg = instance->transitions[i].segment;
+ //see if this segment + color already has a running transition
+ if (tSeg == s) {
+ tIndex = i; break;
+ }
+ if (tSeg == 0xFF) { //free transition
+ tIndex = i; tProgression = 0xFFFF;
+ }
+ }
+
+ if (tIndex == 0xFF) { //no slot found yet
+ for (uint8_t i = 0; i < MAX_NUM_TRANSITIONS; i++) {
+ //find most progressed transition to overwrite
+ uint16_t prog = instance->transitions[i].progress();
+ if (prog > tProgression) {
+ tIndex = i; tProgression = prog;
+ }
+ }
+ }
+
+ ColorTransition& t = instance->transitions[tIndex];
+ if (t.segment == s) //this is an active transition on the same segment+color
+ {
+ t.briOld = t.currentBri();
+ t.colorOld = t.currentColor(oldCol);
+ } else {
+ t.briOld = oldBri;
+ t.colorOld = oldCol;
+ uint8_t prevSeg = t.segment & 0x3F;
+ if (prevSeg < MAX_NUM_SEGMENTS) instance->_segments[prevSeg].setOption(SEG_OPTION_TRANSITIONAL, false);
+ }
+ t.transitionDur = dur;
+ t.transitionStart = millis();
+ t.segment = s;
+ instance->_segments[segn].setOption(SEG_OPTION_TRANSITIONAL, true);
+ //refresh immediately, required for Solid mode
+ if (instance->_segment_runtimes[segn].next_time > t.transitionStart + 22) instance->_segment_runtimes[segn].next_time = t.transitionStart;
+ }
+ uint16_t progress(bool allowEnd = false) { //transition progression between 0-65535
+ uint32_t timeNow = millis();
+ if (timeNow - transitionStart > transitionDur) {
+ if (allowEnd) {
+ uint8_t segn = segment & 0x3F;
+ if (segn < MAX_NUM_SEGMENTS) instance->_segments[segn].setOption(SEG_OPTION_TRANSITIONAL, false);
+ segment = 0xFF;
+ }
+ return 0xFFFF;
+ }
+ uint32_t elapsed = timeNow - transitionStart;
+ uint32_t prog = elapsed * 0xFFFF / transitionDur;
+ return (prog > 0xFFFF) ? 0xFFFF : prog;
+ }
+ uint32_t currentColor(uint32_t colorNew) {
+ return instance->color_blend(colorOld, colorNew, progress(true), true);
+ }
+ uint8_t currentBri() {
+ uint8_t segn = segment & 0x3F;
+ if (segn >= MAX_NUM_SEGMENTS) return 0;
+ uint8_t briNew = instance->_segments[segn].opacity;
+ uint32_t prog = progress() + 1;
+ return ((briNew * prog) + (briOld * (0x10000 - prog))) >> 16;
+ }
+ } color_transition;
+
WS2812FX() {
+ WS2812FX::instance = this;
//assign each member of the _mode[] array to its respective function reference
_mode[FX_MODE_STATIC] = &WS2812FX::mode_static;
_mode[FX_MODE_BLINK] = &WS2812FX::mode_blink;
@@ -389,7 +495,7 @@ class WS2812FX {
_mode[FX_MODE_TRAFFIC_LIGHT] = &WS2812FX::mode_traffic_light;
_mode[FX_MODE_COLOR_SWEEP_RANDOM] = &WS2812FX::mode_color_sweep_random;
_mode[FX_MODE_RUNNING_COLOR] = &WS2812FX::mode_running_color;
- _mode[FX_MODE_RUNNING_RED_BLUE] = &WS2812FX::mode_running_red_blue;
+ _mode[FX_MODE_AURORA] = &WS2812FX::mode_aurora;
_mode[FX_MODE_RUNNING_RANDOM] = &WS2812FX::mode_running_random;
_mode[FX_MODE_LARSON_SCANNER] = &WS2812FX::mode_larson_scanner;
_mode[FX_MODE_COMET] = &WS2812FX::mode_comet;
@@ -494,6 +600,7 @@ class WS2812FX {
setBrightness(uint8_t b),
setRange(uint16_t i, uint16_t i2, uint32_t col),
setShowCallback(show_callback cb),
+ setTransition(uint16_t t),
setTransitionMode(bool t),
calcGammaTable(float),
trigger(void),
@@ -548,7 +655,8 @@ class WS2812FX {
timebase,
color_wheel(uint8_t),
color_from_palette(uint16_t, bool mapping, bool wrap, uint8_t mcol, uint8_t pbri = 255),
- color_blend(uint32_t,uint32_t,uint8_t),
+ color_blend(uint32_t,uint32_t,uint16_t,bool b16=false),
+ currentColor(uint32_t colorNew, uint8_t tNr),
gamma32(uint32_t),
getLastShow(void),
getPixelColor(uint16_t),
@@ -603,7 +711,7 @@ class WS2812FX {
mode_colorful(void),
mode_traffic_light(void),
mode_running_color(void),
- mode_running_red_blue(void),
+ mode_aurora(void),
mode_running_random(void),
mode_larson_scanner(void),
mode_comet(void),
@@ -696,7 +804,8 @@ class WS2812FX {
uint16_t _length, _lengthRaw, _virtualSegmentLength;
uint16_t _rand16seed;
uint8_t _brightness;
- static uint16_t _usedSegmentData;
+ uint16_t _usedSegmentData = 0;
+ uint16_t _transitionDur = 750;
void load_gradient_palette(uint8_t);
void handle_palette(void);
@@ -736,10 +845,15 @@ class WS2812FX {
CRGB twinklefox_one_twinkle(uint32_t ms, uint8_t salt, bool cat);
CRGB pacifica_one_layer(uint16_t i, CRGBPalette16& p, uint16_t cistart, uint16_t wavescale, uint8_t bri, uint16_t ioff);
- void blendPixelColor(uint16_t n, uint32_t color, uint8_t blend);
+ void
+ blendPixelColor(uint16_t n, uint32_t color, uint8_t blend),
+ startTransition(uint8_t oldBri, uint32_t oldCol, uint16_t dur, uint8_t segn, uint8_t slot);
uint32_t _lastPaletteChange = 0;
uint32_t _lastShow = 0;
+
+ uint32_t _colors_t[3];
+ uint8_t _bri_t;
#ifdef WLED_USE_ANALOG_LEDS
uint32_t _analogLastShow = 0;
@@ -756,7 +870,12 @@ class WS2812FX {
segment_runtime _segment_runtimes[MAX_NUM_SEGMENTS]; // SRAM footprint: 28 bytes per element
friend class Segment_runtime;
- uint16_t realPixelIndex(uint16_t i);
+ ColorTransition transitions[MAX_NUM_TRANSITIONS]; //12 bytes per element
+ friend class ColorTransition;
+
+ uint16_t
+ realPixelIndex(uint16_t i),
+ transitionProgress(uint8_t tNr);
};
//10 names per line
@@ -764,7 +883,7 @@ const char JSON_mode_names[] PROGMEM = R"=====([
"Solid","Blink","Breathe","Wipe","Wipe Random","Random Colors","Sweep","Dynamic","Colorloop","Rainbow",
"Scan","Scan Dual","Fade","Theater","Theater Rainbow","Running","Saw","Twinkle","Dissolve","Dissolve Rnd",
"Sparkle","Sparkle Dark","Sparkle+","Strobe","Strobe Rainbow","Strobe Mega","Blink Rainbow","Android","Chase","Chase Random",
-"Chase Rainbow","Chase Flash","Chase Flash Rnd","Rainbow Runner","Colorful","Traffic Light","Sweep Random","Running 2","Red & Blue","Stream",
+"Chase Rainbow","Chase Flash","Chase Flash Rnd","Rainbow Runner","Colorful","Traffic Light","Sweep Random","Running 2","Aurora","Stream",
"Scanner","Lighthouse","Fireworks","Rain","Merry Christmas","Fire Flicker","Gradient","Loading","Police","Police All",
"Two Dots","Two Areas","Circus","Halloween","Tri Chase","Tri Wipe","Tri Fade","Lightning","ICU","Multi Comet",
"Scanner Dual","Stream 2","Oscillate","Pride 2015","Juggle","Palette","Fire 2012","Colorwaves","Bpm","Fill Noise",
@@ -782,7 +901,7 @@ const char JSON_palette_names[] PROGMEM = R"=====([
"Pastel","Sunset 2","Beech","Vintage","Departure","Landscape","Beach","Sherbet","Hult","Hult 64",
"Drywet","Jul","Grintage","Rewhi","Tertiary","Fire","Icefire","Cyane","Light Pink","Autumn",
"Magenta","Magred","Yelmag","Yelblu","Orange & Teal","Tiamat","April Night","Orangery","C9","Sakura",
-"Aurora","Atlantica","C9 2","C9 New","Temperature"
+"Aurora","Atlantica","C9 2","C9 New","Temperature","Aurora 2"
])=====";
#endif
diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp
index 4d66a67a3..8c1681a30 100644
--- a/wled00/FX_fcn.cpp
+++ b/wled00/FX_fcn.cpp
@@ -85,23 +85,31 @@ void WS2812FX::service() {
// segment's buffers are cleared
SEGENV.resetIfRequired();
- if (SEGMENT.isActive())
+ if (!SEGMENT.isActive()) continue;
+
+ if(nowUp > SEGENV.next_time || _triggered || (doShow && SEGMENT.mode == 0)) //last is temporary
{
- if(nowUp > SEGENV.next_time || _triggered || (doShow && SEGMENT.mode == 0)) //last is temporary
- {
- if (SEGMENT.grouping == 0) SEGMENT.grouping = 1; //sanity check
- doShow = true;
- uint16_t delay = FRAMETIME;
+ if (SEGMENT.grouping == 0) SEGMENT.grouping = 1; //sanity check
+ doShow = true;
+ uint16_t delay = FRAMETIME;
- if (!SEGMENT.getOption(SEG_OPTION_FREEZE)) { //only run effect function if not frozen
- _virtualSegmentLength = SEGMENT.virtualLength();
- handle_palette();
- delay = (this->*_mode[SEGMENT.mode])(); //effect function
- if (SEGMENT.mode != FX_MODE_HALLOWEEN_EYES) SEGENV.call++;
+ if (!SEGMENT.getOption(SEG_OPTION_FREEZE)) { //only run effect function if not frozen
+ _virtualSegmentLength = SEGMENT.virtualLength();
+ _bri_t = SEGMENT.opacity; _colors_t[0] = SEGMENT.colors[0]; _colors_t[1] = SEGMENT.colors[1]; _colors_t[2] = SEGMENT.colors[2];
+ if (!IS_SEGMENT_ON) _bri_t = 0;
+ for (uint8_t t = 0; t < MAX_NUM_TRANSITIONS; t++) {
+ if ((transitions[t].segment & 0x3F) != i) continue;
+ uint8_t slot = transitions[t].segment >> 6;
+ if (slot == 0) _bri_t = transitions[t].currentBri();
+ _colors_t[slot] = transitions[t].currentColor(SEGMENT.colors[slot]);
}
-
- SEGENV.next_time = nowUp + delay;
+ for (uint8_t c = 0; c < 3; c++) _colors_t[c] = gamma32(_colors_t[c]);
+ handle_palette();
+ delay = (this->*_mode[SEGMENT.mode])(); //effect function
+ if (SEGMENT.mode != FX_MODE_HALLOWEEN_EYES) SEGENV.call++;
}
+
+ SEGENV.next_time = nowUp + delay;
}
}
_virtualSegmentLength = 0;
@@ -165,17 +173,12 @@ void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w)
uint16_t skip = _skipFirstMode ? LED_SKIP_AMOUNT : 0;
if (SEGLEN) {//from segment
- //color_blend(getpixel, col, SEGMENT.opacity); (pseudocode for future blending of segments)
- if (IS_SEGMENT_ON)
- {
- if (SEGMENT.opacity < 255) {
- col.R = scale8(col.R, SEGMENT.opacity);
- col.G = scale8(col.G, SEGMENT.opacity);
- col.B = scale8(col.B, SEGMENT.opacity);
- col.W = scale8(col.W, SEGMENT.opacity);
- }
- } else {
- col = BLACK;
+ //color_blend(getpixel, col, _bri_t); (pseudocode for future blending of segments)
+ if (_bri_t < 255) {
+ col.R = scale8(col.R, _bri_t);
+ col.G = scale8(col.G, _bri_t);
+ col.B = scale8(col.B, _bri_t);
+ col.W = scale8(col.W, _bri_t);
}
/* Set all the pixels in the group, ensuring _skipFirstMode is honored */
@@ -347,7 +350,7 @@ uint8_t WS2812FX::getPaletteCount()
return 13 + GRADIENT_PALETTE_COUNT;
}
-//TODO transitions
+//TODO effect transitions
bool WS2812FX::setEffectConfig(uint8_t m, uint8_t s, uint8_t in, uint8_t p) {
@@ -394,12 +397,16 @@ void WS2812FX::setColor(uint8_t slot, uint32_t c) {
if (applyToAllSelected) {
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++)
{
- if (_segments[i].isSelected()) _segments[i].colors[slot] = c;
+ if (_segments[i].isSelected()) {
+ _segments[i].setColor(slot, c, i);
+ applied = true;
+ }
}
}
if (!applyToAllSelected || !applied) {
- _segments[getMainSegmentId()].colors[slot] = c;
+ uint8_t mainseg = getMainSegmentId();
+ _segments[mainseg].setColor(slot, c, mainseg);
}
}
@@ -602,6 +609,11 @@ void WS2812FX::setShowCallback(show_callback cb)
_callback = cb;
}
+void WS2812FX::setTransition(uint16_t t)
+{
+ _transitionDur = t;
+}
+
void WS2812FX::setTransitionMode(bool t)
{
unsigned long waitMax = millis() + 20; //refresh after 20 ms if transition enabled
@@ -617,24 +629,26 @@ void WS2812FX::setTransitionMode(bool t)
/*
* color blend function
*/
-uint32_t WS2812FX::color_blend(uint32_t color1, uint32_t color2, uint8_t blend) {
+uint32_t WS2812FX::color_blend(uint32_t color1, uint32_t color2, uint16_t blend, bool b16) {
if(blend == 0) return color1;
- if(blend == 255) return color2;
+ uint16_t blendmax = b16 ? 0xFFFF : 0xFF;
+ if(blend == blendmax) return color2;
+ uint8_t shift = b16 ? 16 : 8;
- uint32_t w1 = (color1 >> 24) & 0xff;
- uint32_t r1 = (color1 >> 16) & 0xff;
- uint32_t g1 = (color1 >> 8) & 0xff;
- uint32_t b1 = color1 & 0xff;
+ uint32_t w1 = (color1 >> 24) & 0xFF;
+ uint32_t r1 = (color1 >> 16) & 0xFF;
+ uint32_t g1 = (color1 >> 8) & 0xFF;
+ uint32_t b1 = color1 & 0xFF;
- uint32_t w2 = (color2 >> 24) & 0xff;
- uint32_t r2 = (color2 >> 16) & 0xff;
- uint32_t g2 = (color2 >> 8) & 0xff;
- uint32_t b2 = color2 & 0xff;
+ uint32_t w2 = (color2 >> 24) & 0xFF;
+ uint32_t r2 = (color2 >> 16) & 0xFF;
+ uint32_t g2 = (color2 >> 8) & 0xFF;
+ uint32_t b2 = color2 & 0xFF;
- uint32_t w3 = ((w2 * blend) + (w1 * (255 - blend))) >> 8;
- uint32_t r3 = ((r2 * blend) + (r1 * (255 - blend))) >> 8;
- uint32_t g3 = ((g2 * blend) + (g1 * (255 - blend))) >> 8;
- uint32_t b3 = ((b2 * blend) + (b1 * (255 - blend))) >> 8;
+ uint32_t w3 = ((w2 * blend) + (w1 * (blendmax - blend))) >> shift;
+ uint32_t r3 = ((r2 * blend) + (r1 * (blendmax - blend))) >> shift;
+ uint32_t g3 = ((g2 * blend) + (g1 * (blendmax - blend))) >> shift;
+ uint32_t b3 = ((b2 * blend) + (b1 * (blendmax - blend))) >> shift;
return ((w3 << 24) | (r3 << 16) | (g3 << 8) | (b3));
}
@@ -1041,4 +1055,4 @@ uint32_t WS2812FX::gamma32(uint32_t color)
return ((w << 24) | (r << 16) | (g << 8) | (b));
}
-uint16_t WS2812FX::_usedSegmentData = 0;
+WS2812FX* WS2812FX::instance = nullptr;
\ No newline at end of file
diff --git a/wled00/cfg.cpp b/wled00/cfg.cpp
index 68eba7a3e..43d2615ee 100644
--- a/wled00/cfg.cpp
+++ b/wled00/cfg.cpp
@@ -71,6 +71,11 @@ void deserializeConfig() {
if (apHide > 1) apHide = 1;
CJSON(apBehavior, ap[F("behav")]);
+
+ #ifdef WLED_USE_ETHERNET
+ JsonObject ethernet = doc[F("eth")];
+ CJSON(ethernetType, ethernet[F("type")]);
+ #endif
/*
JsonArray ap_ip = ap[F("ip")];
@@ -272,6 +277,7 @@ void deserializeConfig() {
CJSON(countdownMin, cntdwn_goal[4]);
CJSON(countdownSec, cntdwn_goal[5]);
CJSON(macroCountdown, cntdwn[F("macro")]);
+ setCountdown();
JsonArray timers = tm[F("ins")];
uint8_t it = 0;
@@ -382,6 +388,11 @@ void serializeConfig() {
wifi[F("sleep")] = !noWifiSleep;
wifi[F("phy")] = 1;
+ #ifdef WLED_USE_ETHERNET
+ JsonObject ethernet = doc.createNestedObject("eth");
+ ethernet[F("type")] = ethernetType;
+ #endif
+
JsonObject hw = doc.createNestedObject("hw");
JsonObject hw_led = hw.createNestedObject("led");
diff --git a/wled00/colors.cpp b/wled00/colors.cpp
index 0996de07f..625d9d103 100644
--- a/wled00/colors.cpp
+++ b/wled00/colors.cpp
@@ -33,6 +33,11 @@ void colorFromUint24(uint32_t in, bool secondary)
}
}
+//store color components in uint32_t
+uint32_t colorFromRgbw(byte* rgbw) {
+ return (rgbw[0] << 16) + (rgbw[1] << 8) + rgbw[2] + (rgbw[3] << 24);
+}
+
//relatively change white brightness, minumum A=5
void relativeChangeWhite(int8_t amount, byte lowerBoundary)
{
diff --git a/wled00/const.h b/wled00/const.h
index 3b74bb6f6..8fec2661e 100644
--- a/wled00/const.h
+++ b/wled00/const.h
@@ -132,6 +132,10 @@
#define BTN_TYPE_SWITCH 4 //not implemented
#define BTN_TYPE_SWITCH_ACT_HIGH 5 //not implemented
+//Ethernet board types
+#define WLED_ETH_NONE 0
+#define WLED_ETH_WT32_ETH01 1
+#define WLED_ETH_ESP32_POE 2
//Hue error codes
#define HUE_ERROR_INACTIVE 0
diff --git a/wled00/data/index.js b/wled00/data/index.js
index f3fb72af6..15f6df5d1 100644
--- a/wled00/data/index.js
+++ b/wled00/data/index.js
@@ -454,9 +454,8 @@ function populateInfo(i)
else if (pwr > 0) {pwr = 50 * Math.round(pwr/50); pwru = pwr + " mA";}
var urows="";
if (i.u) {
- for (var k = 0; k < i.u.length; k++)
+ for (const [k, val] of Object.entries(i.u))
{
- var val = i.u[k];
if (val[1]) {
urows += inforow(k,val[0],val[1]);
} else {
@@ -1335,10 +1334,13 @@ function lock(e) {
function move(e) {
if(!locked || pcMode) return;
- var dx = unify(e).clientX - x0, s = Math.sign(dx),
- f = +(s*dx/w).toFixed(2);
+ var clientX = unify(e).clientX;
+ var dx = clientX - x0;
+ var s = Math.sign(dx);
+ var f = +(s*dx/w).toFixed(2);
- if((iSlide > 0 || s < 0) && (iSlide < N - 1 || s > 0) &&
+ if((clientX != 0) &&
+ (iSlide > 0 || s < 0) && (iSlide < N - 1 || s > 0) &&
f > 0.12 &&
d.getElementsByClassName("tabcontent")[iSlide].scrollTop == scrollS) {
_C.style.setProperty('--i', iSlide -= s);
diff --git a/wled00/data/settings_sec.htm b/wled00/data/settings_sec.htm
index f4761db1a..f9d1a3a53 100644
--- a/wled00/data/settings_sec.htm
+++ b/wled00/data/settings_sec.htm
@@ -46,9 +46,9 @@
Enable ArduinoOTA:
About
WLED version ##VERSION##
- Contributors, dependencies and special thanks
+ Contributors, dependencies and special thanks
A huge thank you to everyone who helped me create WLED!
- (c) 2016-2020 Christian Schwinne
+ (c) 2016-2021 Christian Schwinne
Licensed under the MIT license
Server message: Response error!
Back Save & Reboot
diff --git a/wled00/data/settings_sync.htm b/wled00/data/settings_sync.htm
index 0611a0a7d..cd61870b5 100644
--- a/wled00/data/settings_sync.htm
+++ b/wled00/data/settings_sync.htm
@@ -53,7 +53,7 @@ Type:
Port:
Multicast:
Start universe:
-Reboot required. Check out LedFx !
+Reboot required. Check out LedFx !
Skip out-of-sequence packets:
DMX start address:
DMX mode:
diff --git a/wled00/data/settings_wifi.htm b/wled00/data/settings_wifi.htm
index 819fc58a9..3e58609bc 100644
--- a/wled00/data/settings_wifi.htm
+++ b/wled00/data/settings_wifi.htm
@@ -63,7 +63,13 @@
Experimental
Disable WiFi sleep:
Can help with connectivity issues.
- Do not enable if WiFi is working correctly, increases power consumption.
+ Do not enable if WiFi is working correctly, increases power consumption.
+
+
Ethernet Type
+
+ None
+ WT32-ETH01
+ ESP32-POE
Back Save & Connect
diff --git a/wled00/fcn_declare.h b/wled00/fcn_declare.h
index d52d5edf0..909f04f2c 100644
--- a/wled00/fcn_declare.h
+++ b/wled00/fcn_declare.h
@@ -34,6 +34,7 @@ void serializeConfigSec();
//colors.cpp
void colorFromUint32(uint32_t in, bool secondary = false);
void colorFromUint24(uint32_t in, bool secondary = false);
+uint32_t colorFromRgbw(byte* rgbw);
void relativeChangeWhite(int8_t amount, byte lowerBoundary = 0);
void colorHStoRGB(uint16_t hue, byte sat, byte* rgb); //hue, sat to rgb
void colorKtoRGB(uint16_t kelvin, byte* rgb);
@@ -109,7 +110,7 @@ void setValuesFromMainSeg();
void resetTimebase();
void toggleOnOff();
void setAllLeds();
-void setLedsStandard(bool justColors = false);
+void setLedsStandard();
bool colorChanged();
void colorUpdated(int callMode);
void updateInterfaces(uint8_t callMode);
diff --git a/wled00/html_settings.h b/wled00/html_settings.h
index d6d72cb15..13bb18059 100644
--- a/wled00/html_settings.h
+++ b/wled00/html_settings.h
@@ -61,9 +61,11 @@ value="2">AlwaysNever (not recommended)
AP IP: Not active Experimental
Disable WiFi sleep:
Can help with connectivity issues.
-Do not enable if WiFi is working correctly, increases power consumption.
-Back
-Save & Connect