← Subir ficheros de la SD desde un PLC ESP32 por HTTP POST
Monitorización textil (tejeduría)ESP32 PLCHTTPComunicación
Subir ficheros de la SD desde un PLC ESP32 por HTTP POST — ejemplo completo
Recupera datos de máquina en búfer: un PLC ESP32 sube ficheros de log de la tarjeta SD a un servidor por HTTP POST con basic auth y entrega confirmada.
Programa completo y ejecutable para el ESP32 PLC (sd-file-upload-http-post.ino): incluye cabecera de conexionado, requisitos y notas de integración.
Descarga el pack completo del proyecto — gratisEste ejemplo + los relacionados + lista de materiales
Vista de solo lectura.
/*
* COMPLETE EXAMPLE — SD file upload over HTTP POST with authentication
*
* Hardware: ESP32 PLC (Industrial Shields, with WiFi + microSD slot)
* Based on: textile monitoring project, modul_MQTT.h
*
* Network:
* The Node-RED concentrator listens on http://:1880/get_data
* with basic authentication. The PLC uploads the daily files from the SD
* card (created by the datalogging module) to fill the gaps left by a
* network outage.
*
* Architecture:
* 1. uploadFile(name): opens the file on the SD card and streams it
* (without loading it into RAM) over HTTP POST
* 2. Basic auth with HTTP_USER/HTTP_PASS and X-File-Name header so
* Node-RED knows which day it is receiving
* 3. The file is only deleted/renamed if the server returns 200
* 4. Triggered on demand: here via Serial; in production it arrives as
* an MQTT command ("upload 2026-06-10.json")
*
* Works together with other catalog examples:
* - sd-daily-file-datalogging.ino (source of the files)
* - mqtt-remote-commands.ino (remote trigger)
* - node-red-multi-plant-concentrator.js (/get_data endpoint)
*/
#include
#include
#include
const char *WIFI_SSID = "WIFI_SSID";
const char *WIFI_PASS = "WIFI_PASS";
const char *SERVER = "CONCENTRADOR_IP"; // Node-RED host
const int PORT = 1880;
const char *HTTP_USER = "HTTP_USER";
const char *HTTP_PASS = "HTTP_PASS";
// ------------------------------------------------- Streaming upload
// Returns true if the server confirmed reception (HTTP 200)
bool uploadFile(const String &fileName) {
if (WiFi.status() != WL_CONNECTED) {
Serial.println("No WiFi: cannot upload " + fileName);
return false;
}
File file = SD.open(fileName, FILE_READ);
if (!file) {
Serial.println("Not found on SD: " + fileName);
return false;
}
HTTPClient http;
http.begin("http://" + String(SERVER) + ":" + String(PORT) + "/get_data");
http.setAuthorization(HTTP_USER, HTTP_PASS); // basic auth
http.addHeader("Content-Type", "text/plain");
http.addHeader("X-File-Name", fileName); // which day is uploaded
http.setTimeout(15000); // large files
// The file is streamed directly from the SD card
int code = http.sendRequest("POST", &file, file.size());
size_t bytes = file.size();
file.close();
http.end();
Serial.println("POST " + fileName + " (" + String(bytes) +
" bytes) -> HTTP " + String(code));
return code == 200;
}
// After a confirmed upload, mark the file as sent
void markAsUploaded(const String &fileName) {
String destination = "/uploaded" + fileName;
SD.mkdir("/uploaded");
if (SD.rename(fileName, destination))
Serial.println("Moved to " + destination);
}
void setup() {
Serial.begin(115200);
SD.begin();
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID, WIFI_PASS);
uint32_t t0 = millis();
while (WiFi.status() != WL_CONNECTED && millis() - t0 < 15000) delay(500);
Serial.println("Ready. Type the name of the file to upload,");
Serial.println("e.g.: /2026-06-10.json");
}
void loop() {
// Console demo; in production this is triggered by an MQTT command
if (Serial.available()) {
String name = Serial.readStringUntil('\n');
name.trim();
if (name.length() == 0) return;
if (!name.startsWith("/")) name = "/" + name;
if (uploadFile(name)) {
markAsUploaded(name); // only if the server confirmed (200)
} else {
Serial.println("Upload failed: the file stays on the SD for retry");
}
}
delay(20);
}
Descarga el pack completo del proyecto — gratisEste ejemplo + los relacionados + lista de materiales