Un servidor web con ESP32, ¿Para qué?
Es posible que te preguntes justo esto. Si lo piensas un momento te darás cuenta (posiblemente con preocupación) que muchas horas de nuestra vida giran alrededor de páginas web. Las consumimos a saco, leemos el periódico, buscamos hoteles, que tiempo va a hacer mañana, etc, etc, etc… Podría estar así hasta que el mundo se acabe.
Bueno, capaz que no tanto :D
En fin, ¿Qué te parece incorporarlo a nuestra domótica casera?
Podríamos saber la temperatura de una habitación, encender luces o apagarlas y todo a través de un servidor web.
Aunque lo más interesante es el hardware donde irá instalado. Un famoso microcontrolador de muy muy pocos euros. El ESP32.
Y, por lo tanto, este artículo va de eso. De quitarse el miedo e ir agregando cada día más posibilidades a tus decisiones.
Para ello vamos a hacer un ejemplo muy sencillo. Apagaremos un par de LED desde nuestro móvil. Y quien dice un LED dice cualquier dispositivo que acepte estados binarios, es decir, ON/OFF, HIGH/LOW, en definitiva 1 o 0.
Vamos allá.
Indice de contenidos
Requisitos del servidor web con ESP32
Puedes utilizar cualquier microcontrolador que tenga capacidad de comunicarse vía TCP/IP, que es el protocolo de comunicaciones que utilizan los servicios WEB en el planeta Tierra.
Ese microcontrolador tiene que poder comunicarse, ya sea por cable o por wifi. Para ello, vamos a utilizar un ESP32 de la empresa Espressif Systems, que aparte de tener una antena Wifi también tiene capacidad de comunicarse vía Bluetooth BLE.
En particular el modelo ESP32-WORM-32.
Esto es lo que necesitas:
- Un entorno de programación: Arduino IDE
- Guía de instalación de la placa ESP32 en Arduino IDE
- Componentes necesarios:
- ESP32, en este artículo un ESP32-WORM-32
- Una base para conectar todos los elementos
- Un par de LED de 5 mm color rojo
- Un par de resistencias de 220 ohmios
- Unos conectores
Si quieres profundizar en esta página encontraras todo lo relevante de todos los modelos ESP32.
¿Qué es un servidor web y cómo funciona?
¿Qué crees que hay detrás de una dirección WEB (URL) que escribes en un navegador (como Chrome, Firefox, etc.)? Por ejemplo, la de un periódico digital http://www.elperiodicodigital.com (no existe, es solo un ejemplo).
Lo que hay detrás es un mínimo de tres entornos que pueden estar separados o no, te lo cuento muy sintetizado, son:
Entiendo que puedas pensar que estoy ampliando demasiado el entorno, lo sé, pero me interesa que entiendas como funciona todo este tinglado a nivel empresarial. Reflexionar a lo grande no es ningún pecado. Quedaros con la idea y nada más.
- Entorno FrontEnd: cuyo principal cometido es servir páginas y formatearlas para hacerlas atractivas a ti, el consumidor. Utilizando diversos idiomas de programación, principalmente HTML, CSS y JavaScript
- Entorno MiddleWare: responsable de la inteligencia de la página. Imagínate que ya has elegido cualquier elemento de una página web dedicada a vender ropa y te propones pagar. Esa gestión la podría hacer perfectamente este entorno, envía una petición a VISA para el cobro y termina enviando una orden para almacenar todos los datos de la venta.
- Entorno BackeEnd: aquí se almacenan los datos, imagínate cuando te das de alta en una web para poder hacer el pago de cualquier producto, normalmente rellenas un formulario (FrontEnd), se procesa los datos del formulario (MiddleWare) que los graba en una base de datos, este es el BackEnd. Donde están los datos persistentes
Dependiendo del dinero que pueda una empresa gastar, estos entornos pueden estar en el mismo servidor o no. Incluso aun separados, cada entorno puede tener 1 o N servidores, además estos pueden crecer o disminuir en función de la carga que tengan.
Un periódico digital es un ejemplo perfecto de esto último, imagínate que publican un bombazo, el servicio puede crecer automáticamente en 2 o N servidores para dar servicio a una concurrencia de clientes alta, cuando la noticia deja de ser un bombazo, de la misma manera, los servidores que componen el servicio del periódico digital decrecerán hasta adecuarse a la concurrencia normal.
Ahora volvamos a la tierra, en nuestro caso solo vamos a servir páginas web con HTML y vamos a formatearlas con un poco de CSS. Y en el proceso, vamos a interactuar con nuestro ESP32 y nuestro móvil.
Y volviendo al principio, cuando escribes una página WEB (URL) en un navegador y pulsas INTRO/ENTER, lo que hace tu navegador es enviar una solicitud HTTP al servidor WEB (GET request). El trabajo se traslada al servidor WEB que debe de poder procesar esa solicitud.
Por ejemplo, imagina que escribes una URL como http://192.168.1.125/ledon en el navegador de vuestro PC o móvil. El navegador envía una solicitud HTTP al ESP32 que procesa esta solicitud, la lee y entiende que el usuario quiere encender un LED, el ESP32 enciende el LED y devuelve una página web al navegador mostrándole el estado del LED: ON
Para lograr este cometido vamos a utilizar dos librerías:
1 2 |
#include <WiFi.h> #include <WebServer.h> |
- WiFi.h: esta librería es la responsable de la conectividad
- WebServer.h: esta librería es la responsable del servicio WEB
Modos de funcionamiento ESP32
El ESP32 con la librería Wifi.h nos posibilita trabajar de varias maneras diferentes. No solo la típica conexión al AP (punto de acceso) de tu router (como cualquier PC o móvil), sino que también permite una conexión directa entre ESP32 y los clientes sin pasar por el router, ni por su punto de acceso Wifi.
- Modo Estación (STA): su comportamiento que como cualquier otro dispuesto en vuestra casa, móvil, PC o tablet.
- Modo de Punto de acceso (AP): en este modo de operar, el ESP32 crea su propia red Wifi, permitiendo conexiones máquina a máquina, estableciendo una comunicación directa entre dos o más estaciones (PC, móvil, Tablets) sin un punto de acceso que enrute el tráfico.
- Existe un tercer modo que es un modo mixto, es decir, es un híbrido que se comporta de los dos modos anteriores.
Cualquiera de estos modos de operar son posibles con ESP32, la diferencia radica en decidir como quieres que se comporte el ESP32.
- Si quieres que se conecte como cualquier otro dispositivo integrado en la red Wifi de casa, debes elegir Modo Estación.
- Si quieres mantenerte al margen con otra red Wifi debes elegir Modo de punto de acceso, es decir, estaríamos aislados de nuestra propia red con el SSID de nuestro ESP32, lógicamente aislado, es aislado, tampoco tendríamos conectividad internet (al menos vía Wifi).
Servidor web con ESP32
Este es el camino que vamos a seguir:
- Se debe conseguir los elementos necesarios (si no dispones de ellos).
- Se diseña el esquema de conexiones.
- Se configura el IDE Arduino para que reconozca nuestra placa ESP32.
- Se sube el código con la configuración Modo Estación.
- Y por último, pruebas de acceso y test.
Compras
- Protoboard, la placa de pruebas donde se pueden insertar componentes electrónicos, o cables hembra-macho.
Te he puesto como opción los cables porque el ESP32 que yo he utilizado para este artículo no cabe en una placa de pruebas estándar, en mi caso (lo verás en las fotos) he partido por la mitad y las he separado, de ahí el tema de los cables. También puedes comprar dos placas de pruebas e insertar cada fila de pines del ESP32 en cada una de las placas de prueba.
- ESP32 – en este caso que voy a utilizar es el modelo ESP32-WORM-32. Como siempre tienes opciones que dependen de la prisa que tengas y lo que quieras arriesgar Amazon y AliExpress.
- Dos resistencias de 220 ohmios.
Las resistencias y los dos LED, van de la mano, es decir, no todos los colores de un LED necesitan la misma resistencia, como no es lo mismo su diámetro, LED de 5 mm o 3 mm.
- Dos LED rojos de 5 mm.
- Cables
Esquema del prototipo de nuestro servidor web con ESP32
El diseño no tiene misterio alguno, solamente debes de tener precaución al colocar los diodos LED en su posición correcta, la patilla más corta llamada cátodo es el negativo que conectaremos al pin GND del ESP32.
Utilizo los pines G4 y G5 para alimentar los LED. Como puedes ver en la imagen.
Nada, del dicho al hecho… en este caso no hay un gran trecho, es muy sencillo, solo atento a la posición del los LED
Código del servidor web con ESP32
He dejado en los comentarios del propio programa las explicaciones más relevantes del código. De todos modos, os dejo una serie de enlaces si quieres profundizar.
Primero debes de configurar tu IDE Arduino para que reconozca tu ESP32 y el puerto de comunicaciones correcto para transmitir y recibir datos por el puerto serie.
Placa: «ESP32 Dev Module».
Puerto: depende de tu sistema operativo COMx para Windows y /dev/xxxxx para los Linux y Mac.
Si quieres ver en profundidad como se configura el IDE de Arduino pásate por esta página, además encontrarás datos sobre el ESP32, pines, características y algunos detalles más.
No olvides subir el siguiente código.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 |
/* * Servidor web con ESP32 * Librerias necesarias para conectarnos a un entorno Wifi y poder configurar * un servidor WEB */ #include <WiFi.h> #include <WebServer.h> /* Añade tu SSID & Clave para acceder a tu Wifi */ const char* ssid = "TU_SSID"; // Tu SSID const char* password = "TU_CLAVE"; //Tu Clave /* Declaramos un objeto de la libreria WebServer para poder acceder a sus funciones Y como parametro 80, que es el puerto estandar de todos los servicios WEB HTTP */ WebServer server(80); /* Declaramos el estado inicial de los LEDs del ESP32 */ uint8_t LED1pin = 4; bool LED1Estado = LOW; uint8_t LED2pin = 5; bool LED2Estado = LOW; /* Todos las siguientes funciones ejecutan tres tareas: 1 Cambian de estado las variables de los LED 2 Muestran por el monitor Serial de Arduino IDE, informacion relevante al estado de los LED 3 Actualizan la vista de la pagina del servidor WEB con ESP32, envia al navegador un codigo 200 indican el exito de la conexion y llama a otra funcion SendHTML con dos parametros que modificaran la pagina del servidor WEB con Arduino. */ void handle_OnConnect() { LED1Estado = LOW; // 1 LED2Estado = LOW; // 1 Serial.println("GPIO4 Estado: OFF | GPIO5 Estado: OFF"); // 2 server.send(200, "text/html", SendHTML(LED1Estado, LED2Estado)); // 3 } void handle_led1on() { LED1Estado = HIGH; //1 Serial.println("GPIO4 Estado: ON"); // 2 server.send(200, "text/html", SendHTML(true, LED2Estado)); //3 } void handle_led1off() { LED1Estado = LOW; Serial.println("GPIO4 Estado: OFF"); server.send(200, "text/html", SendHTML(false, LED2Estado)); } void handle_led2on() { LED2Estado = HIGH; Serial.println("GPIO5 Estado: ON"); server.send(200, "text/html", SendHTML(LED1Estado, true)); } void handle_led2off() { LED2Estado = LOW; Serial.println("GPIO5 Estado: OFF"); server.send(200, "text/html", SendHTML(LED1Estado, false)); } void handle_NotFound() { server.send(404, "text/plain", "La pagina no existe"); } /* Aqui esta definido todo el HTML y el CSS del servidor WEB con ESP32 */ String SendHTML(uint8_t led1stat, uint8_t led2stat) { // Cabecera de todas las paginas WEB String ptr = "<!DOCTYPE html> <html>\n"; // <meta> viewport. Para que la pagina se vea correctamente en cualquier dispositivo ptr += "<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n"; ptr += "<title>Control LED</title>\n"; /* * El estilo de la pagina WEB, tipo de letra, tamaño, colores, * El estilos de los botones (las clases en CSS) y la definicion de como van a cambiar dependiendo de como * cambien los estado de los LEDs, color fondo etc */ ptr += "<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}\n"; ptr += "body{margin-top: 50px;} h1 {color: #444444;margin: 50px auto 30px;} h3 {color: #444444;margin-bottom: 50px;}\n"; ptr += ".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;}\n"; ptr += ".button-on {background-color: #3498db;}\n"; ptr += ".button-on:active {background-color: #2980b9;}\n"; ptr += ".button-off {background-color: #34495e;}\n"; ptr += ".button-off:active {background-color: #2c3e50;}\n"; ptr += "p {font-size: 14px;color: #888;margin-bottom: 10px;}\n"; ptr += "</style>\n"; ptr += "</head>\n"; ptr += "<body>\n"; /* * Encabezados de la pagina */ ptr += "<h1>ESP32 Servidor WEB</h1>\n"; ptr += "<h3>Usando Modo Estacion</h3>\n"; /* * Aqui esta la inteligencia del servidor WEB con ESP32, dependiento de los parametros de la funcion SendHTML * modificara la vista de la pagina WEB, llamaran a las clases "button-on y button-off" que cambian como * se muestran los datos en la pagina WEB */ if (led1stat) { ptr += "<p>LED1 Estado: ON</p><a class=\"button button-off\" href=\"/led1off\">OFF</a>\n"; } else { ptr += "<p>LED1 Estado: OFF</p><a class=\"button button-on\" href=\"/led1on\">ON</a>\n"; } if (led2stat) { ptr += "<p>LED2 Estado: ON</p><a class=\"button button-off\" href=\"/led2off\">OFF</a>\n"; } else { ptr += "<p>LED2 Estado: OFF</p><a class=\"button button-on\" href=\"/led2on\">ON</a>\n"; } ptr += "</body>\n"; ptr += "</html>\n"; return ptr; } void setup() { /* * Declaracion de la velocidad de comunicacion entre Arduino IDE y ESP32 * Configura el comportamiento de los pines */ Serial.begin(115200); pinMode(LED1pin, OUTPUT); pinMode(LED2pin, OUTPUT); /* * Configuracion de la conexion a la Wifi de tu casa */ WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); Serial.println(""); // Wait for connection while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.print("Conectado a "); Serial.println(ssid); Serial.print("Direccion IP: "); Serial.println(WiFi.localIP()); /* * Para procesar las solicitudes HTTP necesitamos definir el codigo que debe de ejecutar en * cada estado. Para ello utilizamos el metodo "on" de la libreria WebServer que hemos * habilitador en la linea 13 de este codigo * 1 El primero se ejecuta cuando te conectas al Servidor WEB con ESP32 http://la_ip_del_esp32/ * 2 Los 4 siguientes procesan los 2 estados que puede tener cada LED ON/OFF * 3 El ultimo gestiona los errores por ejemplo si pones http://la_ip_del_esp32/holaquetal * esta pagina no existe, por lo tanto actualizara la pagina WEB con un mensaje de error */ server.on("/", handle_OnConnect); // 1 server.on("/led1on", handle_led1on); // 2 server.on("/led1off", handle_led1off); // 2 server.on("/led2on", handle_led2on); // 2 server.on("/led2off", handle_led2off); // 2 server.onNotFound(handle_NotFound); // 3 /* * Arrancamos el Servicio WEB */ server.begin(); Serial.println("Servidor HTTP iniciado"); } /* * Para gestionar las la peticiones HTTP es necesario llamar al metodo "handleClient" * de la libreria WebServer que se encarga de recibir las peticiones y lanzar las fuciones * de callback asociadas tipo "handle_led1on()" "handle_led2on()" etc * Tambien ejecutan el cambio de estado de los pines y por lo tanto hacen que los * LEDs se enciendan o apaguen */ void loop() { server.handleClient(); if (LED1Estado) { digitalWrite(LED1pin, HIGH); } else { digitalWrite(LED1pin, LOW); } if (LED2Estado) { digitalWrite(LED2pin, HIGH); } else { digitalWrite(LED2pin, LOW); } } |
Aquí dejo unos enlaces de interés:
Acceso al servidor web con ESP32
Para acceder a la página del servidor web con ESP32 y ver los mensajes solo tienes que abrir el Monitor Serie, luego de esto, si todo ha ido bien, debes de ver algo parecido a esto:
Verás claramente la IP con la que el servidor web con ESP32 presenta la página.
Accede ahora con tu móvil (o PC) a la dirección http://192.168.1.39 (en mi caso, pero a ti seguro que te aparecerá otra IP).
Si todo ha ido bien, verás que al pulsar alguno de los botones, aparte de aparecer en el Monitor Serie el correspondiente mensaje, el LED se encenderá o apagara.
Puedes jugar a cambiar los colores, modificando el código, por ejemplo, añadiendo un color de fondo
1 |
ptr += "body{margin-top: 50px;background-color: #e5dce2} ......" |
O cambiar los colores de los botones.
1 |
ptr += ".button-on {background-color: #cc1a1a;}\n"; |
Conclusión sobre servidor web con ESP32
Como comente al principio puedes conectar cualquier dispositivo electrónico que responda a un ON/OFF. El ESP32 es pequeño, pero matón y poder acceder vía WEB lo hace bastante atractivo.
Lo que hemos visto es una pequeña pincelada, como ejemplo, la librería WebServer.h no nos permite conexiones simultáneas, para ello necesitamos otra librería, ESPAsyncWebServer que hace que el ESP32 se comporte como un servidor asíncrono. En el propio Arduino IDE tienes ejemplos.
También si ya sabes algo de html y css, existe una manera de poder trabajar con ficheros tipo index.html o micss.css, sin las complicaciones de compilarlos con otro lenguaje de programación, en este caso C++.
Me refiero a SPIFFS (SPI Flash File System), un sistema de ficheros para trabajar con la memoria flash del nuestro ESP32. Este artículo está en inglés, pero es muy bueno.
Bueno, ¿Quién dijo miedo? A por ello. Ciao
Gracias a Depositphotos por la cesión de las imágenes.