Grouping and Spacing

This commit is contained in:
cschwinne 2020-01-14 10:57:23 +01:00
parent 6bc927c535
commit ae6ba79f1e
4 changed files with 318 additions and 300 deletions

File diff suppressed because it is too large Load Diff

View File

@ -59,7 +59,7 @@
#define SEGMENT _segments[_segment_index] #define SEGMENT _segments[_segment_index]
#define SEGCOLOR(x) gamma32(_segments[_segment_index].colors[x]) #define SEGCOLOR(x) gamma32(_segments[_segment_index].colors[x])
#define SEGENV _segment_runtimes[_segment_index] #define SEGENV _segment_runtimes[_segment_index]
#define SEGLEN SEGMENT.length() #define SEGLEN _virtualSegmentLength
#define SEGACT SEGMENT.stop #define SEGACT SEGMENT.stop
#define SPEED_FORMULA_L 5 + (50*(255 - SEGMENT.speed))/SEGLEN #define SPEED_FORMULA_L 5 + (50*(255 - SEGMENT.speed))/SEGLEN
#define RESET_RUNTIME memset(_segment_runtimes, 0, sizeof(_segment_runtimes)) #define RESET_RUNTIME memset(_segment_runtimes, 0, sizeof(_segment_runtimes))
@ -199,16 +199,15 @@ class WS2812FX {
// segment parameters // segment parameters
public: public:
typedef struct Segment { // 25 bytes typedef struct Segment { // 24 bytes
uint16_t start; uint16_t start;
uint16_t stop; //segment invalid if stop == 0 uint16_t stop; //segment invalid if stop == 0
uint16_t rawLength;
uint8_t speed; uint8_t speed;
uint8_t intensity; uint8_t intensity;
uint8_t palette; uint8_t palette;
uint8_t mode; uint8_t mode;
uint8_t options; //bit pattern: msb first: transitional tbd tbd tbd tbd paused reverse selected uint8_t options; //bit pattern: msb first: transitional tbd tbd tbd tbd paused reverse selected
uint8_t group, spacing; uint8_t grouping, spacing;
uint8_t opacity; uint8_t opacity;
uint32_t colors[NUM_COLORS]; uint32_t colors[NUM_COLORS];
void setOption(uint8_t n, bool val) void setOption(uint8_t n, bool val)
@ -236,8 +235,14 @@ class WS2812FX {
{ {
return stop - start; return stop - start;
} }
uint16_t ledGroup() { uint16_t groupLength()
return group + spacing; {
return grouping + spacing;
}
uint16_t virtualLength()
{
uint16_t groupLen = groupLength();
return (length() + groupLen -1) / groupLen;
} }
} segment; } segment;
@ -381,7 +386,7 @@ class WS2812FX {
} }
void void
init(bool supportWhite, uint16_t countPixels, uint8_t group, uint8_t spacing, bool skipFirst), init(bool supportWhite, uint16_t countPixels, bool skipFirst),
service(void), service(void),
blur(uint8_t), blur(uint8_t),
fade_out(uint8_t r), fade_out(uint8_t r),
@ -396,7 +401,7 @@ class WS2812FX {
setShowCallback(show_callback cb), setShowCallback(show_callback cb),
setTransitionMode(bool t), setTransitionMode(bool t),
trigger(void), trigger(void),
setSegment(uint8_t n, uint16_t start, uint16_t length, uint8_t group, uint8_t spacing), setSegment(uint8_t n, uint16_t start, uint16_t stop, uint8_t grouping = 0, uint8_t spacing = 0),
resetSegments(), resetSegments(),
setPixelColor(uint16_t n, uint32_t c), setPixelColor(uint16_t n, uint32_t c),
setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0), setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0),
@ -416,8 +421,6 @@ class WS2812FX {
paletteBlend = 0, paletteBlend = 0,
colorOrder = 0, colorOrder = 0,
milliampsPerLed = 55, milliampsPerLed = 55,
_spacing = 0,
_group = 1,
getBrightness(void), getBrightness(void),
getMode(void), getMode(void),
getSpeed(void), getSpeed(void),
@ -432,8 +435,7 @@ class WS2812FX {
uint16_t uint16_t
ablMilliampsMax, ablMilliampsMax,
currentMilliamps, currentMilliamps,
triwave16(uint16_t), triwave16(uint16_t);
getUsableCount();
uint32_t uint32_t
timebase, timebase,
@ -564,7 +566,7 @@ class WS2812FX {
CRGBPalette16 targetPalette; CRGBPalette16 targetPalette;
uint32_t now; uint32_t now;
uint16_t _length; uint16_t _length, _lengthRaw, _virtualSegmentLength;
uint16_t _rand16seed; uint16_t _rand16seed;
uint8_t _brightness; uint8_t _brightness;
static uint16_t _usedSegmentData; static uint16_t _usedSegmentData;
@ -610,11 +612,10 @@ class WS2812FX {
uint8_t _segment_index = 0; uint8_t _segment_index = 0;
uint8_t _segment_index_palette_last = 99; uint8_t _segment_index_palette_last = 99;
segment _segments[MAX_NUM_SEGMENTS] = { // SRAM footprint: 25 bytes per element segment _segments[MAX_NUM_SEGMENTS] = { // SRAM footprint: 24 bytes per element
// start, stop, length, speed, intensity, palette, mode, options, group, spacing, opacity (unused), color[] // start, stop, speed, intensity, palette, mode, options, grouping, spacing, opacity (unused), color[]
{ 0, 7, 7, DEFAULT_SPEED, 128, 0, DEFAULT_MODE, NO_OPTIONS, 1, 0, 255, {DEFAULT_COLOR}} { 0, 7, DEFAULT_SPEED, 128, 0, DEFAULT_MODE, NO_OPTIONS, 1, 0, 255, {DEFAULT_COLOR}}
}; };
segment_runtime _segment_runtimes[MAX_NUM_SEGMENTS]; // SRAM footprint: 28 bytes per element segment_runtime _segment_runtimes[MAX_NUM_SEGMENTS]; // SRAM footprint: 28 bytes per element
friend class Segment_runtime; friend class Segment_runtime;

View File

@ -30,37 +30,29 @@
#define LED_SKIP_AMOUNT 1 #define LED_SKIP_AMOUNT 1
#define MIN_SHOW_DELAY 15 #define MIN_SHOW_DELAY 15
void WS2812FX::init(bool supportWhite, uint16_t countPixels, uint8_t group, uint8_t spacing, bool skipFirst) void WS2812FX::init(bool supportWhite, uint16_t countPixels, bool skipFirst)
{ {
if (supportWhite == _rgbwMode && countPixels == _length && disableNLeds == _disableNLeds) return; if (supportWhite == _rgbwMode && countPixels == _length) return;
RESET_RUNTIME; RESET_RUNTIME;
_rgbwMode = supportWhite; _rgbwMode = supportWhite;
_skipFirstMode = skipFirst; _skipFirstMode = skipFirst;
_length = countPixels; _length = countPixels;
_group = group;
_spacing = spacing;
uint8_t ty = 1; uint8_t ty = 1;
if (supportWhite) ty =2; if (supportWhite) ty = 2;
uint16_t lengthRaw = _length + (_skipFirstMode ? LED_SKIP_AMOUNT : 0); _lengthRaw = _length;
if (_skipFirstMode) {
_lengthRaw += LED_SKIP_AMOUNT;
}
bus->Begin((NeoPixelType)ty, lengthRaw); bus->Begin((NeoPixelType)ty, _lengthRaw);
_segments[0].start = 0; _segments[0].start = 0;
_segments[0].stop = _length;
_segments[0].group = _group;
_segments[0].spacing = _spacing;
_segments[0].stop = getUsableCount();
_segments[0].rawLength = _length;
setBrightness(_brightness); setBrightness(_brightness);
} }
uint16_t WS2812FX::getUsableCount() {
uint16_t ledGroup = _group + _spacing;
return (_length + ledGroup -1) / ledGroup;
}
void WS2812FX::service() { void WS2812FX::service() {
uint32_t nowUp = millis(); // Be aware, millis() rolls over every 49 days uint32_t nowUp = millis(); // Be aware, millis() rolls over every 49 days
now = nowUp + timebase; now = nowUp + timebase;
@ -73,6 +65,7 @@ void WS2812FX::service() {
{ {
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
{ {
_virtualSegmentLength = SEGMENT.virtualLength();
doShow = true; doShow = true;
handle_palette(); handle_palette();
uint16_t delay = (this->*_mode[SEGMENT.mode])(); uint16_t delay = (this->*_mode[SEGMENT.mode])();
@ -81,6 +74,7 @@ void WS2812FX::service() {
} }
} }
} }
_virtualSegmentLength = 0;
if(doShow) { if(doShow) {
yield(); yield();
show(); show();
@ -97,82 +91,90 @@ void WS2812FX::setPixelColor(uint16_t n, uint32_t c) {
} }
uint16_t WS2812FX::realPixelIndex(uint16_t i) { uint16_t WS2812FX::realPixelIndex(uint16_t i) {
int16_t iGroup = (i - SEGMENT.start) * SEGMENT.ledGroup(); int16_t iGroup = i * SEGMENT.groupLength();
/* reverse just an individual segment */ /* reverse just an individual segment */
int16_t realIndex; int16_t realIndex = iGroup;
if IS_REVERSE if (IS_REVERSE) realIndex = SEGMENT.length() -iGroup -1;
realIndex = SEGMENT.rawLength + SEGMENT.start - iGroup -1;
else
realIndex = SEGMENT.start + iGroup;
/* Reverse the whole string */
if (reverseMode) realIndex = _length - 1 - realIndex;
return realIndex; realIndex += SEGMENT.start;
/* Reverse the whole string */
if (reverseMode) realIndex = _length - 1 - realIndex;
return realIndex;
} }
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)
{ {
RgbwColor col;
RgbwColor color; switch (colorOrder)
color.W = w;
switch (colorOrder) //0 = Grb, default
{ {
case 0: color.G = g; color.R = r; color.B = b; break; // 0 = GRB case 0: col.G = g; col.R = r; col.B = b; break; //0 = GRB, default
case 1: color.G = r; color.R = g; color.B = b; break; // 1 = RGB, common for WS2811 case 1: col.G = r; col.R = g; col.B = b; break; //1 = RGB, common for WS2811
case 2: color.G = b; color.R = r; color.B = g; break; // 2 = BRG case 2: col.G = b; col.R = r; col.B = g; break; //2 = BRG
case 3: color.G = r; color.R = b; color.B = g; break; // 3 = RBG case 3: col.G = r; col.R = b; col.B = g; break; //3 = RBG
case 4: col.G = b; col.R = g; col.B = r; break; //4 = BGR
default: col.G = g; col.R = b; col.B = r; break; //5 = GBR
} }
col.W = w;
if (!_cronixieMode) if (!_cronixieMode)
{ {
/* Set all the pixels in the group, ensuring _skipFirstMode is honored */
bool reversed = reverseMode ^ IS_REVERSE;
uint16_t realIndex = realPixelIndex(i);
uint16_t skip = _skipFirstMode ? LED_SKIP_AMOUNT : 0; uint16_t skip = _skipFirstMode ? LED_SKIP_AMOUNT : 0;
for (uint16_t l = 0; l < SEGMENT.ledGroup(); l++) { if (SEGLEN) {//from segment
int16_t indexSet = realIndex + (reversed ? -l : l); /* Set all the pixels in the group, ensuring _skipFirstMode is honored */
if (indexSet >= SEGMENT.start && (indexSet < SEGMENT.start + SEGMENT.rawLength)) bool reversed = reverseMode ^ IS_REVERSE;
bus->SetPixelColor(indexSet + skip, l < SEGMENT.group ? color : RgbwColor(0, 0, 0, 0)); uint16_t realIndex = realPixelIndex(i);
for (uint16_t l = 0; indexSet == 0 && l < skip; l++) {// Clear the skipped pixels for (uint16_t j = 0; j < SEGMENT.grouping; j++) {
bus->SetPixelColor(l, RgbwColor(0, 0, 0, 0)); int16_t indexSet = realIndex + (reversed ? -j : j);
if (indexSet >= SEGMENT.start && indexSet < SEGMENT.stop) bus->SetPixelColor(indexSet + skip, col);
}
} else { //live data, etc.
if (reverseMode) i = _length - 1 - i;
bus->SetPixelColor(i + skip, col);
}
if (skip && i == 0) {
for (uint16_t j = 0; j < skip; j++) {
bus->SetPixelColor(j, RgbwColor(0, 0, 0, 0));
} }
} }
} else { return;
if(i>6)return; }
byte o = 10*i;
if (_cronixieBacklightEnabled && _cronixieDigits[i] <11) //CRONIXIE
if(i>6)return;
byte o = 10*i;
if (_cronixieBacklightEnabled && _cronixieDigits[i] <11)
{
byte r2 = _segments[0].colors[1] >>16;
byte g2 = _segments[0].colors[1] >> 8;
byte b2 = _segments[0].colors[1];
byte w2 = _segments[0].colors[1] >>24;
for (int j=o; j< o+19; j++)
{ {
byte r2 = _segments[0].colors[1] >>16; bus->SetPixelColor(j, RgbwColor(r2,g2,b2,w2));
byte g2 = _segments[0].colors[1] >> 8;
byte b2 = _segments[0].colors[1];
byte w2 = _segments[0].colors[1] >>24;
for (int j=o; j< o+19; j++)
{
bus->SetPixelColor(j, RgbwColor(r2,g2,b2,w2));
}
} else
{
for (int j=o; j< o+19; j++)
{
bus->SetPixelColor(j, RgbwColor(0,0,0,0));
}
} }
if (_skipFirstMode) o += LED_SKIP_AMOUNT; } else
switch(_cronixieDigits[i]) {
for (int j=o; j< o+19; j++)
{ {
case 0: bus->SetPixelColor(o+5, color); break; bus->SetPixelColor(j, RgbwColor(0,0,0,0));
case 1: bus->SetPixelColor(o+0, color); break;
case 2: bus->SetPixelColor(o+6, color); break;
case 3: bus->SetPixelColor(o+1, color); break;
case 4: bus->SetPixelColor(o+7, color); break;
case 5: bus->SetPixelColor(o+2, color); break;
case 6: bus->SetPixelColor(o+8, color); break;
case 7: bus->SetPixelColor(o+3, color); break;
case 8: bus->SetPixelColor(o+9, color); break;
case 9: bus->SetPixelColor(o+4, color); break;
} }
} }
if (_skipFirstMode) o += LED_SKIP_AMOUNT;
switch(_cronixieDigits[i])
{
case 0: bus->SetPixelColor(o+5, col); break;
case 1: bus->SetPixelColor(o+0, col); break;
case 2: bus->SetPixelColor(o+6, col); break;
case 3: bus->SetPixelColor(o+1, col); break;
case 4: bus->SetPixelColor(o+7, col); break;
case 5: bus->SetPixelColor(o+2, col); break;
case 6: bus->SetPixelColor(o+8, col); break;
case 7: bus->SetPixelColor(o+3, col); break;
case 8: bus->SetPixelColor(o+9, col); break;
case 9: bus->SetPixelColor(o+4, col); break;
}
} }
void WS2812FX::driverModeCronixie(bool b) void WS2812FX::driverModeCronixie(bool b)
@ -387,6 +389,7 @@ uint32_t WS2812FX::getColor(void) {
uint32_t WS2812FX::getPixelColor(uint16_t i) uint32_t WS2812FX::getPixelColor(uint16_t i)
{ {
i = realPixelIndex(i) + (_skipFirstMode ? LED_SKIP_AMOUNT : 0); i = realPixelIndex(i) + (_skipFirstMode ? LED_SKIP_AMOUNT : 0);
if (_cronixieMode) if (_cronixieMode)
{ {
if(i>6)return 0; if(i>6)return 0;
@ -406,18 +409,20 @@ uint32_t WS2812FX::getPixelColor(uint16_t i)
default: return 0; default: return 0;
} }
} }
uint16_t skip = _skipFirstMode ? LED_SKIP_AMOUNT : 0; if (i >= _lengthRaw) return 0;
if (i >= (_length + skip)) return 0;
RgbwColor lColor = bus->GetPixelColorRgbw(i); RgbwColor col = bus->GetPixelColorRgbw(i);
byte r = lColor.R, g = lColor.G, b = lColor.B;
switch (colorOrder) switch (colorOrder)
{ {
case 0: break; //0 = Grb // W G R B
case 1: r = lColor.G; g = lColor.R; break; //1 = Rgb, common for WS2811 case 0: return ((col.W << 24) | (col.G << 8) | (col.R << 16) | (col.B)); //0 = GRB, default
case 2: g = lColor.B; b = lColor.G; break; //2 = Brg case 1: return ((col.W << 24) | (col.R << 8) | (col.G << 16) | (col.B)); //1 = RGB, common for WS2811
case 3: r = lColor.B; g = lColor.R; b = lColor.G; //3 = Rbg case 2: return ((col.W << 24) | (col.B << 8) | (col.R << 16) | (col.G)); //2 = BRG
case 3: return ((col.W << 24) | (col.R << 8) | (col.B << 16) | (col.G)); //3 = RBG
case 4: return ((col.W << 24) | (col.B << 8) | (col.G << 16) | (col.R)); //4 = BGR
case 5: return ((col.W << 24) | (col.G << 8) | (col.B << 16) | (col.R)); //5 = GBR
} }
return ( (lColor.W << 24) | (r << 16) | (g << 8) | (b) ); return 0;
} }
WS2812FX::Segment& WS2812FX::getSegment(uint8_t id) { WS2812FX::Segment& WS2812FX::getSegment(uint8_t id) {
@ -437,26 +442,26 @@ uint32_t WS2812FX::getLastShow(void) {
return _lastShow; return _lastShow;
} }
void WS2812FX::setSegment(uint8_t n, uint16_t start, uint16_t length, uint8_t group, uint8_t spacing) { void WS2812FX::setSegment(uint8_t n, uint16_t i1, uint16_t i2, uint8_t grouping, uint8_t spacing) {
if (n >= MAX_NUM_SEGMENTS) return; if (n >= MAX_NUM_SEGMENTS) return;
Segment& seg = _segments[n]; Segment& seg = _segments[n];
if (seg.start == start && seg.rawLength == length && seg.group == group && seg.spacing == spacing) return; //return if neither bounds nor grouping have changed
if (seg.start == i1 && seg.stop == i2 && (!grouping || (seg.grouping == grouping && seg.spacing == spacing))) return;
_segment_index = n; fill(0); //turn old segment range off if (seg.stop) setRange(seg.start, seg.stop -1, 0); //turn old segment range off
if (i2 <= i1) //disable segment
seg.rawLength = min(_length - start, length); {
seg.spacing = spacing; seg.stop = 0; return;
seg.group = group;
seg.start = start;
uint16_t ledGroup = seg.ledGroup();
seg.stop = (seg.rawLength - seg.start + ledGroup -1) / ledGroup + seg.start;
if (seg.start >= seg.stop) {
seg.stop = 0;
} }
else { if (i1 < _length) seg.start = i1;
_segment_runtimes[n].reset(); seg.stop = i2;
if (i2 > _length) seg.stop = _length;
if (grouping) {
seg.grouping = grouping;
seg.spacing = spacing;
} }
_segment_runtimes[n].reset();
} }
void WS2812FX::resetSegments() { void WS2812FX::resetSegments() {
@ -467,16 +472,13 @@ void WS2812FX::resetSegments() {
_segments[0].colors[0] = DEFAULT_COLOR; _segments[0].colors[0] = DEFAULT_COLOR;
_segments[0].start = 0; _segments[0].start = 0;
_segments[0].speed = DEFAULT_SPEED; _segments[0].speed = DEFAULT_SPEED;
_segments[0].stop = getUsableCount(); _segments[0].stop = _length;
_segments[0].rawLength = _length; _segments[0].grouping = 1;
_segments[0].setOption(0, 1); //select _segments[0].setOption(0, 1); //select
_segments[0].group = _group;
_segments[0].spacing = _spacing;
for (uint16_t i = 1; i < MAX_NUM_SEGMENTS; i++) for (uint16_t i = 1; i < MAX_NUM_SEGMENTS; i++)
{ {
_segments[i].colors[0] = color_wheel(i*51); _segments[i].colors[0] = color_wheel(i*51);
_segments[i].grouping = 1;
_segment_runtimes[i].reset(); _segment_runtimes[i].reset();
} }
_segment_runtimes[0].reset(); _segment_runtimes[0].reset();
@ -536,7 +538,7 @@ uint32_t WS2812FX::color_blend(uint32_t color1, uint32_t color2, uint8_t blend)
* Fills segment with color * Fills segment with color
*/ */
void WS2812FX::fill(uint32_t c) { void WS2812FX::fill(uint32_t c) {
for(uint16_t i=SEGMENT.start; i < SEGMENT.stop; i++) { for(uint16_t i = 0; i < SEGLEN; i++) {
setPixelColor(i, c); setPixelColor(i, c);
} }
} }
@ -554,7 +556,7 @@ void WS2812FX::fade_out(uint8_t rate) {
int g2 = (color >> 8) & 0xff; int g2 = (color >> 8) & 0xff;
int b2 = color & 0xff; int b2 = color & 0xff;
for(uint16_t i=SEGMENT.start; i < SEGMENT.stop; i++) { for(uint16_t i = 0; i < SEGLEN; i++) {
color = getPixelColor(i); color = getPixelColor(i);
int w1 = (color >> 24) & 0xff; int w1 = (color >> 24) & 0xff;
int r1 = (color >> 16) & 0xff; int r1 = (color >> 16) & 0xff;
@ -584,14 +586,14 @@ void WS2812FX::blur(uint8_t blur_amount)
uint8_t keep = 255 - blur_amount; uint8_t keep = 255 - blur_amount;
uint8_t seep = blur_amount >> 1; uint8_t seep = blur_amount >> 1;
CRGB carryover = CRGB::Black; CRGB carryover = CRGB::Black;
for(uint16_t i = SEGMENT.start; i < SEGMENT.stop; i++) for(uint16_t i = 0; i < SEGLEN; i++)
{ {
CRGB cur = col_to_crgb(getPixelColor(i)); CRGB cur = col_to_crgb(getPixelColor(i));
CRGB part = cur; CRGB part = cur;
part.nscale8(seep); part.nscale8(seep);
cur.nscale8(keep); cur.nscale8(keep);
cur += carryover; cur += carryover;
if(i > SEGMENT.start) { if(i > 0) {
uint32_t c = getPixelColor(i-1); uint32_t c = getPixelColor(i-1);
uint8_t r = (c >> 16 & 0xFF); uint8_t r = (c >> 16 & 0xFF);
uint8_t g = (c >> 8 & 0xFF); uint8_t g = (c >> 8 & 0xFF);
@ -756,7 +758,7 @@ uint32_t WS2812FX::color_from_palette(uint16_t i, bool mapping, bool wrap, uint8
{ {
if (SEGMENT.palette == 0 && mcol < 3) return SEGCOLOR(mcol); //WS2812FX default if (SEGMENT.palette == 0 && mcol < 3) return SEGCOLOR(mcol); //WS2812FX default
uint8_t paletteIndex = i; uint8_t paletteIndex = i;
if (mapping) paletteIndex = map(i,SEGMENT.start,SEGMENT.stop-1,0,255); if (mapping) paletteIndex = (i*255)/(SEGLEN -1);
if (!wrap) paletteIndex = scale8(paletteIndex, 240); //cut off blend at palette "end" if (!wrap) paletteIndex = scale8(paletteIndex, 240); //cut off blend at palette "end"
CRGB fastled_col; CRGB fastled_col;
fastled_col = ColorFromPalette( currentPalette, paletteIndex, pbri, (paletteBlend == 3)? NOBLEND:LINEARBLEND); fastled_col = ColorFromPalette( currentPalette, paletteIndex, pbri, (paletteBlend == 3)? NOBLEND:LINEARBLEND);

View File

@ -8,12 +8,16 @@ void deserializeSegment(JsonObject elem, byte it)
if (id < strip.getMaxSegments()) if (id < strip.getMaxSegments())
{ {
WS2812FX::Segment& seg = strip.getSegment(id); WS2812FX::Segment& seg = strip.getSegment(id);
uint16_t start = elem.containsKey("start") ? elem["start"] : seg.start; uint16_t start = elem["start"] | seg.start;
uint16_t len = elem.containsKey("len") ? elem["len"] : seg.rawLength; int stop = elem["stop"] | -1;
uint8_t group = max(1, elem["grp"] | seg.group);
uint8_t spacing = elem.containsKey("spc") ? elem["spc"] : seg.spacing;
strip.setSegment(id, start, len, group, spacing); if (stop < 0) {
uint16_t len = elem["len"];
stop = (len > 0) ? start + len : seg.stop;
}
uint16_t grp = elem["grp"] | seg.grouping;
uint16_t spc = elem["spc"] | seg.spacing;
strip.setSegment(id, start, stop, grp, spc);
JsonArray colarr = elem["col"]; JsonArray colarr = elem["col"];
if (!colarr.isNull()) if (!colarr.isNull())
@ -163,7 +167,9 @@ void serializeSegment(JsonObject& root, WS2812FX::Segment& seg, byte id)
root["id"] = id; root["id"] = id;
root["start"] = seg.start; root["start"] = seg.start;
root["stop"] = seg.stop; root["stop"] = seg.stop;
root["len"] = seg.rawLength; root["len"] = seg.stop - seg.start;
root["grp"] = seg.grouping;
root["spc"] = seg.spacing;
JsonArray colarr = root.createNestedArray("col"); JsonArray colarr = root.createNestedArray("col");
@ -182,8 +188,6 @@ void serializeSegment(JsonObject& root, WS2812FX::Segment& seg, byte id)
root["ix"] = seg.intensity; root["ix"] = seg.intensity;
root["pal"] = seg.palette; root["pal"] = seg.palette;
root["sel"] = seg.isSelected(); root["sel"] = seg.isSelected();
root["grp"] = seg.group;
root["spc"] = seg.spacing;
root["rev"] = seg.getOption(1); root["rev"] = seg.getOption(1);
} }
@ -257,7 +261,9 @@ void serializeInfo(JsonObject root)
JsonObject wifi_info = root.createNestedObject("wifi"); JsonObject wifi_info = root.createNestedObject("wifi");
wifi_info["bssid"] = WiFi.BSSIDstr(); wifi_info["bssid"] = WiFi.BSSIDstr();
wifi_info["signal"] = getSignalQuality(WiFi.RSSI()); int qrssi = WiFi.RSSI();
wifi_info["rssi"] = qrssi;
wifi_info["signal"] = getSignalQuality(qrssi);
wifi_info["channel"] = WiFi.channel(); wifi_info["channel"] = WiFi.channel();
#ifdef ARDUINO_ARCH_ESP32 #ifdef ARDUINO_ARCH_ESP32
@ -357,7 +363,7 @@ void serveJson(AsyncWebServerRequest* request)
void serveLiveLeds(AsyncWebServerRequest* request) void serveLiveLeds(AsyncWebServerRequest* request)
{ {
byte used = strip.getUsableCount(); byte used = ledCount;
byte n = (used -1) /MAX_LIVE_LEDS +1; //only serve every n'th LED if count over MAX_LIVE_LEDS byte n = (used -1) /MAX_LIVE_LEDS +1; //only serve every n'th LED if count over MAX_LIVE_LEDS
char buffer[2000] = "{\"leds\":["; char buffer[2000] = "{\"leds\":[";
olen = 9; olen = 9;