前にESP32でFTPサーバを立てられるようにしていたんだけど、ESP32側で生成したログファイルとかをダウンロードするだけならブラウザ経由でダウンロードしたほうが手っ取り早いんじゃないかということでWeb版のファイルマネージャーを作ってみた。
SDカードはSD_MMC.hで高速にアクセスできる配線にしてある。起動時にプルアップしておけないIOは起動後にプルアップするようにGPIO27でプルアップしてみた。
#include <WiFi.h>
#include <WebServer.h>
#include "SD_MMC.h"
#include "esp_mac.h" //MACアドレス取得用
#define WiFi_password "12345678"
#define WiFi_ch 3
#define SD_PULLUP 27
WebServer server(80);
File uploadFile;
String htmlHeader() {
return R"rawliteral(
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ESP32 SD_MMC File Manager</title>
</head>
<body>
<h2>ESP32 SD_MMC File Manager</h2>
<form method="POST" action="/upload" enctype="multipart/form-data">
<input type="file" name="upload">
<input type="submit" value="Upload">
</form>
<hr>
)rawliteral";
}
void listFiles() {
String html = htmlHeader();
File root = SD_MMC.open("/");
File file = root.openNextFile();
while (file) {
String name = file.name();
html += "<p>";
html += name;
html += " [<a href=\"/download?name=" + name + "\">Download</a>]";
html += " [<a href=\"/delete?name=" + name + "\">Delete</a>]";
html += "</p>";
file = root.openNextFile();
}
html += "</body></html>";
server.send(200, "text/html", html);
}
void handleDownload() {
if (!server.hasArg("name")) {
server.send(400, "text/plain", "Bad Request");
return;
}
String filename = server.arg("name");
String path = "/" + filename;
File file = SD_MMC.open(path);
if (!file) {
server.send(404, "text/plain", "File Not Found");
return;
}
server.sendHeader("Content-Disposition", "attachment; filename=\"" + filename + "\"");
server.sendHeader("Content-Type", "application/octet-stream");
server.sendHeader("Connection", "close");
server.streamFile(file, "application/octet-stream");
file.close();
}
void handleDelete() {
if (!server.hasArg("name")) {
server.send(400, "text/plain", "Bad Request");
return;
}
String filename = "/" + server.arg("name");
if (SD_MMC.exists(filename)) {
SD_MMC.remove(filename);
}
server.sendHeader("Location", "/");
server.send(303);
}
void handleUpload() {
HTTPUpload& upload = server.upload();
if (upload.status == UPLOAD_FILE_START) {
String filename = "/" + upload.filename;
uploadFile = SD_MMC.open(filename, FILE_WRITE);
} else if (upload.status == UPLOAD_FILE_WRITE) {
if (uploadFile) {
uploadFile.write(upload.buf, upload.currentSize);
}
} else if (upload.status == UPLOAD_FILE_END) {
if (uploadFile) {
uploadFile.close();
}
}
}
void setup() {
Serial.begin(115200);
pinMode(SD_PULLUP, OUTPUT);
digitalWrite(SD_PULLUP, HIGH);
if (!SD_MMC.begin()) {
Serial.println("SD_MMC Mount Failed");
return;
}
if (SD_MMC.cardType() == CARD_NONE) {
Serial.println("No SD card attached");
return;
}
Serial.println("SD_MMC Ready");
uint8_t macaddr[6];
esp_read_mac(macaddr, ESP_MAC_WIFI_SOFTAP); //WiFi Macアドレス読み込み
char SSID[14];
sprintf(SSID, "ESP32-%02X%02X", macaddr[4], macaddr[5]);
WiFi.softAP(SSID, WiFi_password, WiFi_ch); //SoftAPを起動
server.on("/", listFiles);
server.on("/download", handleDownload);
server.on("/delete", handleDelete);
server.on(
"/upload", HTTP_POST, []() {
server.sendHeader("Location", "/");
server.send(303);
},
handleUpload);
server.begin();
}
void loop() {
server.handleClient();
}一応アップロード機能もついてるのファイルアップロードもできる。ディレクトリは面倒なのでとりあえず非対応で。ログファイルを生成してダウンロードする用途だったら十分使えそうなレベル。スマホとかでもそのまま使えるのでFTPより便利かも…