Empezando con Web para Arduino/Esp8266
1. Introducción:
La forma más fácil de crear un interface para el usuario, puede ser mediante una web embebida.
En este punto, describiremos cómo crear una web sencilla. Como también estoy aprendiendo, voy buscando información
y mirando páginas que expliquen las cosas. Una de esas páginas es la siguiente:
StartingElectronics.
Es de agradecer, que haya páginas que dediquen tiempo a explicar y ayudar a los que no sabemos tanto.
2. Empezando:
En este caso, el servidor Web puede ser un Arduino con ethernet o un módulo ESP8266 y el cliente un navegador Web.
El sistema funciona, de tal forma que el cliente establece la conexión y solicita una serie de información; el servidor
se encarga de responder.
Para llevar a cabo la comunicación, se hace mediante programación HTML:
Html significa "HyperText Markup Language" que es "Lenguaje de Formato de Documentos para Hipertexto".
Este lenguaje se encarga de desarrollar una descripción sobre los contenidos que aparecen como textos y sobre su estructura,
complementando dicho texto con diversos objetos (fotografías, animaciones, etc).
Digamos que HTML, son las instrucciones que le indican al navegador Web cómo tiene que presentar la información que le pasa.
2.1. Estructura de una página Web:
Todo lo contenido entre las etiquetas <head> ... </head> es el encabezado de la página que contiene información acerca del
documento como una breve descripción que identificará la página.
Todo lo contenido entre las etiquetas <body> ... </body> es lo que describirá la página Web como el color de fondo o una imagen
el color del texto, el tipo de letra, ...

2.2. Descripción del funcionamiento:
Todo empieza cuando desde un explorador Web, se accede a la dirección del servidor Web.
El cliente envía una serie de líneas indicándole al servidor desde qué explorador inicia la comunicación, el idioma,
la versión, . Terminando con una línea en blanco ("\r\n") que indicará al servidor que puede responder:

El servidor responde enviando unas líneas estándar:

Seguido de la página Web en sí.

Si escribimos lo anterior en un fichero y lo guardamos con extensión .html; al hacer doble click, se nos abre el navegador Web predeterminado y nos muestran la página:


3. Empezando:
Una vez hemos visto cómo funciona una página Web sencilla, tenemos que entender cómo la gestiona Arduino para
implementarla en el programa.
Como hemos dicho, lo que se desarrolla es una conversación entre el navegador Web y en este caso nuestro Arduino; es
decir, se envían tramas TCP cliente-servidor.
Los pasos desde el Arduino:
- Arduino tiene un servicio servidor TCP, escuchando en el puerto 80 (puerto por defecto para conexiones Web; podemos usar otro, pero entonces debemos indicarle al navegador a qué puerto debe conectarse.)
- Cuando Arduino detecte una conexión en el puerto TCP, empezará a capturar caracteres hasta econtrar "/r/n" (salto de línea).
- Acto seguido, responde con una cadena HTTP estándar.
- Toca procesar lo recibido. En este punto, es dónde vemos si es necesario enviar toda la página o sólo algún dato para actualizar algo en concreto. Veremos más adelante, que no es necesario refrescar toda la página sólo para actualizar un campo.
- Cierra la conexión.
- En espera de nueva conexión.
3.1. Adaptando código a Arduino:

El código en Arduino:
#include#include byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; //La mac que asignaremos al Wiznet IPAddress ip(192, 168, 168, 168); //La dirección asignada EthernetServer server(80); //Puerto de escucha del servidor String respuestaCliente; //String que almacenará la petición del cliente void setup() { Serial.begin(9600); //Inicializamos la conexión Serie para ver lo que sucede Ethernet.begin(mac, ip); //Inicializamos la conexión Ethernet server.begin(); //Levantamos el servidor escuchando en el puerto definido Serial.print("server is at "); //Por puerto Serie, nos indica qué IP tiene Serial.println(Ethernet.localIP()); } void loop() { EthernetClient client = server.available(); //Creamos un elemento client char c; //Variable para almacenar caracteres recibidos if (client) //Comprobamos si client ha recibido solicitud de conexión { Serial.println("Cliente nuevo"); boolean currentLineIsBlank = true; //Variable que nos indicará que hemos recibido línea nueva while (client.connected()) { while (client.available() > 0) //Recogemos todos los datos del buffer y los almacenamos en respuestaCliente { c = client.read(); respuestaCliente += c; } if (c == '\n' && currentLineIsBlank) { //Sacamos por puerto Serie lo recibido Serial.println(respuestaCliente); //Enviamos respuesta HTTP estándar client.println(F("HTTP/1.1 200 OK")); client.println(F("Content-Type: text/html")); client.println(F("Connection: close")); client.println(); //Podemos procesar la respuesta para ver si enviamos toda la pagina o solo actualizamos un campo //Si queremos detectar una palabra clave para hacer algo //Enviamos pagina client.println(F("<!DOCTYPE HTML>")); client.println(F("<html>")); client.println(F("<head>")); client.println(F("<title> MicroEdu Web</title>")); client.println(F("</head>")); client.println(F("<body> <h1> Hola desde Arduino! </h1>")); client.println(F("<p> Servidor Web desde Arduino </p>")); client.println(F("</body></html>")); break; } if (c == '\n') { currentLineIsBlank = true; //Nos preparamos para otra conexion respuestaCliente=" "; //Vaciamos la cadena recibida } else if (c != '\r') { currentLineIsBlank = false; //Aun no hemos terminado esta conexion } client.flush(); } } delay(1); client.stop(); }
El resultado:

