7.7 KiB
7.7 KiB
ESP32 MP3 Player - Web Request & WiFiManager Memory Optimizations
High-Impact Web Request Optimizations
1. ESPAsyncWifiManager Configuration Optimization (HIGH IMPACT: 10-20KB)
The ESPAsyncWifiManager can be configured to use less memory:
// In setup(), before wifiManager.autoConnect():
AsyncWiFiManager wifiManager(&server, &dns);
// Reduce timeout to free memory faster
wifiManager.setTimeout(60); // Reduced from 180 to 60 seconds
// Disable debug output to save memory
wifiManager.setDebugOutput(false);
// Set custom parameters to reduce memory usage
wifiManager.setConfigPortalBlocking(false); // Non-blocking mode saves memory
wifiManager.setConnectTimeout(20); // Faster connection timeout
wifiManager.setConfigPortalTimeout(60); // Shorter portal timeout
2. Web Server Request Handler Optimization (MEDIUM IMPACT: 5-10KB)
Current issue: Each request handler creates temporary objects and strings.
Optimization A: Use String References Instead of Copies
// Replace current parameter handling with more efficient version:
void id_song_action(AsyncWebServerRequest *request)
{
const AsyncWebParameter* p = request->getParam("id");
if (p != nullptr) {
playSongById(p->value().toInt()); // Direct conversion, no string copy
}
lastInteraction = millis();
request->send_P(200, "text/plain", "ok"); // Use PROGMEM string
}
Optimization B: Reduce JSON Buffer Allocations
String getState()
{
// Use static buffer to avoid repeated allocations
static DynamicJsonDocument jsonState(384); // Further reduced from 512
jsonState.clear(); // Clear previous data
jsonState[F("playing")] = audio.isRunning(); // Use F() macro
if (currentNode != nullptr)
jsonState[F("title")] = *currentNode->getCurrentPlaying();
else
jsonState[F("title")] = F("Angehalten"); // Store in flash
jsonState[F("time")] = audio.getAudioCurrentTime();
jsonState[F("volume")] = audio.getVolume();
jsonState[F("length")] = audio.getAudioFileDuration();
jsonState[F("voltage")] = lastVoltage;
jsonState[F("uid")] = lastUid;
jsonState[F("heap")] = free_heap;
String output;
output.reserve(256); // Pre-allocate string buffer
serializeJson(jsonState, output);
return output;
}
3. File Upload Handler Memory Optimization (HIGH IMPACT: 15-30KB)
Current issue: Large temporary buffers and inefficient string operations.
void handleUpload(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final) {
static String logBuffer; // Static to avoid repeated allocations
if (!index) {
// Use const references to avoid string copies
const String& lowerFilename = filename;
// Pre-allocate log buffer
logBuffer.reserve(128);
logBuffer = F("Upload Start: ");
logBuffer += filename;
// More efficient space check
uint32_t freeSpace = (SD.cardSize() - SD.usedBytes()) >> 20; // Bit shift instead of division
if (freeSpace < 10) {
request->send(507, F("text/plain"), F("Insufficient storage space"));
return;
}
Serial.println(logBuffer);
logBuffer.clear(); // Free memory immediately
// ... rest of upload logic
}
// Reduce logging frequency to save memory
if (len && (index % 204800 == 0)) { // Log every 200KB instead of 100KB
logBuffer = F("Upload: ");
logBuffer += humanReadableSize(index + len);
Serial.println(logBuffer);
logBuffer.clear();
}
}
4. HTML Template Processing Optimization (MEDIUM IMPACT: 3-5KB)
String processor(const String &var)
{
if (var == F("DIRECTORY")) // Use F() macro
{
return rootNode.getDirectoryStructureHTML();
}
return String(); // Return empty string instead of creating new String
}
5. Static Content Serving Optimization (LOW IMPACT: 1-2KB)
// Optimize CSS/JS serving with better error handling
server.on("/style.css", HTTP_GET, [](AsyncWebServerRequest *request) {
activateSD();
const char* cssPath = "/system/style.css";
if (SD.exists(cssPath)) {
request->send(SD, cssPath, F("text/css"));
} else {
// Serve minimal fallback without creating large strings
request->send_P(200, "text/css", "body{font-family:Arial;text-align:center;}");
}
deactivateSD();
});
ESPAsyncWifiManager Specific Optimizations
6. WiFiManager Memory Pool Configuration (HIGH IMPACT: 15-25KB)
// Add these configurations in setup():
void setup() {
// ... existing code ...
AsyncWiFiManager wifiManager(&server, &dns);
// Memory optimizations for WiFiManager
wifiManager.setDebugOutput(false); // Disable debug strings
wifiManager.setMinimumSignalQuality(20); // Reduce AP scan results
wifiManager.setRemoveDuplicateAPs(true); // Remove duplicate APs from memory
wifiManager.setConfigPortalBlocking(false); // Non-blocking saves memory
wifiManager.setScanDisposeDelay(5000); // Dispose scan results faster
// Reduce timeouts to free memory faster
wifiManager.setTimeout(60); // Reduced from 180
wifiManager.setConnectTimeout(15); // Faster connection attempts
wifiManager.setConfigPortalTimeout(60); // Shorter portal timeout
// Custom CSS/HTML to reduce memory usage (optional)
wifiManager.setCustomHeadElement(F("<style>body{font-size:14px;}</style>"));
if (wifiManager.autoConnect("HannaBox")) {
// ... existing server setup ...
}
}
Additional Compiler & Build Optimizations
7. Enhanced Build Flags (MEDIUM IMPACT: 5-10KB)
Add to platformio.ini:
build_flags =
-Os ; Optimize for size
-DCORE_DEBUG_LEVEL=0 ; Disable all debug output
-DARDUINO_LOOP_STACK_SIZE=3072 ; Further reduce from 4096
-DWIFI_TASK_STACK_SIZE=3072 ; Reduce WiFi task stack
-DARDUINO_EVENT_TASK_STACK_SIZE=2048 ; Reduce event task stack
-DTCPIP_TASK_STACK_SIZE=2048 ; Reduce TCP/IP stack
-DESP_TASK_WDT_TIMEOUT_S=10 ; Reduce watchdog timeout
-DCONFIG_ASYNC_TCP_MAX_ACK_TIME=3000 ; Reduce TCP ACK timeout
-DCONFIG_ASYNC_TCP_QUEUE_SIZE=32 ; Reduce TCP queue size
Implementation Priority
-
IMMEDIATE (High Impact):
- ESPAsyncWifiManager configuration optimization
- File upload handler memory optimization
- Enhanced build flags
-
SHORT TERM (Medium Impact):
- JSON buffer optimization with F() macros
- Web request handler optimization
- Static content serving optimization
-
LONG TERM (Maintenance):
- Monitor memory usage patterns
- Consider implementing request queuing if needed
- Profile actual memory usage during web operations
Expected Total Memory Savings
| Optimization Category | Memory Saved |
|---|---|
| ESPAsyncWifiManager Config | 15-25KB |
| File Upload Handler | 15-30KB |
| JSON & String Optimizations | 5-10KB |
| Build Flag Optimizations | 5-10KB |
| Total Potential Savings | 40-75KB |
Testing & Validation
After implementing these optimizations:
-
Monitor free heap via web interface during:
- WiFi connection process
- File uploads
- Multiple concurrent web requests
- JSON state requests
-
Test stability under load:
- Multiple rapid web requests
- Large file uploads
- WiFi reconnection scenarios
-
Verify functionality:
- All web endpoints work correctly
- File uploads complete successfully
- WiFi manager portal functions properly