From 2cc67245cab8437b0577a3603d44d9aa3db83c22 Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Fri, 23 Feb 2024 10:54:50 +0100 Subject: [PATCH] avoid infinite disconnect loops when RAM is low --- wled00/const.h | 1 + wled00/data/index.js | 3 +++ wled00/wled.cpp | 37 +++++++++++++++++++++++++++---------- wled00/wled.h | 2 +- 4 files changed, 32 insertions(+), 11 deletions(-) diff --git a/wled00/const.h b/wled00/const.h index 4492f631..ae97beef 100644 --- a/wled00/const.h +++ b/wled00/const.h @@ -344,6 +344,7 @@ #define ERR_OVERTEMP 30 // An attached temperature sensor has measured above threshold temperature (not implemented) #define ERR_OVERCURRENT 31 // An attached current sensor has measured a current above the threshold (not implemented) #define ERR_UNDERVOLT 32 // An attached voltmeter has measured a voltage below the threshold (not implemented) +#define ERR_LOW_MEM 33 // low memory (RAM) // Timer mode types #define NL_MODE_SET 0 //After nightlight time elapsed, set to target brightness diff --git a/wled00/data/index.js b/wled00/data/index.js index 783424ff..c8159d9e 100644 --- a/wled00/data/index.js +++ b/wled00/data/index.js @@ -1967,6 +1967,9 @@ function readState(s,command=false) case 19: errstr = "A filesystem error has occured."; break; + case 33: + errstr = "Warning: Low Memory (RAM)."; + break; } showToast('Error ' + s.error + ": " + errstr, true); } diff --git a/wled00/wled.cpp b/wled00/wled.cpp index a5a93430..3bdd3297 100644 --- a/wled00/wled.cpp +++ b/wled00/wled.cpp @@ -1205,6 +1205,7 @@ void WLED::handleConnection() return; } + static unsigned retryCount = 0; // WLEDMM #ifdef ARDUINO_ARCH_ESP32 // reconnect WiFi to clear stale allocations if heap gets too low if (now - heapTime > 5000) { // WLEDMM: updated with better logic for small heap available by block, not total. @@ -1214,10 +1215,16 @@ void WLED::handleConnection() uint32_t heap = heap_caps_get_largest_free_block(0x1800); // WLEDMM: This is a better metric for free heap. #endif if (heap < MIN_HEAP_SIZE && lastHeap < MIN_HEAP_SIZE) { - USER_PRINT(F("Heap too low! (step 2, force reconnect): ")); - USER_PRINTLN(heap); - forceReconnect = true; - strip.purgeSegments(true); // remove all but one segments from memory + if (retryCount < 5) { // WLEDMM avoid repeated disconnects + USER_PRINT(F("Heap too low! (step 2, force reconnect): ")); + USER_PRINTLN(heap); + forceReconnect = true; + strip.purgeSegments(true); // remove all but one segments from memory + // WLEDMM + errorFlag = ERR_LOW_MEM; + retryCount ++; + } + errorFlag = ERR_LOW_MEM; } else if (heap < MIN_HEAP_SIZE) { USER_PRINT(F("Heap too low! (step 1, flush unread UDP): ")); USER_PRINTLN(heap); @@ -1226,7 +1233,10 @@ void WLED::handleConnection() rgbUdp.flush(); notifier2Udp.flush(); ntpUdp.flush(); - } + // WLEDMM + errorFlag = ERR_LOW_MEM; + retryCount = 1; + } else retryCount = 0; // WLEDMM memory OK - reset counter lastHeap = heap; heapTime = now; } @@ -1235,15 +1245,22 @@ void WLED::handleConnection() if (now - heapTime > 5000) { uint32_t heap = ESP.getFreeHeap(); if (heap < MIN_HEAP_SIZE && lastHeap < MIN_HEAP_SIZE) { - USER_PRINT(F("Heap too low! (step 2, force reconnect): ")); - USER_PRINTLN(heap); - forceReconnect = true; - strip.purgeSegments(true); // remove all but one segments from memory + if (retryCount < 5) { // WLEDMM avoid repeated disconnects + USER_PRINT(F("Heap too low! (step 2, force reconnect): ")); + USER_PRINTLN(heap); + forceReconnect = true; + strip.purgeSegments(true); // remove all but one segments from memory + // WLEDMM + errorFlag = ERR_LOW_MEM; + } } else if (heap < MIN_HEAP_SIZE) { USER_PRINT(F("Heap too low! (step 1, purge segments): ")); USER_PRINTLN(heap); strip.purgeSegments(); - } + // WLEDMM + errorFlag = ERR_LOW_MEM; + retryCount = 1; + } else retryCount = 0; // WLEDMM memory OK - reset counter lastHeap = heap; heapTime = now; } diff --git a/wled00/wled.h b/wled00/wled.h index 6a3f386a..365bf53b 100644 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -8,7 +8,7 @@ */ // version code in format yymmddb (b = daily build) -#define VERSION 2402180 +#define VERSION 2402230 // WLEDMM - you can check for this define in usermods, to only enabled WLEDMM specific code in the "right" fork. Its not defined in AC WLED. #define _MoonModules_WLED_