4. Ejemplo control led:
En este ejemplo, manipularemos un led según un "botón".
Código en HTML:
Nota: Como el botón cambia de color y texto, se intercala una sentencia if-else
para que Arduino escoja según el estado de la varible "estadoLed". Este código no es HTML.
<!DOCTYPE html> <html> <head> <title> MicroEdu Web </title> </head> <body> <h1> LED </h1> //En esta parte, Arduino escoge qué mostrar según el estado del led if (estadoLed) { <p> Pulsa para cambiar el estado del led: Led Encendido </p> <input type=submit value=OFF style=width:100px;height:45px;background-color:green onClick=location.href="/?Led=Off"> } else { <<p> Pulsa para cambiar el estado del led: Led Apagado </p> <input type=submit value=ON style=width:100px;height:45px;background-color:red onClick=location.href="/?Led=On"> } </body> </html>
El código en Arduino:
#include#include byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; //La mac que asignaremos al Wiznet IPAddress ip(192, 168, 168, 168); //La dirección asignada EthernetServer server(80); //Puerto de escucha del servidor String respuestaCliente; //String que almacenará la petición del cliente boolean estadoLed = false; //Variable que almacena el estado del Led void setup() { Serial.begin(9600); //Inicializamos la conexión Serie para ver lo que sucede Ethernet.begin(mac, ip); //Inicializamos la conexión Ethernet server.begin(); //Levantamos el servidor escuchando en el puerto definido Serial.print("server is at "); //Por puerto Serie, nos indica qué IP tiene Serial.println(Ethernet.localIP()); } void loop() { EthernetClient client = server.available(); //Creamos un elemento client char c; //Variable para almacenar caracteres recibidos if (client) //Comprobamos si client ha recibido solicitud de conexión { Serial.println("Cliente nuevo"); boolean currentLineIsBlank = false; //Variable que nos indicará que hemos recibido línea nueva while (client.connected()) { while (client.available() > 0) //Recogemos todos los datos del buffer y los almacenamos en respuestaCliente { c = client.read(); respuestaCliente += c; } if (c == '\n' && currentLineIsBlank) { //Sacamos por puerto Serie lo recibido Serial.println(respuestaCliente); //Enviamos respuesta HTTP estándar client.println(F("HTTP/1.1 200 OK")); client.println(F("Content-Type: text/html")); client.println(F("Connection: close")); client.println(); //Podemos procesar la respuesta para ver si enviamos toda la pagina o solo actualizamos un campo //Si queremos detectar una palabra clave para hacer algo procesar(); //Enviamos pagina client.println(F("<!DOCTYPE HTML>")); client.println(F("<html>")); client.println(F("<head>")); client.println(F("<title> MicroEdu Web</title>")); client.println(F("</head>")); client.println(F("<body> <h1> LED </h1>")); if (estadoLed) //Si el led esta activo { client.println(F("<p> Pulsa para cambiar el estado del led: Led Encendido </p>")); client.print("<input type=submit value=OFF style=width:100px;height:45px;background-color:green onClick=location.href='/?Led=Off'>"); } else //Si el led no esta activo { client.println(F("<p> Pulsa para cambiar el estado del led: Led Apagado </p>")); client.print("<input type=submit value=ON style=width:100px;height:45px;background-color:red onClick=location.href='/?Led=On'>"); } client.println(F("</body></html>")); client.println(); break; } if (c == '\n') { currentLineIsBlank = true; //Nos preparamos para otra conexion Serial.println("Empezamos ..."); } else if (c != '\r') { currentLineIsBlank = false; //Aun no hemos terminado esta conexion Serial.println("No hemos terminado ..."); } client.flush(); } } delay(1); client.stop(); } void procesar() { if (respuestaCliente.indexOf("/?Led") > -1) { // Importante buscar la clave GET if (respuestaCliente.indexOf("GET /?Led=Off") > -1) //Encontrada palabra clave "Led=Off" { estadoLed = false; Serial.println("Apagar Led"); } else if (respuestaCliente.indexOf("GET /?Led=On") > -1) //Encontrada palabra clave "Led=On" { estadoLed = true; Serial.println("Encender Led"); } else { Serial.println("Palabra clave no encontrada"); } respuestaCliente=""; } }
El resultado:

