#include #include #include #include #include "FS.h" #include "SD.h" #include "SPI.h" #include "ESP32-targz.h" #include #define SD_CS_PIN 5 #define RXD2 16 #define TXD2 17 const char* ssid = "112358"; const char* password = "Wawen69$"; String gzFilePath = ""; // Inicialmente vacío, se actualizará dinámicamente String outputFilePath = "/RondanaMini.gcode"; // The output file or directory // Initialize the TarGzUnpacker object TarGzUnpacker tarGz; WebServer server(80); void handleRoot() { File htmlFile = SD.open("/index.html", FILE_READ); // Open the HTML file on the SD card if (!htmlFile) { server.send(404, "text/plain", "File Not Found"); return; } // Send the HTML content as the HTTP response server.streamFile(htmlFile, "text/html"); htmlFile.close(); // Close the file after sending its content } // Logger callback function void targzPrintLoggerCallback(const char* format, ...) { char buf[256]; va_list args; va_start(args, format); vsnprintf(buf, sizeof(buf), format, args); va_end(args); Serial.print(buf); } void handleFileDelete() { if (!server.hasArg("file")) { server.send(400, "text/plain", "Bad Request: No file name provided"); return; } String filename = server.arg("file"); if (!SD.exists(filename)) { server.send(404, "text/plain", "File Not Found"); return; } String nogzFilename; if (filename.endsWith(".gz")) { nogzFilename = filename.substring(0, filename.length() - 3); // Elimina los últimos 3 caracteres (.gz) } else { nogzFilename = filename; } SD.remove(filename); SD.remove(nogzFilename); server.send(200, "text/plain", "File Deleted Successfully"); // Aquí debes enviar un mensaje de actualización a la página web server.send(200, "text/plain", "File Deleted Successfully"); // Vuelve a cargar la lista de archivos en la interfaz server.send(200, "text/plain", "Reload"); } void handleFileUpload() { if (server.uri() != "/upload") return; HTTPUpload& upload = server.upload(); if (upload.status == UPLOAD_FILE_START) { String filename = "/sd" + upload.filename; if (!SD.exists("/sd")) { SD.mkdir("/sd"); } File file = SD.open(filename, FILE_WRITE); if(!file){ Serial.println("Error al abrir el archivo para escribir"); return; } Serial.printf("Subida de archivo: %s\n", filename.c_str()); file.close(); gzFilePath = filename; int lastDotIndex = gzFilePath.lastIndexOf('.'); if (lastDotIndex != -1) { outputFilePath = gzFilePath.substring(0, lastDotIndex); } } else if (upload.status == UPLOAD_FILE_WRITE) { String filename = "/sd" + upload.filename; File file = SD.open(filename, FILE_APPEND); if(file){ file.write(upload.buf, upload.currentSize); file.close(); } } else if (upload.status == UPLOAD_FILE_END) { String message = "Archivo Subido Exitosamente: " + upload.filename + ", Tamaño: " + String(upload.totalSize) + " bytes"; server.send(200, "text/plain", message); Serial.println(message); tarGz.setLoggerCallback(targzPrintLoggerCallback); bool decompressResult = tarGz.gzExpander(SD, gzFilePath.c_str(), SD, outputFilePath.c_str()); if (decompressResult) { Serial.println("Decompression succeeded."); } else { Serial.print("Decompression failed with error: "); Serial.println(tarGz.tarGzGetError()); } } } void handleFileList() { File root = SD.open("/"); String fileList = "["; bool first = true; while (File file = root.openNextFile()) { if (file.isDirectory()) { continue; } if (!first) { fileList += ","; } fileList += "\"" + String(file.name()) + "\""; first = false; } fileList += "]"; server.send(200, "application/json", fileList); } void handlePrint() { // Obtener el nombre del archivo desde el argumento de la solicitud if (!server.hasArg("file")) { server.send(400, "text/plain", "Bad Request: No file name provided"); return; } String filename = server.arg("file"); // Asegura la ruta correcta con el prefijo /sd if (filename.endsWith(".gz")) { filename = filename.substring(0, filename.length() - 3); // Elimina los últimos 3 caracteres (.gz) } // No es necesario el 'else', filename ya tiene el valor correcto if (!SD.exists(filename)) { Serial.println("Archivo no encontrado"); server.send(404, "text/plain", "File Not Found"); return; } File file = SD.open(filename, FILE_READ); if (!file) { Serial.println("Fallo al abrir el archivo para imprimir"); server.send(500, "text/plain", "Failed to open file for printing"); return; } Serial.println("Iniciando impresión..."); // Leer el archivo línea por línea y enviar cada línea a través de UART while (file.available()) { String line = file.readStringUntil('\n'); Serial2.println(line); // Enviar la línea a través de Serial2 // Esperar por la respuesta "OK" de Marlin bool okReceived = false; unsigned long startTime = millis(); while (!okReceived) { // Leer y mostrar respuestas de Marlin para depuración while (Serial2.available()) { String response = Serial2.readStringUntil('\n'); Serial.println(response); // Imprime respuesta en el Serial if (response.indexOf("ok") >= 0) { okReceived = true; break; // Salir del bucle si se recibe "OK" } } // Introduce un timeout para evitar un bucle infinito si nunca se recibe "OK" if (millis() - startTime > 5000) { // Timeout después de 5 segundos Serial.println("Timeout esperando respuesta de Marlin."); break; // Salir del bucle después del timeout } } } file.close(); // Mover file.close() fuera del bucle while server.send(200, "text/plain", "Print job completed successfully"); Serial.println("Trabajo de impresión completado exitosamente"); } String urlDecode(String str) { String decoded = ""; char temp[] = "0x00"; unsigned int len = str.length(); unsigned int i = 0; while (i < len) { if (str[i] == '+') { decoded += ' '; } else if (str[i] == '%') { if (i + 2 < len) { temp[2] = str[i + 1]; temp[3] = str[i + 2]; decoded += (char)strtol(temp, NULL, 16); i += 2; } } else { decoded += str[i]; } i++; } return decoded; } void setup(void) { Serial.begin(115200); // Para la depuración Serial2.begin(250000, SERIAL_8N1, RXD2, TXD2); // Configura el Serial2 a 250000 baudios, que es común en impresoras 3D if(!SD.begin()){ Serial.println("Error al montar la tarjeta SD"); return; } WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi conectado."); Serial.print("Dirección IP del servidor: "); Serial.println(WiFi.localIP()); // Imprime la dirección IP del servidor server.on("/", handleRoot); server.on("/listFiles", HTTP_GET, handleFileList); server.on("/delete", HTTP_GET, handleFileDelete); server.on("/print", HTTP_GET, handlePrint); server.on("/home", HTTP_GET, []() { Serial2.println("G28 ;"); server.send(200, "text/plain", "Enviando impresora a Home"); Serial.println("Enviando G28 a la impresora"); }); // Ruta para mover hacia la derecha. server.on("/derecha", HTTP_GET, []() { Serial2.println("G91 ; Establecer coordenadas relativas"); Serial2.println("G1 X1 F1000 ; Mover 1mm a la derecha"); Serial2.println("G90 ; Establecer coordenadas absolutas"); server.send(200, "text/plain", "Moviendo 1mm a la derecha"); Serial.println("Enviando G1 X1 a la impresora"); }); // Ruta para mover hacia la izquierda. server.on("/izquierda", HTTP_GET, []() { Serial2.println("G91 ; Establecer coordenadas relativas"); Serial2.println("G1 X-1 F1000 ; Mover 1mm a la izquierda"); Serial2.println("G90 ; Establecer coordenadas absolutas"); server.send(200, "text/plain", "Moviendo 1mm a la izquierda"); Serial.println("Enviando G1 X-1 a la impresora"); }); server.on("/arriba", HTTP_GET, []() { Serial2.println("G91 ; Establecer coordenadas relativas"); Serial2.println("G1 Y1 F1000 ; Mover 1mm a enfrente"); Serial2.println("G90 ; Establecer coordenadas absolutas"); server.send(200, "text/plain", "Moviendo 1mm a la derecha"); Serial.println("Enviando G1 X1 a la impresora"); }); // Ruta para mover hacia la izquierda. server.on("/abajo", HTTP_GET, []() { Serial2.println("G91 ; Establecer coordenadas relativas"); Serial2.println("G1 Y-1 F1000 ; Mover 1mm a la izquierda"); Serial2.println("G90 ; Establecer coordenadas absolutas"); server.send(200, "text/plain", "Moviendo 1mm a la izquierda"); Serial.println("Enviando G1 X-1 a la impresora"); }); server.on("/z-mas", HTTP_GET, []() { Serial2.println("G91 ; Establecer coordenadas relativas"); Serial2.println("G1 Z1 F1000 ; Mover 1mm a la derecha"); Serial2.println("G90 ; Establecer coordenadas absolutas"); server.send(200, "text/plain", "Moviendo 1mm a la derecha"); Serial.println("Enviando G1 X1 a la impresora"); }); // Ruta para mover hacia la izquierda. server.on("/z-menos", HTTP_GET, []() { Serial2.println("G91 ; Establecer coordenadas relativas"); Serial2.println("G1 Z-1 F1000 ; Mover 1mm a la izquierda"); Serial2.println("G90 ; Establecer coordenadas absolutas"); server.send(200, "text/plain", "Moviendo 1mm a la izquierda"); Serial.println("Enviando G1 X-1 a la impresora"); }); // Repite la estructura para arriba, abajo, z-mas, z-menos ajustando los comandos del código G. server.on("/upload", HTTP_POST, [](){ server.send(200, "text/plain", ""); }, handleFileUpload); server.on("/download", HTTP_GET, []() { if (!server.hasArg("file")) { server.send(400, "text/plain", "Bad Request: No file name provided"); return; } String filename = server.arg("file"); // Asume que los archivos están en un directorio 'sd' if (!SD.exists(filename)) { server.send(404, "text/plain", "File Not Found"); return; } File file = SD.open(filename, FILE_READ); if (!file) { server.send(500, "text/plain", "Failed to open file"); return; } server.streamFile(file, "application/octet-stream"); file.close(); }); server.onNotFound([](){ server.send(404, "text/plain", "404: Not Found"); }); server.begin(); Serial.println("Servidor HTTP iniciado"); } void loop(void) { server.handleClient(); }