Bugfixes.

This commit is contained in:
Blaz Kristan 2022-07-19 16:16:43 +02:00
parent 6c6849d8d7
commit a46894f395
15 changed files with 2399 additions and 2320 deletions

View File

@ -103,7 +103,7 @@ class Animated_Staircase : public Usermod {
void updateSegments() {
mainSegmentId = strip.getMainSegmentId();
for (int i = 0; i < strip.getActiveSegmentsNum(); i++) {
for (int i = 0; i < strip.getSegmentsNum(); i++) {
Segment &seg = strip.getSegment(i);
if (!seg.isActive()) {
maxSegmentId = i - 1;
@ -289,7 +289,7 @@ class Animated_Staircase : public Usermod {
}
} else {
// Restore segment options
for (int i = 0; i < strip.getActiveSegmentsNum(); i++) {
for (int i = 0; i < strip.getSegmentsNum(); i++) {
Segment &seg = strip.getSegment(i);
if (!seg.isActive()) {
maxSegmentId = i - 1;

View File

@ -528,7 +528,7 @@ public:
effectCurrent = modes_alpha_indexes[effectCurrentIndex];
stateChanged = true;
if (applyToAll) {
for (byte i=0; i<strip.getActiveSegmentsNum(); i++) {
for (byte i=0; i<strip.getSegmentsNum(); i++) {
Segment& seg = strip.getSegment(i);
if (!seg.isActive()) continue;
strip.setMode(i, effectCurrent);
@ -556,7 +556,7 @@ public:
effectSpeed = max(min((increase ? effectSpeed+fadeAmount : effectSpeed-fadeAmount), 255), 0);
stateChanged = true;
if (applyToAll) {
for (byte i=0; i<strip.getActiveSegmentsNum(); i++) {
for (byte i=0; i<strip.getSegmentsNum(); i++) {
Segment& seg = strip.getSegment(i);
if (!seg.isActive()) continue;
seg.speed = effectSpeed;
@ -584,7 +584,7 @@ public:
effectIntensity = max(min((increase ? effectIntensity+fadeAmount : effectIntensity-fadeAmount), 255), 0);
stateChanged = true;
if (applyToAll) {
for (byte i=0; i<strip.getActiveSegmentsNum(); i++) {
for (byte i=0; i<strip.getSegmentsNum(); i++) {
Segment& seg = strip.getSegment(i);
if (!seg.isActive()) continue;
seg.intensity = effectIntensity;
@ -619,7 +619,7 @@ public:
case 2: val = sid.custom2 = max(min((increase ? sid.custom2+fadeAmount : sid.custom2-fadeAmount), 255), 0); break;
default: val = sid.custom1 = max(min((increase ? sid.custom1+fadeAmount : sid.custom1-fadeAmount), 255), 0); break;
}
for (byte i=0; i<strip.getActiveSegmentsNum(); i++) {
for (byte i=0; i<strip.getSegmentsNum(); i++) {
Segment& seg = strip.getSegment(i);
if (!seg.isActive() || i == id) continue;
switch (par) {
@ -658,7 +658,7 @@ public:
effectPalette = palettes_alpha_indexes[effectPaletteIndex];
stateChanged = true;
if (applyToAll) {
for (byte i=0; i<strip.getActiveSegmentsNum(); i++) {
for (byte i=0; i<strip.getSegmentsNum(); i++) {
Segment& seg = strip.getSegment(i);
if (!seg.isActive()) continue;
seg.palette = effectPalette;
@ -687,7 +687,7 @@ public:
colorHStoRGB(currentHue1*256, currentSat1, col);
stateChanged = true;
if (applyToAll) {
for (byte i=0; i<strip.getActiveSegmentsNum(); i++) {
for (byte i=0; i<strip.getSegmentsNum(); i++) {
Segment& seg = strip.getSegment(i);
if (!seg.isActive()) continue;
seg.colors[0] = RGBW32(col[0], col[1], col[2], col[3]);
@ -716,7 +716,7 @@ public:
currentSat1 = max(min((increase ? currentSat1+fadeAmount : currentSat1-fadeAmount), 255), 0);
colorHStoRGB(currentHue1*256, currentSat1, col);
if (applyToAll) {
for (byte i=0; i<strip.getActiveSegmentsNum(); i++) {
for (byte i=0; i<strip.getSegmentsNum(); i++) {
Segment& seg = strip.getSegment(i);
if (!seg.isActive()) continue;
seg.colors[0] = RGBW32(col[0], col[1], col[2], col[3]);
@ -776,7 +776,7 @@ public:
#endif
currentCCT = max(min((increase ? currentCCT+fadeAmount : currentCCT-fadeAmount), 255), 0);
// if (applyToAll) {
for (byte i=0; i<strip.getActiveSegmentsNum(); i++) {
for (byte i=0; i<strip.getSegmentsNum(); i++) {
Segment& seg = strip.getSegment(i);
if (!seg.isActive()) continue;
seg.setCCT(currentCCT);

View File

@ -426,39 +426,38 @@ typedef struct Segment {
public:
Segment(uint16_t sStart=0, uint16_t sStop=30) : start(sStart), stop(sStop) {
mode = DEFAULT_MODE;
colors[0] = DEFAULT_COLOR;
colors[1] = BLACK;
colors[2] = BLACK;
startY = 0;
stopY = 1;
speed = DEFAULT_SPEED;
intensity = DEFAULT_INTENSITY;
custom1 = DEFAULT_C1;
custom2 = DEFAULT_C2;
custom3 = DEFAULT_C3;
grouping = 1;
spacing = 0;
offset = 0;
opacity = 255;
cct = 127;
name = nullptr;
options = NO_OPTIONS;
setOption(SEG_OPTION_SELECTED, 1);
setOption(SEG_OPTION_ON, 1);
call = 0;
step = 0;
next_time = 0;
aux0 = 0;
aux1 = 0;
data = nullptr;
_dataLen = 0;
//_t = nullptr;
}
Segment(uint16_t sStart=0, uint16_t sStop=30) :
start(sStart),
stop(sStop),
offset(0),
speed(DEFAULT_SPEED),
intensity(DEFAULT_INTENSITY),
palette(0),
mode(DEFAULT_MODE),
options(SELECTED | SEGMENT_ON),
grouping(1),
spacing(0),
opacity(255),
colors{DEFAULT_COLOR,BLACK,BLACK},
cct(127),
custom1(DEFAULT_C1),
custom2(DEFAULT_C2),
custom3(DEFAULT_C3),
startY(0),
stopY(1),
name(nullptr),
next_time(0),
step(0),
call(0),
aux0(0),
aux1(0),
data(nullptr),
_capabilities(0),
_dataLen(0)
//_t(nullptr)
{}
Segment(uint16_t sStartX, uint16_t sStopX, uint16_t sStartY, uint16_t sStopY) {
Segment(sStartX, sStopX);
Segment(uint16_t sStartX, uint16_t sStopX, uint16_t sStartY, uint16_t sStopY) : Segment(sStartX, sStopX) {
startY = sStartY;
stopY = sStopY;
}
@ -467,8 +466,12 @@ typedef struct Segment {
Segment(Segment &&orig) noexcept; // move constructor
~Segment() {
Serial.print(F("Destroying segment: "));
if (name) Serial.println(name); else Serial.println();
#ifdef WLED_DEBUG
Serial.print(F("Destroying segment."));
if (name) Serial.printf(" %s (%p)", name, name);
if (data) Serial.printf(" %p", data);
Serial.println();
#endif
if (name) delete[] name;
//if (_t) delete _t;
deallocateData();
@ -495,8 +498,9 @@ typedef struct Segment {
// runtime data functions
bool allocateData(uint16_t len);
void deallocateData();
void resetIfRequired();
void deallocateData(void);
inline uint16_t dataSize(void) { return _dataLen; }
void resetIfRequired(void);
/**
* Flags that before the next effect is calculated,
* the internal segment state should be reset.
@ -581,7 +585,56 @@ class WS2812FX { // 96 bytes
public:
WS2812FX() {
WS2812FX() :
gammaCorrectBri(false),
gammaCorrectCol(true),
paletteFade(0),
paletteBlend(0),
milliampsPerLed(55),
cctBlending(0),
ablMilliampsMax(ABL_MILLIAMPS_DEFAULT),
currentMilliamps(0),
now(millis()),
timebase(0),
isMatrix(false),
#ifndef WLED_DISABLE_2D
hPanels(1),
vPanels(1),
panelH(8),
panelW(8),
matrixWidth(DEFAULT_LED_COUNT),
matrixHeight(1),
matrix{0,0,0,0},
panel{{0,0,0,0}},
#endif
currentPalette(CRGBPalette16(CRGB::Black)),
targetPalette(CloudColors_p),
_bri_t(0),
_colors_t{0,0,0},
_virtualSegmentLength(0),
_length(DEFAULT_LED_COUNT),
_rand16seed(0),
_brightness(DEFAULT_BRIGHTNESS),
_usedSegmentData(0),
_transitionDur(750),
_targetFps(WLED_FPS),
_frametime(FRAMETIME_FIXED),
_cumulativeFps(2),
_isServicing(false),
_isOffRefreshRequired(false),
_hasWhiteChannel(false),
_triggered(false),
_no_rgb(false),
_modeCount(MODE_COUNT),
_callback(nullptr),
customMappingTable(nullptr),
customMappingSize(0),
_lastPaletteChange(0),
_lastShow(0),
_segment_index(0),
_segment_index_palette_last(99),
_mainSegment(0)
{
WS2812FX::instance = this;
_mode.reserve(_modeCount);
_modeData.reserve(_modeCount);
@ -593,21 +646,15 @@ class WS2812FX { // 96 bytes
if (_mode && _modeData) setupEffectData();
else _modeCount = 1; // only Solid will work
*/
_brightness = DEFAULT_BRIGHTNESS;
currentPalette = CRGBPalette16(CRGB::Black);
targetPalette = CloudColors_p;
ablMilliampsMax = ABL_MILLIAMPS_DEFAULT;
currentMilliamps = 0;
timebase = 0;
_usedSegmentData = 0;
//resetSegments(); // no need here
}
~WS2812FX() {
if (customMappingTable) delete[] customMappingTable;
//delete[] _mode;
//delete[] _modeData;
_mode.clear();
_modeData.clear();
_segments.clear();
}
static WS2812FX* getInstance(void) { return instance; }
@ -649,23 +696,24 @@ class WS2812FX { // 96 bytes
inline void addUsedSegmentData(int16_t size) { _usedSegmentData += size; }
bool
gammaCorrectBri = false,
gammaCorrectCol = true,
gammaCorrectBri,
gammaCorrectCol,
checkSegmentAlignment(void),
hasRGBWBus(void),
hasCCTBus(void),
// return true if the strip is being sent pixel updates
isUpdating(void);
inline bool isServicing(void) { return _isServicing; }
inline bool hasWhiteChannel(void) {return _hasWhiteChannel;}
inline bool isOffRefreshRequired(void) {return _isOffRefreshRequired;}
uint8_t
paletteFade = 0,
paletteBlend = 0,
milliampsPerLed = 55,
cctBlending = 0,
//getActiveSegmentsNum(void),
paletteFade,
paletteBlend,
milliampsPerLed,
cctBlending,
getActiveSegmentsNum(void),
getFirstSelectedSegId(void),
getLastActiveSegmentId(void),
setPixelSegment(uint8_t n),
@ -674,7 +722,7 @@ class WS2812FX { // 96 bytes
inline uint8_t getBrightness(void) { return _brightness; }
inline uint8_t getMaxSegments(void) { return MAX_NUM_SEGMENTS; } // returns maximum number of supported segments (fixed value)
inline uint8_t getActiveSegmentsNum(void) { return _segments.size(); } // returns currently active (present) segments
inline uint8_t getSegmentsNum(void) { return _segments.size(); } // returns currently present segments
inline uint8_t getCurrSegmentId(void) { return _segment_index; }
inline uint8_t getMainSegmentId(void) { return _mainSegment; }
inline uint8_t getPaletteCount() { return 13 + GRADIENT_PALETTE_COUNT; }
@ -709,27 +757,26 @@ class WS2812FX { // 96 bytes
const char **
getModeDataSrc(void) { return &(_modeData[0]); } // vectors use arrays for underlying data
//inline Segment& getSegment(uint8_t id) { return _segments[id >= getMaxSegments() ? getMainSegmentId() : id]; }
inline Segment& getSegment(uint8_t id) { return _segments[id >= _segments.size() ? getMainSegmentId() : id]; } // vectors
Segment& getSegment(uint8_t id);
inline Segment& getFirstSelectedSeg(void) { return _segments[getFirstSelectedSegId()]; }
inline Segment& getMainSegment(void) { return _segments[getMainSegmentId()]; }
inline Segment* getSegments(void) { return &(_segments[0]); }
// 2D support (panels)
bool
isMatrix = false;
isMatrix;
#ifndef WLED_DISABLE_2D
#define WLED_MAX_PANELS 64
uint8_t
hPanels = 1,
vPanels = 1;
hPanels,
vPanels;
uint16_t
panelH = 8,
panelW = 8,
matrixWidth = DEFAULT_LED_COUNT,
matrixHeight = 1;
panelH,
panelW,
matrixWidth,
matrixHeight;
typedef struct panel_bitfield_t {
unsigned char
@ -739,8 +786,8 @@ class WS2812FX { // 96 bytes
serpentine : 1; // is serpentine?
} Panel;
Panel
matrix = {0,0,0,0},
panel[WLED_MAX_PANELS] = {{0,0,0,0}};
matrix,
panel[WLED_MAX_PANELS];
#endif
void
@ -776,37 +823,43 @@ class WS2812FX { // 96 bytes
uint16_t _rand16seed;
uint8_t _brightness;
uint16_t _usedSegmentData;
uint16_t _transitionDur = 750;
uint16_t _transitionDur;
uint8_t _targetFps = 42;
uint16_t _frametime = (1000/42);
uint16_t _cumulativeFps = 2;
uint8_t _targetFps;
uint16_t _frametime;
uint16_t _cumulativeFps;
// will require only 1 byte
// struct {
// byte _isServicing : 1;
// byte _isOffRefreshRequired : 1;
// byte _hasWhiteChannel : 1;
// byte _triggered : 1;
// byte _no_rgb : 1;
// };
bool
_isOffRefreshRequired = false, //periodic refresh is required for the strip to remain off.
_hasWhiteChannel = false,
_triggered;
_isServicing,
_isOffRefreshRequired, //periodic refresh is required for the strip to remain off.
_hasWhiteChannel,
_triggered,
_no_rgb;
uint8_t _modeCount = MODE_COUNT;
uint8_t _modeCount;
//mode_ptr *_mode; // SRAM footprint: 4 bytes per element
//const char **_modeData; // mode (effect) name and its slider control data array
std::vector<mode_ptr> _mode; // SRAM footprint: 4 bytes per element
std::vector<const char*> _modeData; // mode (effect) name and its slider control data array
//std::vector<ModeData> _modes; // this will require substantial rewrite of code
show_callback _callback;
show_callback _callback = nullptr;
uint16_t* customMappingTable;
uint16_t customMappingSize;
uint16_t* customMappingTable = nullptr;
uint16_t customMappingSize = 0;
uint32_t _lastPaletteChange;
uint32_t _lastShow;
uint32_t _lastPaletteChange = 0;
uint32_t _lastShow = 0;
bool _no_rgb = false;
uint8_t _segment_index = 0;
uint8_t _segment_index_palette_last = 99;
uint8_t _segment_index;
uint8_t _segment_index_palette_last;
uint8_t _mainSegment;
void

View File

@ -93,13 +93,17 @@ Segment::Segment(Segment &&orig) noexcept {
memcpy(this, &orig, sizeof(Segment));
orig.name = nullptr;
orig.data = nullptr;
orig._dataLen = 0;
//orig._t = nullptr;
}
Segment& Segment::operator= (const Segment &orig) {
DEBUG_PRINTLN(F("-- Segment copied --"));
if (this != &orig) {
if (name) delete[] name;
if (name) {
DEBUG_PRINTF(" Copy Deleting %s (%p)\n", name, name);
delete[] name;
}
//if (_t) delete _t;
deallocateData();
memcpy(this, &orig, sizeof(Segment));
@ -110,8 +114,8 @@ Segment& Segment::operator= (const Segment &orig) {
if (orig.name) { name = new char[strlen(orig.name)+1]; if (name) strcpy(name, orig.name); }
if (orig.data) { allocateData(orig._dataLen); memcpy(data, orig.data, orig._dataLen); }
//if (orig._t) { _t = new Transition(orig._t->_dur, orig._t->_briT, orig._t->_cctT, orig._t->_colorT); }
DEBUG_PRINTF(" Copied data: %p (%d)\n", orig.data, (int)orig._dataLen);
DEBUG_PRINTF(" New data: %p (%d)\n", data, (int)_dataLen);
DEBUG_PRINTF(" Original data: %p (%d)\n", orig.data, (int)orig._dataLen);
DEBUG_PRINTF(" Copied data: %p (%d)\n", data, (int)_dataLen);
}
return *this;
}
@ -119,12 +123,16 @@ Segment& Segment::operator= (const Segment &orig) {
Segment& Segment::operator= (Segment &&orig) noexcept {
DEBUG_PRINTLN(F("-- Moving segment --"));
if (this != &orig) {
if (name) delete[] name; // free old name
if (name) {
DEBUG_PRINTF(" Move Deleting %s (%p)\n", name, name);
delete[] name; // free old name
}
//if (_t) delete _t;
deallocateData(); // free old runtime data
memcpy(this, &orig, sizeof(Segment));
orig.name = nullptr;
orig.data = nullptr;
orig._dataLen = 0;
//orig._t = nullptr;
}
return *this;
@ -132,8 +140,8 @@ Segment& Segment::operator= (Segment &&orig) noexcept {
bool Segment::allocateData(uint16_t len) {
if (data && _dataLen == len) return true; //already allocated
DEBUG_PRINTF("-- Allocating data (size:%d) --\n", len);
deallocateData();
// TODO: move out to WS2812FX class: for (seg : _segments) sum += seg.dataSize();
if (strip.getUsedSegmentData() + len > MAX_SEGMENT_DATA) return false; //not enough memory
// if possible use SPI RAM on ESP32
#if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_PSRAM)
@ -143,19 +151,23 @@ bool Segment::allocateData(uint16_t len) {
#endif
data = (byte*) malloc(len);
if (!data) return false; //allocation failed
strip.addUsedSegmentData(len);
strip.addUsedSegmentData(len); // TODO: move out to WS2812FX class: for (seg : _segments) sum += seg.dataSize();
_dataLen = len;
memset(data, 0, len);
DEBUG_PRINTF("-- Allocated data %p (%d)\n", data, (int)len);
return true;
}
void Segment::deallocateData() {
// NOTE: deallocating data sometimes produces corrupt heap.
if (!data) return;
DEBUG_PRINTF("-- Deallocating data: %p (%d) --\n", data, (int)_dataLen);
DEBUG_PRINTF("-- Deallocating data: %p (%d)\n", data, (int)_dataLen);
free(data);
DEBUG_PRINTLN(F("-- Data freed."));
data = nullptr;
strip.addUsedSegmentData(-(int16_t)_dataLen);
strip.addUsedSegmentData(-(int16_t)_dataLen); // TODO: move out to WS2812FX class: for (seg : _segments) sum -= seg.dataSize();
_dataLen = 0;
DEBUG_PRINTLN(F("-- Dealocated data."));
}
/**
@ -168,7 +180,6 @@ void Segment::deallocateData() {
void Segment::resetIfRequired() {
if (reset) { // (getOption(SEG_OPTION_RESET))
next_time = 0; step = 0; call = 0; aux0 = 0; aux1 = 0;
deallocateData();
reset = false; // setOption(SEG_OPTION_RESET, false);
}
}
@ -653,12 +664,12 @@ void WS2812FX::service() {
if (nowUp - _lastShow < MIN_SHOW_DELAY) return;
bool doShow = false;
_isServicing = true;
_segment_index = 0;
for (segment &seg : _segments) {
// for (int i = 0; i < getMaxSegments(); i++) {
// Segment &seg = getSegment(i);
// reset the segment runtime data if needed, called before isActive to ensure deleted
// segment's buffers are cleared
// reset the segment runtime data if needed
seg.resetIfRequired();
if (!seg.isActive()) continue;
@ -700,6 +711,7 @@ void WS2812FX::service() {
show();
}
_triggered = false;
_isServicing = false;
}
void WS2812FX::setPixelColor(int i, uint32_t col)
@ -987,13 +999,14 @@ uint8_t WS2812FX::getLastActiveSegmentId(void) {
return _segments.size()-1;
}
//uint8_t WS2812FX::getActiveSegmentsNum(void) {
// uint8_t c = 0;
uint8_t WS2812FX::getActiveSegmentsNum(void) {
uint8_t c = 0;
// for (uint8_t i = 0; i < getMaxSegments(); i++) {
// if (_segments[i].isActive()) c++;
// }
// return c;
//}
for (int i = 0; i < _segments.size(); i++) {
if (_segments[i].isActive()) c++;
}
return c;
}
uint16_t WS2812FX::getLengthPhysical(void) {
uint16_t len = 0;
@ -1037,17 +1050,26 @@ bool WS2812FX::hasCCTBus(void) {
}
void WS2812FX::purgeSegments(void) {
// remove inactive segments at the back
//while (_segments.back().stop == 0 && _segments.size() > 1) _segments.pop_back();
// remove all inactive segments (from the back)
int deleted = 0;
for (int i = _segments.size()-1; i > 0; i--) if (_segments[i].stop == 0) { DEBUG_PRINT(F(" Removing segment: ")); DEBUG_PRINTLN(i); deleted++; _segments.erase(_segments.begin() + i); }
if (_segments.size() <= 1 || _isServicing) return;
for (int i = _segments.size()-1; i > 0; i--)
if (_segments[i].stop == 0) {
DEBUG_PRINT(F("-- Removing segment: ")); DEBUG_PRINTLN(i);
deleted++;
_segments.erase(_segments.begin() + i);
}
if (deleted) {
_segments.shrink_to_fit();
if (_mainSegment >= _segments.size()) setMainSegmentId(0);
}
}
Segment& WS2812FX::getSegment(uint8_t id) {
// return _segments[id >= getMaxSegments() ? getMainSegmentId() : id];
return _segments[id >= _segments.size() ? getMainSegmentId() : id]; // vectors
}
void WS2812FX::setSegment(uint8_t n, uint16_t i1, uint16_t i2, uint8_t grouping, uint8_t spacing, uint16_t offset, uint16_t startY, uint16_t stopY) {
if (n >= _segments.size()) return;
// if (n >= getMaxSegments()) return;
@ -1067,12 +1089,12 @@ void WS2812FX::setSegment(uint8_t n, uint16_t i1, uint16_t i2, uint8_t grouping,
if (i2 <= i1) //disable segment
{
// disabled segments should get removed using purgeSegments()
DEBUG_PRINTLN(F(" Segment marked inactive."));
DEBUG_PRINT(F("-- Segment ")); DEBUG_PRINT(n); DEBUG_PRINTLN(F(" marked inactive."));
seg.stop = 0;
if (seg.name) {
delete[] seg.name;
seg.name = nullptr;
}
//if (seg.name) {
// delete[] seg.name;
// seg.name = nullptr;
//}
// if main segment is deleted, set first active as main segment
if (n == _mainSegment) setMainSegmentId(0);
seg.markForReset();
@ -1216,9 +1238,8 @@ void WS2812FX::makeAutoSegments(bool forceReset) {
void WS2812FX::fixInvalidSegments() {
//make sure no segment is longer than total (sanity check)
size_t i = 0;
for (std::vector<Segment>::iterator it = _segments.begin(); it != _segments.end(); i++, it++) {
if (_segments[i].start >= _length) { _segments.erase(it); i--; it--; continue; }
for (int i = _segments.size()-1; i > 0; i--) {
if (_segments[i].start >= _length) { _segments.erase(_segments.begin()+i); continue; }
if (_segments[i].stop > _length) _segments[i].stop = _length;
// this is always called as the last step after finalizeInit(), update covered bus types
_segments[i].refreshLightCapabilities();

View File

@ -1179,7 +1179,8 @@ function makeWS() {
function readState(s,command=false)
{
if (!s) return false;
if (!s || s.error) return false;
if (s.success) return true; // no data to process
isOn = s.on;
gId('sliderBri').value = s.bri;
@ -1224,7 +1225,7 @@ function readState(s,command=false)
if (!i) {
showToast('No Segments!', true);
updateUI();
return;
return true;
}
var cd = gId('csl').children;
@ -1271,6 +1272,7 @@ function readState(s,command=false)
selectedFx = i.fx;
redrawPalPrev(); // if any color changed (random palette did at least)
updateUI();
return true;
}
// WLEDSR: control HTML elements for Slider and Color Control

File diff suppressed because it is too large Load Diff

View File

@ -89,7 +89,7 @@ byte relativeChange(byte property, int8_t amount, byte lowerBoundary, byte highe
void changeEffect(uint8_t fx)
{
if (irApplyToAllSelected) {
for (uint8_t i = 0; i < strip.getActiveSegmentsNum(); i++) {
for (uint8_t i = 0; i < strip.getSegmentsNum(); i++) {
Segment& seg = strip.getSegment(i);
if (!seg.isActive() || !seg.isSelected()) continue;
strip.setMode(i, fx);
@ -105,7 +105,7 @@ void changeEffect(uint8_t fx)
void changePalette(uint8_t pal)
{
if (irApplyToAllSelected) {
for (uint8_t i = 0; i < strip.getActiveSegmentsNum(); i++) {
for (uint8_t i = 0; i < strip.getSegmentsNum(); i++) {
Segment& seg = strip.getSegment(i);
if (!seg.isActive() || !seg.isSelected()) continue;
seg.palette = pal;
@ -124,7 +124,7 @@ void changeEffectSpeed(int8_t amount)
int16_t new_val = (int16_t) effectSpeed + amount;
effectSpeed = (byte)constrain(new_val,0,255);
if (irApplyToAllSelected) {
for (uint8_t i = 0; i < strip.getActiveSegmentsNum(); i++) {
for (uint8_t i = 0; i < strip.getSegmentsNum(); i++) {
Segment& seg = strip.getSegment(i);
if (!seg.isActive() || !seg.isSelected()) continue;
seg.speed = effectSpeed;
@ -147,7 +147,7 @@ void changeEffectSpeed(int8_t amount)
prim_hsv.h = (byte)new_val;
hsv2rgb_rainbow(prim_hsv, fastled_col);
if (irApplyToAllSelected) {
for (uint8_t i = 0; i < strip.getActiveSegmentsNum(); i++) {
for (uint8_t i = 0; i < strip.getSegmentsNum(); i++) {
Segment& seg = strip.getSegment(i);
if (!seg.isActive() || !seg.isSelected()) continue;
seg.colors[0] = RGBW32(fastled_col.red, fastled_col.green, fastled_col.blue, W(sseg.colors[0]));
@ -171,7 +171,7 @@ void changeEffectIntensity(int8_t amount)
int16_t new_val = (int16_t) effectIntensity + amount;
effectIntensity = (byte)constrain(new_val,0,255);
if (irApplyToAllSelected) {
for (uint8_t i = 0; i < strip.getActiveSegmentsNum(); i++) {
for (uint8_t i = 0; i < strip.getSegmentsNum(); i++) {
Segment& seg = strip.getSegment(i);
if (!seg.isActive() || !seg.isSelected()) continue;
seg.intensity = effectIntensity;
@ -192,7 +192,7 @@ void changeEffectIntensity(int8_t amount)
prim_hsv.s = (byte)constrain(new_val,0,255); // constrain to 0-255
hsv2rgb_rainbow(prim_hsv, fastled_col);
if (irApplyToAllSelected) {
for (uint8_t i = 0; i < strip.getActiveSegmentsNum(); i++) {
for (uint8_t i = 0; i < strip.getSegmentsNum(); i++) {
Segment& seg = strip.getSegment(i);
if (!seg.isActive() || !seg.isSelected()) continue;
seg.colors[0] = RGBW32(fastled_col.red, fastled_col.green, fastled_col.blue, W(sseg.colors[0]));
@ -214,7 +214,7 @@ void changeColor(uint32_t c, int16_t cct=-1)
{
if (irApplyToAllSelected) {
// main segment may not be selected!
for (uint8_t i = 0; i < strip.getActiveSegmentsNum(); i++) {
for (uint8_t i = 0; i < strip.getSegmentsNum(); i++) {
Segment& seg = strip.getSegment(i);
if (!seg.isActive() || !seg.isSelected()) continue;
byte capabilities = seg.getLightCapabilities();

View File

@ -14,11 +14,10 @@ void deserializeSegment(JsonObject elem, byte it, byte presetId)
int stop = elem["stop"] | -1;
// if using vectors use this code to append segment
if (id >= strip.getActiveSegmentsNum()) {
if (id >= strip.getSegmentsNum()) {
if (stop <= 0) return; // ignore empty/inactive segments
DEBUG_PRINT(F("Adding segment: ")); DEBUG_PRINTLN(id);
strip.appendSegment(Segment(0, strip.getLengthTotal()));
id = strip.getActiveSegmentsNum()-1; // segments are added at the end of list
id = strip.getSegmentsNum()-1; // segments are added at the end of list
}
Segment& seg = strip.getSegment(id);
@ -258,7 +257,7 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId)
if (root["on"].is<const char*>() && root["on"].as<const char*>()[0] == 't') toggleOnOff();
if (bri && !onBefore) { // unfreeze all segments when turning on
for (uint8_t s=0; s < strip.getActiveSegmentsNum(); s++) {
for (uint8_t s=0; s < strip.getSegmentsNum(); s++) {
strip.getSegment(s).setOption(SEG_OPTION_FREEZE, false);
}
if (realtimeMode && !realtimeOverride && useMainSegmentOnly) { // keep live segment frozen if live
@ -336,7 +335,7 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId)
if (id < 0) {
//apply all selected segments
//bool didSet = false;
for (byte s = 0; s < strip.getActiveSegmentsNum(); s++) {
for (byte s = 0; s < strip.getSegmentsNum(); s++) {
Segment &sg = strip.getSegment(s);
if (sg.isSelected()) {
deserializeSegment(segVar, s, presetId);
@ -350,14 +349,10 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId)
}
} else {
JsonArray segs = segVar.as<JsonArray>();
for (JsonObject elem : segs)
{
DEBUG_PRINT(F(" Deserializing segment: ")); DEBUG_PRINTLN(it);
for (JsonObject elem : segs) {
deserializeSegment(elem, it, presetId);
it++;
}
// DEBUG_PRINTLN(F(" Purging segments."));
// strip.purgeSegments(); // prune inactive segments (resets ESP if effect running)
}
usermods.readFromJsonState(root);
@ -505,7 +500,7 @@ void serializeState(JsonObject root, bool forPreset, bool includeBri, bool segme
bool selectedSegmentsOnly = root[F("sc")] | false;
JsonArray seg = root.createNestedArray("seg");
for (byte s = 0; s < strip.getMaxSegments(); s++) {
if (s >= strip.getActiveSegmentsNum()) {
if (s >= strip.getSegmentsNum()) {
if (forPreset && segmentBounds) { //disable segments not part of preset
JsonObject seg0 = seg.createNestedObject();
seg0["stop"] = 0;
@ -537,7 +532,7 @@ void serializeInfo(JsonObject root)
leds["fps"] = strip.getFps();
leds[F("maxpwr")] = (strip.currentMilliamps)? strip.ablMilliampsMax : 0;
leds[F("maxseg")] = strip.getMaxSegments();
leds[F("actseg")] = strip.getActiveSegmentsNum();
//leds[F("actseg")] = strip.getActiveSegmentsNum();
//leds[F("seglock")] = false; //might be used in the future to prevent modifications to segment config
#ifndef WLED_DISABLE_2D

View File

@ -31,7 +31,7 @@ void applyValuesToSelectedSegs()
// copy of first selected segment to tell if value was updated
uint8_t firstSel = strip.getFirstSelectedSegId();
Segment selsegPrev = strip.getSegment(firstSel);
for (uint8_t i = 0; i < strip.getActiveSegmentsNum(); i++) {
for (uint8_t i = 0; i < strip.getSegmentsNum(); i++) {
Segment& seg = strip.getSegment(i);
if (i != firstSel && (!seg.isActive() || !seg.isSelected())) continue;

View File

@ -608,7 +608,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
pos = req.indexOf(F("SS="));
if (pos > 0) {
byte t = getNumVal(&req, pos);
if (t < strip.getActiveSegmentsNum()) {
if (t < strip.getSegmentsNum()) {
selectedSeg = t;
singleSegment = true;
}
@ -618,7 +618,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
pos = req.indexOf(F("SV=")); //segment selected
if (pos > 0) {
byte t = getNumVal(&req, pos);
if (t == 2) for (uint8_t i = 0; i < strip.getActiveSegmentsNum(); i++) strip.getSegment(i).setOption(SEG_OPTION_SELECTED, 0); // unselect other segments
if (t == 2) for (uint8_t i = 0; i < strip.getSegmentsNum(); i++) strip.getSegment(i).setOption(SEG_OPTION_SELECTED, 0); // unselect other segments
selseg.setOption(SEG_OPTION_SELECTED, t);
}
@ -824,7 +824,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
stateChanged |= (fxModeChanged || speedChanged || intensityChanged || paletteChanged);
// apply to main and all selected segments to prevent #1618.
for (uint8_t i = 0; i < strip.getActiveSegmentsNum(); i++) {
for (uint8_t i = 0; i < strip.getSegmentsNum(); i++) {
Segment& seg = strip.getSegment(i);
if (i != selectedSeg && (singleSegment || !seg.isActive() || !seg.isSelected())) continue; // skip non main segments if not applying to all
if (fxModeChanged) strip.setMode(i, effectIn);

View File

@ -91,10 +91,12 @@ void notify(byte callMode, bool followUp)
udpOut[39] = strip.getActiveSegmentsNum();
udpOut[40] = UDP_SEG_SIZE; //size of each loop iteration (one segment)
for (uint8_t i = 0; i < strip.getActiveSegmentsNum(); i++) {
int s = 0;
for (uint8_t i = 0; i < strip.getSegmentsNum(); i++) {
Segment &selseg = strip.getSegment(i);
uint16_t ofs = 41 + i*UDP_SEG_SIZE; //start of segment offset byte
udpOut[0 +ofs] = i;
if (!selseg.isActive()) continue;
uint16_t ofs = 41 + s*UDP_SEG_SIZE; //start of segment offset byte
udpOut[0 +ofs] = s;
udpOut[1 +ofs] = selseg.start >> 8;
udpOut[2 +ofs] = selseg.start & 0xFF;
udpOut[3 +ofs] = selseg.stop >> 8;
@ -122,6 +124,7 @@ void notify(byte callMode, bool followUp)
udpOut[25+ofs] = B(selseg.colors[2]);
udpOut[26+ofs] = W(selseg.colors[2]);
udpOut[27+ofs] = selseg.cct;
++s;
}
//uint16_t offs = SEG_OFFSET;
@ -155,7 +158,7 @@ void realtimeLock(uint32_t timeoutMs, byte md)
for (uint16_t i = start; i < stop; i++) strip.setPixelColor(i,0,0,0,0);
// if WLED was off and using main segment only, freeze non-main segments so they stay off
if (useMainSegmentOnly && bri == 0) {
for (uint8_t s=0; s < strip.getActiveSegmentsNum(); s++) {
for (uint8_t s=0; s < strip.getSegmentsNum(); s++) {
strip.getSegment(s).setOption(SEG_OPTION_FREEZE, true);
}
}
@ -342,7 +345,7 @@ void handleNotifications()
for (uint8_t i = 0; i < numSrcSegs; i++) {
uint16_t ofs = 41 + i*udpIn[40]; //start of segment offset byte
uint8_t id = udpIn[0 +ofs];
if (id > strip.getActiveSegmentsNum()) break;
if (id > strip.getSegmentsNum()) break;
Segment& selseg = strip.getSegment(id);
uint16_t start = (udpIn[1+ofs] << 8 | udpIn[2+ofs]);
uint16_t stop = (udpIn[3+ofs] << 8 | udpIn[4+ofs]);
@ -377,7 +380,7 @@ void handleNotifications()
// simple effect sync, applies to all selected segments
if (applyEffects && (version < 11 || !receiveSegmentOptions)) {
for (uint8_t i = 0; i < strip.getActiveSegmentsNum(); i++) {
for (uint8_t i = 0; i < strip.getSegmentsNum(); i++) {
Segment& seg = strip.getSegment(i);
if (!seg.isActive() || !seg.isSelected()) continue;
if (udpIn[8] < strip.getModeCount()) strip.setMode(i, udpIn[8]);

View File

@ -118,7 +118,6 @@ void WLED::loop()
if (stripMillis > maxStripMillis) maxStripMillis = stripMillis;
#endif
}
if (offMode) strip.purgeSegments(); // remove inactive segments from memory (no effects running)
yield();
#ifdef ESP8266
@ -694,6 +693,7 @@ void WLED::handleConnection()
DEBUG_PRINT(F("Heap too low! "));
DEBUG_PRINTLN(heap);
forceReconnect = true;
strip.purgeSegments(); // remove inactive segments from memory
}
lastHeap = heap;
heapTime = now;

View File

@ -8,7 +8,7 @@
*/
// version code in format yymmddb (b = daily build)
#define VERSION 2207171
#define VERSION 2207191
//uncomment this if you have a "my_config.h" file you'd like to use
//#define WLED_USE_MY_CONFIG

View File

@ -58,6 +58,10 @@ void wsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventTyp
if (verboseResponse) {
sendDataWs(client);
lastInterfaceUpdate = millis() - (INTERFACE_UPDATE_COOLDOWN -500);
} else {
// we have to send something back otherwise WS connection closes
client->text(F("{\"success\":true}"));
lastInterfaceUpdate = millis() - (INTERFACE_UPDATE_COOLDOWN -500);
}
}
} else {