Combat low memory condition on ESP8266.

This commit is contained in:
Blaz Kristan 2023-03-10 15:20:50 +01:00
parent ddd32bd600
commit 763b64cc57
4 changed files with 22 additions and 12 deletions

View File

@ -184,7 +184,8 @@ void Segment::deallocateData() {
void Segment::resetIfRequired() {
if (reset) {
if (leds && !Segment::_globalLeds) { free(leds); leds = nullptr; }
//if (_t) { delete _t; _t = nullptr; transitional = false; }
if (transitional && _t) { transitional = false; delete _t; _t = nullptr; }
deallocateData();
next_time = 0; step = 0; call = 0; aux0 = 0; aux1 = 0;
reset = false; // setOption(SEG_OPTION_RESET, false);
}
@ -1385,7 +1386,6 @@ void WS2812FX::purgeSegments(bool force) {
if (_segments.size() <= 1) return;
for (size_t i = _segments.size()-1; i > 0; i--)
if (_segments[i].stop == 0 || force) {
DEBUG_PRINT(F("Purging segment segment: ")); DEBUG_PRINTLN(i);
deleted++;
_segments.erase(_segments.begin() + i);
}

View File

@ -124,7 +124,7 @@ void handleIR();
#include "src/dependencies/json/AsyncJson-v6.h"
#include "FX.h"
void deserializeSegment(JsonObject elem, byte it, byte presetId = 0);
bool deserializeSegment(JsonObject elem, byte it, byte presetId = 0);
bool deserializeState(JsonObject root, byte callMode = CALL_MODE_DIRECT_CHANGE, byte presetId = 0);
void serializeSegment(JsonObject& root, Segment& seg, byte id, bool forPreset = false, bool segmentBounds = true);
void serializeState(JsonObject root, bool forPreset = false, bool includeBri = true, bool segmentBounds = true, bool selectedSegmentsOnly = false);

View File

@ -14,16 +14,16 @@
* JSON API (De)serialization
*/
void deserializeSegment(JsonObject elem, byte it, byte presetId)
bool deserializeSegment(JsonObject elem, byte it, byte presetId)
{
byte id = elem["id"] | it;
if (id >= strip.getMaxSegments()) return;
if (id >= strip.getMaxSegments()) return false;
int stop = elem["stop"] | -1;
// if using vectors use this code to append segment
if (id >= strip.getSegmentsNum()) {
if (stop <= 0) return; // ignore empty/inactive segments
if (stop <= 0) return false; // ignore empty/inactive segments
strip.appendSegment(Segment(0, strip.getLengthTotal()));
id = strip.getSegmentsNum()-1; // segments are added at the end of list
}
@ -56,7 +56,7 @@ void deserializeSegment(JsonObject elem, byte it, byte presetId)
elem["rev"] = !elem["rev"]; // alternate reverse on even/odd segments
deserializeSegment(elem, i, presetId); // recursive call with new id
}
return;
return true;
}
if (elem["n"]) {
@ -107,7 +107,7 @@ void deserializeSegment(JsonObject elem, byte it, byte presetId)
if (stop > start && of > len -1) of = len -1;
seg.set(start, stop, grp, spc, of, startY, stopY);
if (seg.reset && seg.stop == 0) return; // segment was deleted & is marked for reset, no need to change anything else
if (seg.reset && seg.stop == 0) return true; // segment was deleted & is marked for reset, no need to change anything else
byte segbri = seg.opacity;
if (getVal(elem["bri"], &segbri)) {
@ -264,6 +264,8 @@ void deserializeSegment(JsonObject elem, byte it, byte presetId)
}
// send UDP/WS if segment options changed (except selection; will also deselect current preset)
if (seg.differs(prev) & 0x7F) stateChanged = true;
return true;
}
// deserializes WLED state (fileDoc points to doc object if called from web server)
@ -379,11 +381,12 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId)
deserializeSegment(segVar, id, presetId); //apply only the segment with the specified ID
}
} else {
size_t deleted = 0;
JsonArray segs = segVar.as<JsonArray>();
for (JsonObject elem : segs) {
deserializeSegment(elem, it, presetId);
it++;
if (deserializeSegment(elem, it++, presetId) && !elem["stop"].isNull() && elem["stop"]==0) deleted++;
}
if (strip.getSegmentsNum() > 3 && deleted >= strip.getSegmentsNum()/2U) strip.purgeSegments(); // batch deleting more than half segments
}
usermods.readFromJsonState(root);

View File

@ -316,8 +316,7 @@ void WLED::setup()
DEBUG_PRINT(F("esp8266 "));
DEBUG_PRINTLN(ESP.getCoreVersion());
#endif
DEBUG_PRINT(F("heap "));
DEBUG_PRINTLN(ESP.getFreeHeap());
DEBUG_PRINT(F("heap ")); DEBUG_PRINTLN(ESP.getFreeHeap());
#if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_PSRAM)
if (psramFound()) {
@ -352,6 +351,8 @@ void WLED::setup()
DEBUG_PRINTLN(F("Registering usermods ..."));
registerUsermods();
DEBUG_PRINT(F("heap ")); DEBUG_PRINTLN(ESP.getFreeHeap());
for (uint8_t i=1; i<WLED_MAX_BUTTONS; i++) btnPin[i] = -1;
bool fsinit = false;
@ -392,10 +393,12 @@ void WLED::setup()
DEBUG_PRINTLN(F("Initializing strip"));
beginStrip();
DEBUG_PRINT(F("heap ")); DEBUG_PRINTLN(ESP.getFreeHeap());
DEBUG_PRINTLN(F("Usermods setup"));
userSetup();
usermods.setup();
DEBUG_PRINT(F("heap ")); DEBUG_PRINTLN(ESP.getFreeHeap());
if (strcmp(clientSSID, DEFAULT_CLIENT_SSID) == 0)
showWelcomePage = true;
@ -451,7 +454,9 @@ void WLED::setup()
#endif
// HTTP server page init
DEBUG_PRINTLN(F("initServer"));
initServer();
DEBUG_PRINT(F("heap ")); DEBUG_PRINTLN(ESP.getFreeHeap());
enableWatchdog();
@ -747,6 +752,8 @@ void WLED::handleConnection()
DEBUG_PRINTLN(heap);
forceReconnect = true;
strip.purgeSegments(true); // remove all but one segments from memory
} else if (heap < MIN_HEAP_SIZE) {
strip.purgeSegments();
}
lastHeap = heap;
heapTime = now;