[ai] Memory Optimizations
This commit is contained in:
@@ -19,8 +19,8 @@ lib_deps =
|
|||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
build_flags =
|
build_flags =
|
||||||
-Os ; Optimize for size
|
-Os ; Optimize for size
|
||||||
; -DDEBUG ; Hannabox Debugging
|
-DDEBUG ; Hannabox Debugging
|
||||||
-DCORE_DEBUG_LEVEL=0 ; Disable all debug output
|
; -DCORE_DEBUG_LEVEL=0 ; Disable all debug output
|
||||||
; -DARDUINO_LOOP_STACK_SIZE=4096 ; Balanced to avoid stack canary without starving heap
|
; -DARDUINO_LOOP_STACK_SIZE=4096 ; Balanced to avoid stack canary without starving heap
|
||||||
; -DWIFI_TASK_STACK_SIZE=3072 ; Reduce WiFi task stack
|
; -DWIFI_TASK_STACK_SIZE=3072 ; Reduce WiFi task stack
|
||||||
; -DARDUINO_EVENT_TASK_STACK_SIZE=2048 ; Reduce event task stack
|
; -DARDUINO_EVENT_TASK_STACK_SIZE=2048 ; Reduce event task stack
|
||||||
|
|||||||
@@ -405,11 +405,11 @@ DirectoryNode *DirectoryNode::advanceToMP3(const String &songName)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Use static buffer for case conversion and comparison
|
// Use static buffer for comparison without allocation
|
||||||
buildFullPath(mp3Files[i], buffer, buffer_size);
|
buildFullPath(mp3Files[i], buffer, buffer_size);
|
||||||
String f = String(buffer);
|
size_t bufLen = strlen(buffer);
|
||||||
f.toLowerCase();
|
size_t targetLen = lowTarget.length();
|
||||||
if (f.endsWith(lowTarget))
|
if (bufLen >= targetLen && strcasecmp(buffer + bufLen - targetLen, lowTarget.c_str()) == 0)
|
||||||
{
|
{
|
||||||
setCurrentPlaying(mp3Files[i]);
|
setCurrentPlaying(mp3Files[i]);
|
||||||
return this;
|
return this;
|
||||||
@@ -450,9 +450,11 @@ DirectoryNode *DirectoryNode::advanceToMP3(const String &songName)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
String f = subdir->mp3Files[i];
|
// Check suffix case-insensitively without creating new Strings
|
||||||
f.toLowerCase();
|
const String& fName = subdir->mp3Files[i];
|
||||||
if (f.endsWith(lowTarget))
|
size_t fLen = fName.length();
|
||||||
|
size_t targetLen = lowTarget.length();
|
||||||
|
if (fLen >= targetLen && strcasecmp(fName.c_str() + fLen - targetLen, lowTarget.c_str()) == 0)
|
||||||
{
|
{
|
||||||
subdir->setCurrentPlaying(subdir->mp3Files[i]);
|
subdir->setCurrentPlaying(subdir->mp3Files[i]);
|
||||||
return subdir;
|
return subdir;
|
||||||
|
|||||||
58
src/main.cpp
58
src/main.cpp
@@ -147,10 +147,8 @@ void handleUpload(AsyncWebServerRequest *request, String filename, size_t index,
|
|||||||
activateSD();
|
activateSD();
|
||||||
|
|
||||||
// Check if file already exists and create backup name if needed
|
// Check if file already exists and create backup name if needed
|
||||||
String filepath;
|
char filepath[256];
|
||||||
filepath.reserve(1 + filename.length());
|
snprintf(filepath, sizeof(filepath), "/%s", filename.c_str());
|
||||||
filepath = "/";
|
|
||||||
filepath += filename;
|
|
||||||
if (SD.exists(filepath))
|
if (SD.exists(filepath))
|
||||||
{
|
{
|
||||||
request->send(500, txt_plain, F("File already exists."));
|
request->send(500, txt_plain, F("File already exists."));
|
||||||
@@ -806,54 +804,6 @@ void readDataFromFile(const String &filename)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String processor(const String &var)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (var == "MAPPING")
|
|
||||||
{
|
|
||||||
auto htmlEscape = [](const String &s) -> String
|
|
||||||
{
|
|
||||||
String out;
|
|
||||||
for (size_t i = 0; i < s.length(); ++i)
|
|
||||||
{
|
|
||||||
char c = s[i];
|
|
||||||
if (c == '&')
|
|
||||||
out += "&";
|
|
||||||
else if (c == '<')
|
|
||||||
out += "";
|
|
||||||
else if (c == '>')
|
|
||||||
out += "";
|
|
||||||
else if (c == '"')
|
|
||||||
out += "";
|
|
||||||
else if (c == '\'')
|
|
||||||
out += "";
|
|
||||||
else
|
|
||||||
out += c;
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
};
|
|
||||||
String html;
|
|
||||||
html.reserve(256);
|
|
||||||
html.concat(F("<table style='width:100%;border-collapse:collapse;'><tr><th style='border:1px solid #ccc;padding:4px;'>RFID</th><th style='border:1px solid #ccc;padding:4px;'>Song</th></tr>"));
|
|
||||||
for (const auto &pair : rfid_map)
|
|
||||||
{
|
|
||||||
html.concat(F("<tr><td style='border:1px solid #ccc;padding:4px;'>"));
|
|
||||||
html.concat(htmlEscape(pair.first));
|
|
||||||
html.concat(F("</td><td style='border:1px solid #ccc;padding:4px;'>"));
|
|
||||||
// Show target and mode (e.g. "mysong.mp3|s")
|
|
||||||
String mappingVal = pair.second.target;
|
|
||||||
mappingVal += "|";
|
|
||||||
mappingVal += pair.second.mode;
|
|
||||||
html.concat(htmlEscape(mappingVal));
|
|
||||||
html.concat(F("</td></tr>"));
|
|
||||||
}
|
|
||||||
html.concat(F("</table>"));
|
|
||||||
return html;
|
|
||||||
}
|
|
||||||
|
|
||||||
return String(); // Return empty string instead of creating new String
|
|
||||||
}
|
|
||||||
|
|
||||||
// Memory-optimized helpers and streamers to avoid large temporary Strings
|
// Memory-optimized helpers and streamers to avoid large temporary Strings
|
||||||
|
|
||||||
static inline void htmlEscapeAndPrint(Print &out, const String &s)
|
static inline void htmlEscapeAndPrint(Print &out, const String &s)
|
||||||
@@ -1565,8 +1515,8 @@ void setup()
|
|||||||
wifiManager.setDebugOutput(true);
|
wifiManager.setDebugOutput(true);
|
||||||
|
|
||||||
// Reduce timeouts to free memory faster
|
// Reduce timeouts to free memory faster
|
||||||
wifiManager.setTimeout(180); // Reduced from 180
|
wifiManager.setTimeout(150); // Reduced from 180
|
||||||
wifiManager.setConnectTimeout(20); // Faster connection attempts
|
wifiManager.setConnectTimeout(30); // Faster connection attempts
|
||||||
wifiManager.setConfigPortalTimeout(120); // Shorter portal timeout
|
wifiManager.setConfigPortalTimeout(120); // Shorter portal timeout
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
|||||||
Reference in New Issue
Block a user