Skip to Content

← HTTP Client on an ESP32 PLC to Read Machine XML Data

Textile monitoring (weaving)ESP32 PLCHTTPEthernetAcquisition

HTTP Client on an ESP32 PLC to Read Machine XML Data — full example

Poll a knitting machine controller over Ethernet with an ESP32 PLC HTTP client: GET its status XML, parse RPM and state, repackage as JSON for MQTT.

Complete, runnable program for the ESP32 PLC (http-client-xml-terrot.ino): wiring header, requirements and integration notes included.

Download the full project pack — freeThis example + the related ones + bill of materials

Read-only preview.

/*
 * COMPLETE EXAMPLE — HTTP client with XML parsing of a Terrot machine
 *
 * Hardware: ESP32 PLC (Industrial Shields, with Ethernet port)
 * Based on: textile monitoring project, modul_EthWebClient.h
 *
 * Network:
 *   Ethernet  PLC and Terrot knitting machine on the same plant subnet.
 *             The machine exposes its status at http:///statusErw.xml
 *   WiFi      (optional) MQTT output towards the concentrator
 *
 * Architecture:
 *   1. Every 10 s, GET /statusErw.xml to the Terrot controller
 *   2. Response read with a 500 ms timeout (do not block the loop
 *      if the machine is switched off)
 *   3. Tag extraction with getTagValue(): revolutions, RPM, status
 *   4. Repackaged as JSON ready to publish over MQTT
 *
 * Works together with other catalog examples:
 *   - mqtt-events-sd-buffering.ino (JSON output)
 *   - sd-daily-file-datalogging.ino (offline backup of the JSON)
 *   - node-red-multi-plant-concentrator.js (consumption on the server)
 */

#include 

byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x01};
IPAddress plcIP(192, 168, 1, 50);          // fixed IP of the PLC in the plant
IPAddress terrotServer(192, 168, 1, 60);   // controller of the Terrot machine

const int PLC_ID = 1;
const uint32_t POLL_PERIOD_MS = 10000;     // one reading every 10 s
const uint32_t HTTP_TIMEOUT_MS = 500;      // machine off = do not wait

EthernetClient EthClient;
uint32_t tPoll = 0;

// ------------------------------------------------- Minimalist XML parser
// The Terrot responses are flat XML: 23.5... No full parser
// is needed, only extracting the text between tags
String getTagValue(const String &xml, const String &tag) {
  int start = xml.indexOf("<" + tag + ">");
  int end   = xml.indexOf("");
  if (start < 0 || end < 0) return "";
  return xml.substring(start + tag.length() + 2, end);
}

// ------------------------------------------------- GET request with timeout
// Returns the response body, or "" if there is no answer in time
String readTerrotStatus() {
  if (!EthClient.connect(terrotServer, 80)) {
    Serial.println("Terrot: no connection (switched off?)");
    return "";
  }

  EthClient.println("GET /statusErw.xml HTTP/1.1");
  EthClient.println("Host: 192.168.1.60");
  EthClient.println("Connection: close");
  EthClient.println();

  String response = "";
  uint32_t t0 = millis();
  while (millis() - t0 < HTTP_TIMEOUT_MS) {
    while (EthClient.available()) {
      response += (char)EthClient.read();
      t0 = millis();                       // data arriving: extend the window
    }
    if (!EthClient.connected() && !EthClient.available()) break;
  }
  EthClient.stop();

  int body = response.indexOf("\r\n\r\n");     // skip HTTP headers
  return (body >= 0) ? response.substring(body + 4) : response;
}

void setup() {
  Serial.begin(115200);
  Ethernet.begin(mac, plcIP);
  delay(1000);
  Serial.println("Ethernet ready. PLC: " + plcIP.toString());
}

void loop() {
  if (millis() - tPoll >= POLL_PERIOD_MS) {
    tPoll = millis();

    String xml = readTerrotStatus();
    if (xml.length() == 0) return;         // no response: retry in 10 s

    // Fields of the Terrot statusErw.xml
    String revStr  = getTagValue(xml, "revolutions");  // accumulated revolutions
    String rpmStr  = getTagValue(xml, "rpm");          // current speed
    String machStr = getTagValue(xml, "machstat");     // status code

    // Repackage as JSON homogeneous with the rest of the fleet
    String json = "{\"id\":" + String(PLC_ID) +
                  ",\"source\":\"terrot_xml\"" +
                  ",\"revolutions\":" + (revStr.length() ? revStr : "null") +
                  ",\"rpm\":" + (rpmStr.length() ? rpmStr : "null") +
                  ",\"status\":\"" + machStr + "\"}";

    Serial.println(json);
    // In production: publishMessage(TOPIC_DATA, json) -> MQTT + SD backup
  }

  delay(20);
}
Download the full project pack — freeThis example + the related ones + bill of materials