5. Ejemplo monitorizar estado pulsador:
En este ejemplo, monitorizaremos el estado del pin 7 de Arduino a través de la página Web.
Código en HTML:
Nota: Como hay un cambio de texto, se intercala una sentencia if-else
para que Arduino escoja según el estado del pulsador la frase a mostrar. Este código no es HTML.
<!DOCTYPE html> <html> <head> <title> MicroEdu Web </title> //Sentencia que le indica al navegador Web que refresque la página cada 5 segundos <meta http-equiv=\"refresh\" content=\"5\"> </head> <body> <h1> PULSADOR </h1> //En esta parte, Arduino escoge qué mostrar según el estado del led if (digitalRead(7)) //Si el pin 7 esta a nivel alto { <p> Estado del pulsador: Activado </p> } else //Si el pin 7 esta a nivel alto { <p> Estado del pulsador: Desactivado </p> } </body> </html>
El código en Arduino:
#include#include byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; //La mac que asignaremos al Wiznet IPAddress ip(192, 168, 168, 168); //La dirección asignada EthernetServer server(80); //Puerto de escucha del servidor String respuestaCliente; //String que almacenará la petición del cliente void setup() { Serial.begin(9600); //Inicializamos la conexión Serie para ver lo que sucede Ethernet.begin(mac, ip); //Inicializamos la conexión Ethernet server.begin(); //Levantamos el servidor escuchando en el puerto definido Serial.print("server is at "); //Por puerto Serie, nos indica qué IP tiene Serial.println(Ethernet.localIP()); pinMode(7, INPUT); //Configuramos el pin 7 como entrada } void loop() { EthernetClient client = server.available(); //Creamos un elemento client char c; //Variable para almacenar caracteres recibidos if (client) //Comprobamos si client ha recibido solicitud de conexión { Serial.println("Cliente nuevo"); boolean currentLineIsBlank = false; //Variable que nos indicará que hemos recibido línea nueva while (client.connected()) { while (client.available() > 0) //Recogemos todos los datos del buffer y los almacenamos en respuestaCliente { c = client.read(); respuestaCliente += c; } if (c == '\n' && currentLineIsBlank) { //Sacamos por puerto Serie lo recibido Serial.println(respuestaCliente); //Enviamos respuesta HTTP estándar client.println(F("HTTP/1.1 200 OK")); client.println(F("Content-Type: text/html")); client.println(F("Connection: close")); client.println(); //Podemos procesar la respuesta para ver si enviamos toda la pagina o solo actualizamos un campo //Si queremos detectar una palabra clave para hacer algo //procesar(); //Enviamos pagina client.println(F("<!DOCTYPE HTML>")); client.println(F("<html>")); client.println(F("<head>")); client.println(F("<meta http-equiv=\"refresh\" content=\"5\">")); client.println(F("<title> MicroEdu Web</title>")); client.println(F("</head>")); client.println(F("<body> <h1> PULSADOR </h1>")); if (digitalRead(7)) //Si el pin 7 esta a nivel alto { client.println(F("<p> Estado del pulsador: Activado </p>")); } else //Si el pin 7 esta a nivel alto { client.println(F("<p> Estado del pulsador: Desactivado </p>")); } client.println(F("</body></html>")); client.println(); break; } if (c == '\n') { currentLineIsBlank = true; //Nos preparamos para otra conexion Serial.println("Empezamos ..."); } else if (c != '\r') { currentLineIsBlank = false; //Aun no hemos terminado esta conexion Serial.println("No hemos terminado ..."); } client.flush(); } } delay(1); client.stop(); }
El resultado:

6. Descargas: