I'm trying to join this 2 codes but the one from the web server doesn't work, it for ESP32
//web server
#include <Arduino.h>
#include <FS.h>
#include <SPIFFS.h>
#include <ESPAsyncWebServer.h>
const char *ssid = "hi";
const char *password = "12345678";
String currentDirectory = "/"; // Carpeta inicial en SPIFFS
AsyncWebServer server(80);
void setup() {
Serial.begin(115200);
if (!SPIFFS.begin()) {
Serial.println("No se pudo inicializar SPIFFS.");
return;
}
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Conectando a WiFi...");
}
Serial.println("Conexión exitosa al WiFi");
Serial.print("Dirección IP: ");
Serial.println(WiFi.localIP());
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
String html = "<html><body>";
html += "<h1>ESP32 SPIFFS Web Server</h1>";
html += "<p>Conexión exitosa al WiFi</p>";
html += "<p>Dirección IP: " + WiFi.localIP().toString() + "</p>";
html += "<p>SPIFFS Inicializado</p>";
html += "<form action=\"/changeDirectory\" method=\"post\">";
html += " <label for=\"directory\">Carpeta Actual: " + currentDirectory + "</label><br>";
html += " <input type=\"text\" id=\"directory\" name=\"directory\" placeholder=\"Ingrese nueva carpeta\">";
html += " <input type=\"submit\" value=\"Cambiar Carpeta\">";
html += "</form>";
html += "<button onclick=\"listFiles()\">Listar Archivos</button>";
html += "<input type=\"file\" id=\"fileInput\" multiple/>";
html += "<button onclick=\"uploadFiles()\">Subir Archivos</button>";
html += "<button onclick=\"deleteSelectedFiles()\">Eliminar Archivos Seleccionados</button>";
html += "<button onclick=\"goHome()\">Home</button>";
html += "<script>function listFiles(){fetch('/list').then(response => response.text()).then(data => document.getElementById('fileList').innerHTML = data);} function uploadFiles(){var fileInput = document.getElementById('fileInput'); var formData = new FormData(); for (var i = 0; i < fileInput.files.length; i++) { formData.append('file[]', fileInput.files[i]); } fetch('/upload', {method: 'POST', body: formData}).then(listFiles);} function deleteSelectedFiles(){if(confirm('¿Está seguro de que desea eliminar los archivos seleccionados?')){var checkboxes = document.querySelectorAll('input[type=\"checkbox\"]:checked'); var formData = new FormData(); checkboxes.forEach(function(checkbox){formData.append('file', checkbox.value);}); fetch('/delete', {method: 'POST', body: formData}).then(response => response.text()).then(data => alert(data)).then(listFiles);}}";
html += "function goHome(){fetch('/goHome').then(response => response.text()).then(data => alert(data)).then(listFiles);}</script>";
html += "<div id=\"fileList\"></div>";
html += "<script>listFiles();</script>"; // Agregado: listar archivos automáticamente al cargar la página
html += "</body></html>";
request->send(200, "text/html", html);
});
server.on("/upload", HTTP_POST, [](AsyncWebServerRequest *request) {
AsyncWebServerResponse *response = request->beginResponse(200, "text/plain", "Archivos Subidos");
response->addHeader("Connection", "close");
request->send(response);
},
[](AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final) {
static File uploadFile;
if (!index) {
uploadFile = SPIFFS.open(currentDirectory + "/" + filename, FILE_WRITE);
}
if (uploadFile) {
for (size_t i = 0; i < len; i++) {
uploadFile.write(data[i]);
}
}
if (final) {
uploadFile.close();
Serial.printf("Archivo %s subido con éxito.\n", filename.c_str());
}
});
server.on("/list", HTTP_GET, [](AsyncWebServerRequest *request) {
String files;
File dir = SPIFFS.open(currentDirectory);
while (File entry = dir.openNextFile()) {
String previewPath = generatePreview(entry.name());
files += "<p><input type=\"checkbox\" name=\"file\" value=\"" + String(entry.name()) + "\"> " + entry.name() + "<br><img src=\"" + previewPath + "\" width=\"100\"></p>";
entry.close();
}
request->send(200, "text/html", files);
});
server.on("/delete", HTTP_POST, [](AsyncWebServerRequest *request) {
String responseMessage = deleteSelectedFiles(request);
request->send(200, "text/plain", responseMessage);
});
server.on("/changeDirectory", HTTP_POST, [](AsyncWebServerRequest *request){
if(request->hasParam("directory", true)){
currentDirectory = "/" + request->getParam("directory", true)->value();
}
request->redirect("/");
});
server.on("/goHome", HTTP_GET, [](AsyncWebServerRequest *request){
currentDirectory = "/";
request->send(200, "text/plain", "Ir a la carpeta raíz.");
});
server.on("/preview", HTTP_GET, [](AsyncWebServerRequest *request){
servePreview(request);
});
Serial.println("ESP32 SPIFFS Web Server iniciado.");
server.begin();
}
void loop() {
// Nada que hacer aquí
}
String deleteSelectedFiles(AsyncWebServerRequest *request) {
String responseMessage = "Archivos seleccionados eliminados con éxito";
int params = request->params();
for (int i = 0; i < params; i++) {
AsyncWebParameter* p = request->getParam(i);
if (p->name() == "file") {
SPIFFS.remove(currentDirectory + "/" + p->value());
Serial.printf("Archivo %s eliminado con éxito.\n", p->value().c_str());
}
}
return responseMessage;
}
String generatePreview(String filename) {
if (filename.endsWith(".gif")) {
return "/preview?file=" + filename;
}
// Si el archivo no es un GIF, simplemente devolver una cadena vacía
return "";
}
void servePreview(AsyncWebServerRequest *request) {
if (request->hasParam("file")) {
String filename = request->getParam("file")->value();
String filePath = currentDirectory + "/" + filename;
if (SPIFFS.exists(filePath)) {
AsyncWebServerResponse *response = request->beginResponse(SPIFFS, filePath, "image/gif");
request->send(response);
} else {
request->send(404, "text/plain", "Archivo no encontrado");
}
} else {
request->send(400, "text/plain", "Parámetro 'file' faltante");
}
}
//GIF SPIFFS player
// Example sketch which shows how to display a 64x32 animated GIF image stored in FLASH memory
// on a 64x32 LED matrix
//
// Credits: https://github.com/bitbank2/AnimatedGIF/tree/master/examples/ESP32_LEDMatrix_I2S
//
/* INSTRUCTIONS
*
* 1. First Run the 'ESP32 Sketch Data Upload Tool' in Arduino from the 'Tools' Menu.
* - If you don't know what this is or see it as an option, then read this:
* https://github.com/me-no-dev/arduino-esp32fs-plugin
* - This tool will upload the contents of the data/ directory in the sketch folder onto
* the ESP32 itself.
*
* 2. You can drop any animated GIF you want in there, but keep it to the resolution of the
* MATRIX you're displaying to. To resize a gif, use this online website: https://ezgif.com/
*
* 3. Have fun.
*/
#define FILESYSTEM SPIFFS
#include <SPIFFS.h>
#include <AnimatedGIF.h>
#include <ESP32-HUB75-MatrixPanel-I2S-DMA.h>
#define A_PIN 33
#define B_PIN 32
#define C_PIN 22
#define E_PIN 21
#define PANEL_RES_X 64 // Number of pixels wide of each INDIVIDUAL panel module.
#define PANEL_RES_Y 64 // Number of pixels tall of each INDIVIDUAL panel module.
#define PANEL_CHAIN 1 // Total number of panels chained one to another
//MatrixPanel_I2S_DMA dma_display;
MatrixPanel_I2S_DMA *dma_display = nullptr;
uint16_t myBLACK = dma_display->color565(0, 0, 0);
uint16_t myWHITE = dma_display->color565(255, 255, 255);
uint16_t myRED = dma_display->color565(255, 0, 0);
uint16_t myGREEN = dma_display->color565(0, 255, 0);
uint16_t myBLUE = dma_display->color565(0, 0, 255);
AnimatedGIF gif;
File f;
int x_offset, y_offset;
// Draw a line of image directly on the LED Matrix
void GIFDraw(GIFDRAW *pDraw)
{
uint8_t *s;
uint16_t *d, *usPalette, usTemp[320];
int x, y, iWidth;
iWidth = pDraw->iWidth;
if (iWidth > MATRIX_WIDTH)
iWidth = MATRIX_WIDTH;
usPalette = pDraw->pPalette;
y = pDraw->iY + pDraw->y; // current line
s = pDraw->pPixels;
if (pDraw->ucDisposalMethod == 2) // restore to background color
{
for (x=0; x<iWidth; x++)
{
if (s[x] == pDraw->ucTransparent)
s[x] = pDraw->ucBackground;
}
pDraw->ucHasTransparency = 0;
}
// Apply the new pixels to the main image
if (pDraw->ucHasTransparency) // if transparency used
{
uint8_t *pEnd, c, ucTransparent = pDraw->ucTransparent;
int x, iCount;
pEnd = s + pDraw->iWidth;
x = 0;
iCount = 0; // count non-transparent pixels
while(x < pDraw->iWidth)
{
c = ucTransparent-1;
d = usTemp;
while (c != ucTransparent && s < pEnd)
{
c = *s++;
if (c == ucTransparent) // done, stop
{
s--; // back up to treat it like transparent
}
else // opaque
{
*d++ = usPalette[c];
iCount++;
}
} // while looking for opaque pixels
if (iCount) // any opaque pixels?
{
for(int xOffset = 0; xOffset < iCount; xOffset++ ){
dma_display->drawPixel(x + xOffset, y, usTemp[xOffset]); // 565 Color Format
}
x += iCount;
iCount = 0;
}
// no, look for a run of transparent pixels
c = ucTransparent;
while (c == ucTransparent && s < pEnd)
{
c = *s++;
if (c == ucTransparent)
iCount++;
else
s--;
}
if (iCount)
{
x += iCount; // skip these
iCount = 0;
}
}
}
else // does not have transparency
{
s = pDraw->pPixels;
// Translate the 8-bit pixels through the RGB565 palette (already byte reversed)
for (x=0; x<pDraw->iWidth; x++)
{
dma_display->drawPixel(x, y, usPalette[*s++]); // color 565
}
}
} /* GIFDraw() */
void * GIFOpenFile(const char *fname, int32_t *pSize)
{
Serial.print("Playing gif: ");
Serial.println(fname);
f = FILESYSTEM.open(fname);
if (f)
{
*pSize = f.size();
return (void *)&f;
}
return NULL;
} /* GIFOpenFile() */
void GIFCloseFile(void *pHandle)
{
File *f = static_cast<File *>(pHandle);
if (f != NULL)
f->close();
} /* GIFCloseFile() */
int32_t GIFReadFile(GIFFILE *pFile, uint8_t *pBuf, int32_t iLen)
{
int32_t iBytesRead;
iBytesRead = iLen;
File *f = static_cast<File *>(pFile->fHandle);
// Note: If you read a file all the way to the last byte, seek() stops working
if ((pFile->iSize - pFile->iPos) < iLen)
iBytesRead = pFile->iSize - pFile->iPos - 1; // <-- ugly work-around
if (iBytesRead <= 0)
return 0;
iBytesRead = (int32_t)f->read(pBuf, iBytesRead);
pFile->iPos = f->position();
return iBytesRead;
} /* GIFReadFile() */
int32_t GIFSeekFile(GIFFILE *pFile, int32_t iPosition)
{
int i = micros();
File *f = static_cast<File *>(pFile->fHandle);
f->seek(iPosition);
pFile->iPos = (int32_t)f->position();
i = micros() - i;
// Serial.printf("Seek time = %d us\n", i);
return pFile->iPos;
} /* GIFSeekFile() */
unsigned long start_tick = 0;
void ShowGIF(char *name)
{
start_tick = millis();
if (gif.open(name, GIFOpenFile, GIFCloseFile, GIFReadFile, GIFSeekFile, GIFDraw))
{
x_offset = (MATRIX_WIDTH - gif.getCanvasWidth())/2;
if (x_offset < 0) x_offset = 0;
y_offset = (MATRIX_HEIGHT - gif.getCanvasHeight())/2;
if (y_offset < 0) y_offset = 0;
Serial.printf("Successfully opened GIF; Canvas size = %d x %d\n", gif.getCanvasWidth(), gif.getCanvasHeight());
Serial.flush();
while (gif.playFrame(true, NULL))
{
if ( (millis() - start_tick) > 8000) { // we'll get bored after about 8 seconds of the same looping gif
break;
}
}
gif.close();
}
} /* ShowGIF() */
/************************* Arduino Sketch Setup and Loop() *******************************/
void setup() {
Serial.begin(115200);
delay(1000);
HUB75_I2S_CFG mxconfig(
PANEL_RES_X, // module width
PANEL_RES_Y, // module height
PANEL_CHAIN // Chain length
);
mxconfig.gpio.a = A_PIN;
mxconfig.gpio.b = B_PIN;
mxconfig.gpio.c = C_PIN;
mxconfig.gpio.e = E_PIN;
mxconfig.clkphase = false;
//mxconfig.driver = HUB75_I2S_CFG::FM6126A;
// Display Setup
dma_display = new MatrixPanel_I2S_DMA(mxconfig);
dma_display->begin();
dma_display->setBrightness8(128); //0-255
dma_display->clearScreen();
dma_display->fillScreen(myWHITE);
Serial.println("Starting AnimatedGIFs Sketch");
// Start filesystem
Serial.println(" * Loading SPIFFS");
if(!SPIFFS.begin()){
Serial.println("SPIFFS Mount Failed");
}
dma_display->begin();
/* all other pixel drawing functions can only be called after .begin() */
dma_display->fillScreen(dma_display->color565(0, 0, 0));
gif.begin(LITTLE_ENDIAN_PIXELS);
}
String gifDir = "/"; // play all GIFs in this directory on the SD card
char filePath[256] = { 0 };
File root, gifFile;
void loop()
{
while (1) // run forever
{
root = FILESYSTEM.open(gifDir);
if (root)
{
gifFile = root.openNextFile();
while (gifFile)
{
if (!gifFile.isDirectory()) // play it
{
// C-strings... urghh...
memset(filePath, 0x0, sizeof(filePath));
strcpy(filePath, gifFile.path());
// Show it.
ShowGIF(filePath);
}
gifFile.close();
gifFile = root.openNextFile();
}
root.close();
} // root
delay(1000); // pause before restarting
} // while
}