Hello!
In my project, I have a set of data stored on an SD card. Ideally, the card will be full, and the files inside will total around 60 GB.
Due to the way the project is designed, it would be best not to remove the SD card from the device. That’s why I want to test whether it’s possible to transfer these files from the SD to a computer. The transfer doesn’t need to be particularly fast—it could take up to 30 minutes, and that wouldn’t be an issue.
However, I’m testing this sketch, and if my calculations are correct, the transfer would take around 40 hours, with a download rate of approximately 430 kbps.
I have no experience with this topic, and I wanted to ask if anyone knows what I could try to download the files from the SD card at a somewhat faster speed.
Of course, I am running tests with my ESP32S3 right next to the router.
P.S.: Just as I don’t want to remove the SD card from the device, I also can’t connect via Ethernet.
I’ve seen that there are many discussions about using FTP, but none (that I’ve found) specifically about large files.
Here is my sketch, working at 240MHz (in my project it might be 80MHz):
#include <WiFi.h>
#include <ESPAsyncWebServer.h>
#include <SD_MMC.h>
#define MMC_D2 4
#define MMC_D3 5
#define MMC_CMD 6
#define MMC_CLK 7
#define MMC_D0 15
#define MMC_D1 16
#define SDMMC_SPEED SDMMC_FREQ_HIGHSPEED
const char* ssid = "SSID";
const char* password = "PW";
AsyncWebServer server(80);
void setup() {
Serial.begin(115200);
while(!Serial)
delay(10);
Serial.println("Serial started.");
pinMode(LED_BUILTIN, OUTPUT);
delay(10);
digitalWrite(LED_BUILTIN, LOW);
// Initialize the SD card
SD_MMC.setPins(MMC_CLK, MMC_CMD, MMC_D0, MMC_D1, MMC_D2, MMC_D3);
Serial.println("Initializing SD card...");
if (!SD_MMC.begin("/sdcard", true, SDMMC_SPEED)) {
Serial.println("Failed to initialize SD card.");
return;
}
Serial.println("SD card initialized successfully.");
digitalWrite(LED_BUILTIN, HIGH); // SD card is ready.
// Connect to Wi-Fi
WiFi.begin(ssid, password);
int attempts = 0;
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
attempts++;
if (attempts > 10) { // If not connected within 10 attempts, print error message
Serial.println("Failed to connect to Wi-Fi");
break;
}
}
// Double check.
if (WiFi.status() == WL_CONNECTED) {
Serial.println("Connected to Wi-Fi");
Serial.print("IP: ");
Serial.println(WiFi.localIP());
} else {
Serial.println("Could not connect to Wi-Fi.");
}
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
String response = "<h1>Available files on SD</h1><ul>";
// List all files on the SD card
Serial.println("Listing files on SD...");
File root = SD_MMC.open("/");
if (root) {
File file = root.openNextFile();
while (file) {
String fileName = file.name();
Serial.print("File found: ");
Serial.println(fileName);
// Replace spaces with %20 in the URL
fileName.replace(" ", "%20");
response += "<li><a href='/download?file=" + fileName + "'>" + fileName + "</a></li>";
file = root.openNextFile();
}
root.close();
} else {
Serial.println("Could not open SD root directory.");
}
response += "</ul>";
request->send(200, "text/html", response);
});
// Route to download a file
server.on("/download", HTTP_GET, [](AsyncWebServerRequest *request){
String fileName = request->getParam("file")->value(); // Get the filename from the URL
// Print the requested filename
Serial.print("Requested file: ");
Serial.println(fileName);
String filePath = "/" + fileName;
// Print the full path
Serial.print("File path: ");
Serial.println(filePath);
// Check if the file exists
File file = SD_MMC.open(filePath);
if (file) {
// Send the file to the browser with its original name
Serial.println("File found, sending...");
// File is downloaded with its original name
AsyncWebServerResponse *response = request->beginResponse(SD_MMC, filePath, "application/octet-stream");
response->addHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
request->send(response);
file.close();
} else {
Serial.println("Error: File does not exist.");
request->send(404, "text/plain", "File not found");
}
});
// Start the server
server.begin();
}
void loop() {
// Nothing to do here
}

