From 87c24338b54a676d9b945ed167032531ada10ee3 Mon Sep 17 00:00:00 2001 From: drjones Date: Tue, 30 Jun 2026 01:43:35 -0700 Subject: [PATCH] Implement local web server on SoftAP for uploading PNG/MP3/WAV files directly to SD card --- sound_picture_app/Web_Server.cpp | 148 ++++++++++++++++++++++++ sound_picture_app/Web_Server.h | 5 + sound_picture_app/sound_picture_app.ino | 7 ++ 3 files changed, 160 insertions(+) create mode 100644 sound_picture_app/Web_Server.cpp create mode 100644 sound_picture_app/Web_Server.h diff --git a/sound_picture_app/Web_Server.cpp b/sound_picture_app/Web_Server.cpp new file mode 100644 index 0000000..158beb0 --- /dev/null +++ b/sound_picture_app/Web_Server.cpp @@ -0,0 +1,148 @@ +#include "Web_Server.h" +#include +#include +#include "SD_Card.h" +#include "Display_PNG.h" +#include "Audio_Player.h" + +WebServer server(80); +File uploadFile; + +const char* uploadPage = R"rawliteral( + + + + + Photo Upload Panel + + + +
+

Upload Photo / Audio

+
+
+ + +
+
No file selected
+ +
+
Supports PNG (172x320 max) and MP3/WAV.
+
+ + + +)rawliteral"; + +void handleUpload() { + HTTPUpload& upload = server.upload(); + if (upload.status == UPLOAD_FILE_START) { + String filename = upload.filename; + if (!filename.startsWith("/")) { + filename = "/" + filename; + } + printf("WebUpload: Starting upload of %s\r\n", filename.c_str()); + uploadFile = SD_MMC.open(filename, "w"); + } + 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(); + printf("WebUpload: Successfully uploaded %s (%d bytes)\r\n", upload.filename.c_str(), upload.totalSize); + // Re-scan SD card folders to index the new file + Search_Images("/"); + Search_Audio("/"); + } + } +} + +void initWebServer() { + // Start WiFi Access Point + WiFi.softAP("ESP32-Photo-Frame"); + IPAddress IP = WiFi.softAPIP(); + printf("WiFi AP Started. SSID: 'ESP32-Photo-Frame'\r\n"); + printf("Web Server IP address: %s\r\n", IP.toString().c_str()); + + // Serve Page + server.on("/", HTTP_GET, []() { + server.send(200, "text/html", uploadPage); + }); + + // Handle file uploads + server.on("/upload", HTTP_POST, []() { + // Redirect back to main upload page on success + server.sendHeader("Location", "/"); + server.send(303); + }, handleUpload); + + server.begin(); +} + +void handleWebServer() { + server.handleClient(); +} diff --git a/sound_picture_app/Web_Server.h b/sound_picture_app/Web_Server.h new file mode 100644 index 0000000..bf4ebbd --- /dev/null +++ b/sound_picture_app/Web_Server.h @@ -0,0 +1,5 @@ +#pragma once +#include + +void initWebServer(); +void handleWebServer(); diff --git a/sound_picture_app/sound_picture_app.ino b/sound_picture_app/sound_picture_app.ino index f11ab6d..7314f2f 100644 --- a/sound_picture_app/sound_picture_app.ino +++ b/sound_picture_app/sound_picture_app.ino @@ -2,6 +2,7 @@ #include "SD_Card.h" #include "Display_PNG.h" #include "Audio_Player.h" +#include "Web_Server.h" #include #define BOOT_KEY_PIN 9 @@ -79,6 +80,9 @@ void setup() { Display_Image_By_Index("/", 0); currentState = STATE_IDLE; } + + // Start the SoftAP and local Web Server + initWebServer(); } void playCurrentPair() { @@ -265,6 +269,9 @@ void loop() { lastButtonState = currentButtonReading; + // Handle incoming web server clients + handleWebServer(); + // Update status RGB LED updateLEDStatus();