Introducción
En este artículo veremos cómo conectarse a tu PLC ESP32 desde un ordenador o un dispositivo móvil mediante comunicación Ethernet. Explicaremos cómo crear un servidor web Ethernet en tu PLC ESP32 al que podrán acceder todos los dispositivos de la misma subred. Con los códigos siguientes aprenderás fácilmente a controlar tu PLC ESP32 desde otro dispositivo, sin depender de conexiones WiFi.
Ejemplo de servidor web
El código siguiente describe un servidor Ethernet básico que atiende las peticiones de una página web para controlar un LED.
Usaremos las librerías Ethernet.h y WebServer.h.
Código:
#include <Ethernet.h>
#include <WebServer.h>
EthernetServer server(80);
byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
IPAddress ip(10, 42, 0, 21);
bool ledStatus = LOW;
void header_page(EthernetClient client, int request_status = 200){ // The first half of the common PHP file
client.println("HTTP/1.1 "+String(request_status)+" Not found");
client.println("Content-Type: text/html");
client.println("Connection: close"); // the connection will be closed after completion of the response
client.println("Refresh: 20"); // refresh the page automatically every 5 sec
client.println();
client.println("<!DOCTYPE HTML>");
client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\"><title>Control LED</title><style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}body{margin-top: 50px;} h1 {color: #444444;margin: 50px auto 30px;} h3 {color: #444444;margin-bottom: 50px;}.button {display: block;width: 80px;background-color: #3498db;border: none;color: white;padding: 13px 30px;text-decoration: none;font-size: 25px;margin: 0px auto 35px;cursor: pointer;border-radius: 4px;}.button-on {background-color: #3498db;}.button-on:active {background-color: #2980b9;}.button-off {background-color: #34495e;}.button-off:active {background-color: #2c3e50;}p {font-size: 14px;color: #888;margin-bottom: 10px;}</style></head>");
client.println("<html><h1>ESP32 Web Server</h1><h3>Using Station Mode</h3>");
}
void footer_page(EthernetClient client){ // The closing lines of every PHP file
client.println("</html>");
}
void handle_OnConnect(EthernetClient client) {
header_page(client);
ledStatus = LOW;
client.println("<a class=\"button button-on\" href=\"/ledOn\">LOW</a>");
footer_page(client);
Serial.println("Connection!\nQ: OFF");
}
void handle_ledOn(EthernetClient client) {
header_page(client);
ledStatus = HIGH;
client.println("<a class=\"button button-on\" href=\"/ledOff\">HIGH</a>");
footer_page(client);
Serial.println("Q: ON");
}
void handle_ledOff(EthernetClient client) {
header_page(client);
ledStatus = LOW;
client.println("<a class=\"button button-on\" href=\"/ledOn\">LOW</a>");
footer_page(client);
Serial.println("Q: OFF");
}
void handle_NotFound(EthernetClient client, String url) {
header_page(client,400);
client.println("<a>The path "+url+" doesn't exist</a>");
Serial.println ("Error, unrecognised path");
}
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {;}
// start the Ethernet connection and the server:
Ethernet.begin(mac, ip);
// Check for Ethernet hardware
if (Ethernet.hardwareStatus() == EthernetNoHardware) {
Serial.println("Ethernet shield was not found.");
while (true) {
delay(1); // do nothing, no point running without Ethernet hardware
}
}
if (Ethernet.linkStatus() == LinkOFF) {
Serial.println("Ethernet cable is not connected.");
}
// start the server
server.begin();
Serial.print("Server is at ");
Serial.println(Ethernet.localIP());
}
void loop() {
// listen for incoming clients
EthernetClient client = server.available();
if (client) {
//Serial.println("new client");
String client_message = "";
int argument_reading = 0;
// An http request ends with a blank line
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
// get arguments. note: path arguments must not have any blank spaces
if (String(c) == " " || String(c) == "?")argument_reading++;
if(argument_reading==1 && String(c)!=" ")client_message = client_message + c;
// check end of request
if (c == '\n' && currentLineIsBlank) {
// Send response
// handle arguments
if (client_message == "/")handle_OnConnect(client);
else if (client_message == "/ledOn")handle_ledOn(client);
else if (client_message == "/ledOff")handle_ledOff(client);
else handle_NotFound(client,client_message);
break;
}
if (c == '\n') {
// you're starting a new line
currentLineIsBlank = true;
} else if (c != '\r') {
// you've gotten a character on the current line
currentLineIsBlank = false;
//Serial.write("We're here");
}
}
}
// give the web browser time to receive the data
delay(1);
// close the connection:
client.stop();
}
// Led control
if (ledStatus) {
digitalWrite(Q0_0, HIGH);
}
else
{
digitalWrite(Q0_0, LOW);
}
}
Al ejecutar este código habrás puesto en marcha un servidor web al que se puede acceder desde cualquier navegador de un dispositivo conectado a la misma red que el PLC. Este ejemplo establece una conexión entre tu ordenador y el servidor web alojado en el ESP32, lo que te permite interactuar con el código HTTP implementado en él y controlar el estado encendido o apagado de un LED de tu PLC ESP32.
Si todo está bien configurado, deberías ver la siguiente página web:
Al pulsar el botón azul se alterna entre LOW y HIGH, y con ello se enciende o se apaga uno de los LED del PLC.
Limitaciones:
Este código reconoce consultas en la URL, pero no es capaz de gestionar peticiones GET ni POST.
Cualquier petición GET cortará la URL en el primer signo de interrogación que encuentre, y las peticiones POST no se gestionarán en absoluto.