Ir al contenido

← Actualización OTA remota de firmware en ESP32 PLC Ethernet

Monitorización geotécnica de taludESP32 PLC 14 (×4, Ethernet)HTTPResiliencia / OTA

Actualización OTA remota de firmware en ESP32 PLC Ethernet — ejemplo completo

Actualiza el firmware de estaciones ESP32 PLC remotas por Ethernet con un webserver: /status en JSON y OTA en /update. Ejemplo Arduino completo.

Programa completo y ejecutable para el ESP32 PLC 14 (×4, Ethernet) (webserver-status-ota-ethernet.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 — Remote Ethernet station: HTTP status + centralized OTA
 *
 * Hardware:  ESP32 PLC 14 with Ethernet (Industrial Shields)
 * Based on:  geotechnical slope monitoring project (4 stations)
 *
 * Wiring:
 *   I0_0..I0_3  Station sensors (tilt, detectors...)
 *
 * Architecture (replicable across N stations, one IP per station):
 *   - GET  /status    -> JSON with sensor status and alert level 0-4
 *   - POST /update    -> OTA firmware update from the concentrator
 *   - Every 60 s the station also PUSHES its status to the central Node-RED,
 *     which classifies the alert level and triggers email/FTP/dashboard.
 *
 * With several identical stations, only STATION_ID and IP change — the
 * concentrator polls them and pushes firmware without visiting the site.
 */

#include            // ESP32 PLC Ethernet (see Industrial Shields docs)
#include 
#include 
#include 

const int   STATION_ID = 31;
const char *VERSION    = "1.0.0";
const char *CENTRAL    = "http://NODERED_IP:1880/station/status";

IPAddress ip(10, 10, 10, 31), gw(10, 10, 10, 1), mask(255, 255, 255, 0);
WebServer server(80);

const int pins[] = {I0_0, I0_1, I0_2, I0_3};
const int NPINS = 4;
uint32_t tPush = 0;

// Alert level 0-4 based on active sensors (example threshold)
int alertLevel() {
  int n = 0;
  for (int i = 0; i < NPINS; i++) n += digitalRead(pins[i]);
  return n;                                   // 0=normal ... 4=critical
}

String statusJson() {
  String j = "{\"station\":" + String(STATION_ID) +
             ",\"version\":\"" + VERSION +
             "\",\"status\":" + String(alertLevel()) + ",\"inputs\":{";
  for (int i = 0; i < NPINS; i++)
    j += "\"I0_" + String(i) + "\":" + String(digitalRead(pins[i])) +
         (i < NPINS - 1 ? "," : "");
  j += "}}";
  return j;
}

void setup() {
  Serial.begin(115200);
  for (int i = 0; i < NPINS; i++) pinMode(pins[i], INPUT);

  ETH.begin();
  ETH.config(ip, gw, mask);

  // --- GET /status: the concentrator (or a browser) queries the station
  server.on("/status", HTTP_GET, [] {
    server.send(200, "application/json", statusJson());
  });

  // --- POST /update: OTA — upload the new .bin from Node-RED or curl:
  //     curl -F "[email protected]" http://10.10.10.31/update
  server.on("/update", HTTP_POST,
    [] {
      server.sendHeader("Connection", "close");
      server.send(200, "text/plain", Update.hasError() ? "FAIL" : "OK");
      delay(1000);
      ESP.restart();                          // boots with the new firmware
    },
    [] {
      HTTPUpload &up = server.upload();
      if (up.status == UPLOAD_FILE_START) {
        Serial.printf("OTA: %s\n", up.filename.c_str());
        Update.begin(UPDATE_SIZE_UNKNOWN);
      } else if (up.status == UPLOAD_FILE_WRITE) {
        Update.write(up.buf, up.currentSize);
      } else if (up.status == UPLOAD_FILE_END) {
        if (Update.end(true)) Serial.printf("OTA OK: %u bytes\n", up.totalSize);
      }
    });

  server.begin();
  Serial.printf("Station %d at http://%s\n", STATION_ID, ETH.localIP().toString().c_str());
}

void loop() {
  server.handleClient();

  // Periodic push to the concentrator: if a station goes quiet, the hub notices
  if (millis() - tPush > 60000) {
    tPush = millis();
    HTTPClient http;
    http.begin(CENTRAL);
    http.addHeader("Content-Type", "application/json");
    int code = http.POST(statusJson());
    Serial.printf("push -> %d\n", code);
    http.end();
  }
}
Descarga el pack completo del proyecto — gratisEste ejemplo + los relacionados + lista de materiales