Thanks to visit codestin.com
Credit goes to github.com

Skip to content
This repository was archived by the owner on Jan 20, 2025. It is now read-only.
This repository was archived by the owner on Jan 20, 2025. It is now read-only.

How to serve big files from an SD Card? #939

Closed
@JRoseCPMax

Description

@JRoseCPMax

I'm currently trying to download ~20Mb Files from an ESP32 with an SD Card. I tried the following approach with the ChunkedResponse example:

#include <Arduino.h>
...
#include "FS.h"
#include "SD.h"
...
#include "WiFi.h"
#include "ESPAsyncWebServer.h"
#include "WebSocketsServer.h"

AsyncWebServer server(80);
...

size_t load_data(File f, uint8_t *buffer, size_t maxLen, size_t index){
  if (f.available()){
    // return f.read(buffer, maxLen);     // WDT
    return f.read();                      // extremely slow (6KB/s)
  } else {
    return 0;
  }
}

void onPageNotFound(AsyncWebServerRequest *request){
  IPAddress ip = request -> client() -> remoteIP();
  String requested_file = request->url();
  Serial.println("["+ip.toString() +"] GET Request of " + requested_file);

  if (requested_file.startsWith(folder) & SD.open(requested_file, FILE_READ)){
    File f = SD.open(requested_file, FILE_READ);
    AsyncWebServerResponse *response = request->beginChunkedResponse("text/csv", [f](uint8_t *buffer, size_t maxLen, size_t, index) -> size_t {
      return load_data(f, buffer, maxLen, index);
    });
    response->addHeader("Server","ESP Async Web Server");
    request->send(response);
    // f.close();                        // <-- don't know where to put this, it interrupts the transmission at this point
  } else {
    request->send_P(404, "text/html", "Not Found");
  }
}

void setup(){
...
 WiFi.softAP(ssid, password);
...
 server.on("/", HTTP_GET, onIndexRequest);
 server.onNotFound(onPageNotFound);
 server.begin();
}
...

When using f.read() in load_data it works but only extremly slow, i suspect, it transmits one char at a time?
However, when I use f.read(buffer, maxLen) and start the download the WDT gets triggered.
with request->send(SD, requested_file, "text/csv"); the header (Filesize) gets transmitted correctly, but the WDT also triggers.

E (54572) task_wdt: Task watchdog got triggered. The following tasks did not reset the watchdog in time:
E (54572) task_wdt:  - async_tcp (CPU 0/1)
E (54572) task_wdt: Tasks currently running:
E (54572) task_wdt: CPU 0: IDLE0
E (54572) task_wdt: CPU 1: loopTask
E (54572) task_wdt: Aborting.
abort() was called at PC 0x400e9e17 on core 0

What is the most elegant way to serve a bigger file from SD?

EDIT: Now using the workaround of a second Server instance (WebServer) on a diff. port. ESP32 handles just fine.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions