← Comandos remotos MQTT en un PLC ESP32 con topic de respuesta
Monitorización textil (tejeduría)ESP32 PLCMQTTControl
Comandos remotos MQTT en un PLC ESP32 con topic de respuesta — ejemplo completo
Opera una flota de PLC ESP32 con comandos remotos MQTT: topics de petición/respuesta, listado de la SD, info del sistema y gestión segura del callback.
Programa completo y ejecutable para el ESP32 PLC (mqtt-remote-commands.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 commands over MQTT with response topic
*
* Hardware: ESP32 PLC (Industrial Shields, with WiFi + microSD)
* Based on: textile monitoring project, modul_MQTT.h
*
* Network / topics:
* Subscribe: esp32/{ID}/comands (incoming commands)
* Publish: esp32/{ID}/comands_response (PLC response)
*
* Commands supported in this example:
* info -> uptime, heap, IP, RSSI
* list -> .json files on the SD card with their size
* upload -> triggers the HTTP upload of the file (separate module)
*
* Architecture:
* 1. The MQTT callback only enqueues the command (flag + buffer): the
* heavy work (walking the SD card) is done in the loop, not inside
* the callback
* 2. Every response goes out on the *_response topic with the PLC ID:
* a Node-RED console can operate the whole fleet without entering
* the plant
* 3. Unknown command -> explicit error response (diagnostics)
*
* Works together with other catalog examples:
* - sd-file-upload-http-post.ino (executes the upload command)
* - sd-daily-file-datalogging.ino (source of the file listing)
* - node-red-multi-plant-concentrator.js (console that sends the commands)
*/
#include
#include
#include
const char *WIFI_SSID = "WIFI_SSID";
const char *WIFI_PASS = "WIFI_PASS";
const char *MQTT_HOST = "BROKER_IP";
const char *MQTT_USER = "MQTT_USER";
const char *MQTT_PASS = "MQTT_PASS";
const int MQTT_PORT = 1883;
const int PLC_ID = 1;
String topicCmd = "esp32/" + String(PLC_ID) + "/comands";
String topicResp = "esp32/" + String(PLC_ID) + "/comands_response";
WiFiClient net;
PubSubClient mqtt(net);
volatile bool commandAvailable = false;
String pendingCommand = "";
// ------------------------------------------------- Reception (lightweight callback)
void onMqttMessage(char *topic, byte *payload, unsigned int len) {
String cmd = "";
for (unsigned int i = 0; i < len; i++) cmd += (char)payload[i];
cmd.trim();
pendingCommand = cmd; // enqueue: the loop processes it outside the callback
commandAvailable = true;
}
void respond(const String &text) {
mqtt.publish(topicResp.c_str(), text.c_str());
Serial.println("RESP> " + text);
}
// ------------------------------------------------- Command execution
void processCommand(const String &cmd) {
Serial.println("CMD> " + cmd);
if (cmd == "info") {
respond("{\"id\":" + String(PLC_ID) +
",\"uptime_s\":" + String(millis() / 1000) +
",\"heap\":" + String(ESP.getFreeHeap()) +
",\"ip\":\"" + WiFi.localIP().toString() +
"\",\"rssi\":" + String(WiFi.RSSI()) + "}");
} else if (cmd == "list") {
String fileList = "";
File root = SD.open("/");
File f = root.openNextFile();
while (f) {
if (!f.isDirectory() && String(f.name()).endsWith(".json"))
fileList += String(f.name()) + " (" + String(f.size()) + " bytes)\n";
f = root.openNextFile();
}
root.close();
respond(fileList.length() ? fileList : "SD empty");
} else if (cmd.startsWith("upload ")) {
String fileName = cmd.substring(7);
// Delegated to the HTTP upload module (see the corresponding sheet):
// bool ok = uploadFile("/" + fileName);
respond("upload of " + fileName + " triggered");
} else {
respond("ERROR: unknown command '" + cmd +
"'. Supported: info | list | upload ");
}
}
// ------------------------------------------------- Connectivity
void checkMQTT() {
if (WiFi.status() != WL_CONNECTED || mqtt.connected()) return;
if (mqtt.connect(("plc" + String(PLC_ID)).c_str(), MQTT_USER, MQTT_PASS)) {
mqtt.subscribe(topicCmd.c_str()); // re-subscribe after every reconnection
Serial.println("MQTT connected, subscribed to " + topicCmd);
}
}
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);
mqtt.setServer(MQTT_HOST, MQTT_PORT);
mqtt.setCallback(onMqttMessage);
checkMQTT();
}
void loop() {
checkMQTT();
mqtt.loop();
if (commandAvailable) { // process outside the MQTT callback
commandAvailable = false;
processCommand(pendingCommand);
}
delay(20);
}
Descarga el pack completo del proyecto — gratisEste ejemplo + los relacionados + lista de materiales