Arduino - Servidor Web con Varias Páginas
En este tutorial, aprenderemos cómo convertir un Arduino en un servidor web que pueda manejar varias páginas al mismo tiempo, como index.html, temperature.html, led.html, error_404.html y error_405.html... El contenido de cada página, incluidos HTML, CSS y JavaScript, se almacenará en archivos diferentes en el IDE de Arduino. Al acceder al Arduino Web Server desde un navegador web en tu PC o teléfono inteligente, podrás ver y controlar sensores y actuadores conectados al Arduino a través de la web. Además, el servidor web estará diseñado para aceptar enlaces con o sin la extensión .html.
Siguiendo este tutorial, podrás convertir tu Arduino en un servidor web con algunas características interesantes:
Múltiples páginas web están activas simultáneamente.
El contenido HTML (incluido HTML, CSS y JavaScript) para cada página se mantiene por separado en su propio archivo.
El contenido HTML puede actualizarse dinámicamente con valores en tiempo real de sensores, haciendo que las páginas web sean dinámicas y receptivas.
Puede acceder a las páginas con o sin la extensión .html. Por ejemplo, puede usar enlaces como http://192.168.0.2/led o http://192.168.0.2/led.html para acceder a la misma página de control LED.
El servidor web maneja códigos de error HTTP como 404 Not Found y 405 Method Not Allowed
Puede parecer complicado, ¡pero no te preocupes! Este tutorial ofrece instrucciones paso a paso, y el código está diseñado para ser amigable para principiantes, asegurando que puedas comprenderlo fácilmente y crear tu propio servidor web de Arduino.
Or you can buy the following kits:
Divulgación: Algunos de los enlaces proporcionados en esta sección son enlaces de afiliado de Amazon. Podemos recibir una comisión por las compras realizadas a través de estos enlaces sin costo adicional para usted. Apreciamos su apoyo.
Si no estás familiarizado con Arduino Uno R4 y el servidor web (incluido el diagrama de pines, cómo funciona y la programación), puedes aprender sobre ellos a través de los siguientes tutoriales:
Cuando un navegador web envía una solicitud HTTP a la placa Arduino, el Arduino debe estar programado para realizar las siguientes tareas:
Crear un servidor web que pueda escuchar solicitudes HTTP desde el navegador web.
Leer la primera línea de la cabecera de la solicitud HTTP cuando reciba una solicitud HTTP.
Enrutar las solicitudes basándose en la primera línea de la solicitud HTTP para determinar qué páginas web debe devolver el Arduino.
(Opcional) Analizar la cabecera de la solicitud HTTP para identificar comandos de control enviados por el usuario.
(Opcional) Controlar los dispositivos conectados al Arduino en función de los comandos de control recibidos.
Enviar una respuesta HTTP de vuelta al navegador web, que incluye:
Una cabecera de respuesta HTTP.
El cuerpo de la respuesta HTTP, que contiene contenido HTML y (si procede) datos de sensores o el estado de los dispositivos.
Al realizar estas tareas, el Arduino puede manejar eficazmente las solicitudes HTTP y proporcionar respuestas adecuadas al navegador web, lo que permite el control e interacción basados en la web con los dispositivos conectados al Arduino.
La función de enrutamiento es la tarea más importante y se explicará en detalle. Otras partes están cubiertas en el tutorial Arduino - Web Server. Una vez que entiendas el algoritmo de enrutamiento, procederemos a ver el código completo de un servidor web con múltiples páginas.
Antes de escribir código para la función de enrutamiento, deberías crear una lista de páginas web y sus métodos HTTP correspondientes que estén disponibles en Arduino. En este tutorial, solo soportaremos el método GET. Sin embargo, puedes ampliarlo fácilmente para incluir otros métodos HTTP si es necesario. A continuación, se muestra una lista de ejemplo:
Después de eso, necesitas crear una lista de las cabeceras de la primera línea de la solicitud HTTP correspondientes a la lista de páginas:
GET página de inicio:
GET página de temperatura
GET página de la puerta
GET página de LED
En resumen, tenemos la siguiente lista:
GET /
GET /index.html
GET /temperature.html
GET /door.html
GET /led.html
A continuación se presenta el código completo de Arduino que crea un servidor web con varias páginas. Para mantenerlo sencillo, el contenido HTML de cada página es muy simple y está incrustado directamente en el código de Arduino. En la próxima parte, aprenderemos cómo separar los contenidos HTML de cada página en archivos separados, lo que hará que el código esté más organizado y manejable.
#include <UnoR4WiFi_WebServer.h>
const char WIFI_SSID[] = "YOUR_WIFI_SSID";
const char WIFI_PASSWORD[] = "YOUR_WIFI_PASSWORD";
UnoR4WiFi_WebServer server;
float getTemperature() {
float temp_x100 = random(0, 10000);
return temp_x100 / 100;
}
void handleHome(WiFiClient& client, const String& method, const String& request, const QueryParams& params, const String& jsonData) {
server.sendResponse(client, "This is home page");
}
void handleTemperature(WiFiClient& client, const String& method, const String& request, const QueryParams& params, const String& jsonData) {
server.sendResponse(client, "This is temperature page");
}
void handleDoor(WiFiClient& client, const String& method, const String& request, const QueryParams& params, const String& jsonData) {
server.sendResponse(client, "This is door page");
}
void handleLed(WiFiClient& client, const String& method, const String& request, const QueryParams& params, const String& jsonData) {
server.sendResponse(client, "This is LED page");
}
void handleNotFound(WiFiClient& client, const String& method, const String& request, const QueryParams& params, const String& jsonData) {
server.sendResponse(client, "Page Not Found");
}
void setup() {
Serial.begin(9600);
delay(1000);
Serial.println("Arduino Uno R4 WiFi - Multi-Page Web Server");
Serial.print("Connecting to ");
Serial.println(WIFI_SSID);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println(" connected!");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
server.addRoute("/", handleHome);
server.addRoute("/index", handleHome);
server.addRoute("/index.html", handleHome);
server.addRoute("/temperature", handleTemperature);
server.addRoute("/temperature.html", handleTemperature);
server.addRoute("/door", handleDoor);
server.addRoute("/door.html", handleDoor);
server.addRoute("/led", handleLed);
server.addRoute("/led.html", handleLed);
server.setNotFoundHandler(handleNotFound);
server.begin();
Serial.println("\n=== Web Server Ready! ===");
Serial.print("Visit: http://");
Serial.println(WiFi.localIP());
}
void loop() {
server.handleClient();
}
Abre el Administrador de Bibliotecas haciendo clic en el icono Administrador de Bibliotecas ubicado en el lado izquierdo del IDE de Arduino.
Busca Web Server for Arduino Uno R4 WiFi y localiza la biblioteca Web Server creada por DIYables.
Haz clic en el botón Instalar para agregar la biblioteca Web Server.
Copia el código anterior y ábrelo con el IDE de Arduino
Cambia la información de wifi (SSID y contraseña) en el código por la tuya
Haz clic en el botón Subir en el IDE de Arduino para subir el código al Arduino
Abre el Monitor serie
Revisa el resultado en el Monitor serie
Connecting to YOUR_WIFI_SSID
connected!
IP address: 192.168.0.254
Starting web server on IP: 192.168.0.254
=== Web Server Ready! ===
Visit: http://192.168.0.254
Verás una dirección IP en el Monitor Serial, por ejemplo: 192.168.0.2
Escribe la siguiente lista uno por uno en la barra de direcciones de un navegador web en tu teléfono móvil o PC.
192.168.0.2
192.168.0.2/index
192.168.0.2/index.html
192.168.0.2/led
192.168.0.2/led.html
192.168.0.2/door
192.168.0.2/door.html
192.168.0.2/temperature
192.168.0.2/temperature.html
192.168.0.2/blabla
192.168.0.2/blabla.html
Por favor, tenga en cuenta que debe cambiar la 192.168.0.2 por la dirección IP que obtuvo en el Monitor Serial.
Verá las siguientes páginas: página de inicio, página de LED, página de la puerta, página de temperatura y la página No Encontrada.
También puede ver la salida en el Monitor Serial.
El código anterior tiene un contenido HTML muy simple para cada página. Pero si queremos crear una interfaz elegante con mucho HTML, el código puede hacerse grande y desordenado. Para simplificarlo, aprenderemos cómo separar el HTML del código de Arduino. Esto nos permite mantener el HTML en archivos separados, lo que facilita su gestión y uso.
Abre el IDE de Arduino.
Crea un nuevo sketch y asígnale un nombre, por ejemplo, ArduinoWebServer.ino.
Copia el código proporcionado y pégalo en ese archivo.
#include <UnoR4WiFi_WebServer.h>
#include "index.h"
#include "temperature.h"
#include "door.h"
#include "led.h"
#include "error_404.h"
const char WIFI_SSID[] = "YOUR_WIFI_SSID";
const char WIFI_PASSWORD[] = "YOUR_WIFI_PASSWORD";
UnoR4WiFi_WebServer server;
float getTemperature() {
float temp_x100 = random(0, 10000);
return temp_x100 / 100;
}
void handleHome(WiFiClient& client, const String& method, const String& request, const QueryParams& params, const String& jsonData) {
server.sendResponse(client, HTML_CONTENT_HOME);
}
void handleTemperature(WiFiClient& client, const String& method, const String& request, const QueryParams& params, const String& jsonData) {
String html = String(HTML_CONTENT_TEMPERATURE);
html.replace("TEMPERATURE_MARKER", String(getTemperature(), 2));
server.sendResponse(client, html.c_str());
}
void handleDoor(WiFiClient& client, const String& method, const String& request, const QueryParams& params, const String& jsonData) {
String html = String(HTML_CONTENT_DOOR);
html.replace("DOOR_STATE_MARKER", "OPENED");
server.sendResponse(client, html.c_str());
}
void handleLed(WiFiClient& client, const String& method, const String& request, const QueryParams& params, const String& jsonData) {
String html = String(HTML_CONTENT_LED);
html.replace("LED_STATE_MARKER", "OFF");
server.sendResponse(client, html.c_str());
}
void handleNotFound(WiFiClient& client, const String& method, const String& request, const QueryParams& params, const String& jsonData) {
String html = String(HTML_CONTENT_404 );
server.sendResponse(client, html.c_str());
}
void setup() {
Serial.begin(9600);
delay(1000);
Serial.println("Arduino Uno R4 WiFi - Multi-Page Web Server");
Serial.print("Connecting to ");
Serial.println(WIFI_SSID);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println(" connected!");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
server.addRoute("/", handleHome);
server.addRoute("/index", handleHome);
server.addRoute("/index.html", handleHome);
server.addRoute("/temperature", handleTemperature);
server.addRoute("/temperature.html", handleTemperature);
server.addRoute("/door", handleDoor);
server.addRoute("/door.html", handleDoor);
server.addRoute("/led", handleLed);
server.addRoute("/led.html", handleLed);
server.setNotFoundHandler(handleNotFound);
server.begin();
Serial.println("\n=== Web Server Ready! ===");
Serial.print("Visit: http://");
Serial.println(WiFi.localIP());
}
void loop() {
server.handleClient();
}
Cambia la información de WiFi (SSID y contraseña) en el código por la tuya
Crea el archivo index.h en el IDE de Arduino haciendo:
const char *HTML_CONTENT_HOME = R""""(
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" href="data:,">
<title>Home Page</title>
</head>
<body>
<h1>Welcome to the Home Page</h1>
<ul>
<li><a href="/led">LED Page</a></li>
<li><a href="/temperature">Temperature Page</a></li>
<li><a href="/door">Door Page</a></li>
</ul>
</body>
</html>
)"""";
const char *HTML_CONTENT_TEMPERATURE = R""""(
<!DOCTYPE html>
<html>
<head>
<title>Arduino - Web Temperature</title>
<meta name="viewport" content="width=device-width, initial-scale=0.7, maximum-scale=0.7">
<meta charset="utf-8">
<link rel="icon" href="https://diyables.io/images/page/diyables.svg">
<style>
body { font-family: "Georgia"; text-align: center; font-size: width/2pt;}
h1 { font-weight: bold; font-size: width/2pt;}
h2 { font-weight: bold; font-size: width/2pt;}
button { font-weight: bold; font-size: width/2pt;}
</style>
<script>
var cvs_width = 200, cvs_height = 450;
function init() {
var canvas = document.getElementById("cvs");
canvas.width = cvs_width;
canvas.height = cvs_height + 50;
var ctx = canvas.getContext("2d");
ctx.translate(cvs_width/2, cvs_height - 80);
update_view(TEMPERATURE_MARKER);
}
function update_view(temp) {
var canvas = document.getElementById("cvs");
var ctx = canvas.getContext("2d");
var radius = 70;
var offset = 5;
var width = 45;
var height = 330;
ctx.clearRect(-cvs_width/2, -350, cvs_width, cvs_height);
ctx.strokeStyle="blue";
ctx.fillStyle="blue";
var x = -width/2;
ctx.lineWidth=2;
for (var i = 0; i <= 100; i+=5) {
var y = -(height - radius)*i/100 - radius - 5;
ctx.beginPath();
ctx.lineTo(x, y);
ctx.lineTo(x - 20, y);
ctx.stroke();
}
ctx.lineWidth=5;
for (var i = 0; i <= 100; i+=20) {
var y = -(height - radius)*i/100 - radius - 5;
ctx.beginPath();
ctx.lineTo(x, y);
ctx.lineTo(x - 25, y);
ctx.stroke();
ctx.font="20px Georgia";
ctx.textBaseline="middle";
ctx.textAlign="right";
ctx.fillText(i.toString(), x - 35, y);
}
ctx.lineWidth=16;
ctx.beginPath();
ctx.arc(0, 0, radius, 0, 2 * Math.PI);
ctx.stroke();
ctx.beginPath();
ctx.rect(-width/2, -height, width, height);
ctx.stroke();
ctx.beginPath();
ctx.arc(0, -height, width/2, 0, 2 * Math.PI);
ctx.stroke();
ctx.fillStyle="#e6e6ff";
ctx.beginPath();
ctx.arc(0, 0, radius, 0, 2 * Math.PI);
ctx.fill();
ctx.beginPath();
ctx.rect(-width/2, -height, width, height);
ctx.fill();
ctx.beginPath();
ctx.arc(0, -height, width/2, 0, 2 * Math.PI);
ctx.fill();
ctx.fillStyle="#ff1a1a";
ctx.beginPath();
ctx.arc(0, 0, radius - offset, 0, 2 * Math.PI);
ctx.fill();
temp = Math.round(temp * 100) / 100;
var y = (height - radius)*temp/100.0 + radius + 5;
ctx.beginPath();
ctx.rect(-width/2 + offset, -y, width - 2*offset, y);
ctx.fill();
ctx.fillStyle="red";
ctx.font="bold 34px Georgia";
ctx.textBaseline="middle";
ctx.textAlign="center";
ctx.fillText(temp.toString() + "°C", 0, 100);
}
window.onload = init;
</script>
</head>
<body>
<h1>Arduino - Web Temperature</h1>
<canvas id="cvs"></canvas>
</body>
</html>
)"""";
const char *HTML_CONTENT_DOOR = R""""(
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" href="data:,">
<title>Door Page</title>
</head>
<body>
<h1>Door Page</h1>
<p>Door State: <span style="color: red;">DOOR_STATE_MARKER</span></p>
</body>
</html>
)"""";
const char *HTML_CONTENT_LED = R""""(
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" href="data:,">
<title>LED Page</title>
</head>
<body>
<h1>LED Page</h1>
<p>LED State: <span style="color: red;">LED_STATE_MARKER</span></p>
</body>
</html>
)"""";
const char *HTML_CONTENT_404 = R""""(
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" href="data:,">
<title>404 - Page Not Found</title>
<style>
h1 {color: #ff4040;}
</style>
</head>
<body>
<h1>404</h1>
<p>Oops! The page you are looking for could not be found on Arduino Web Server.</p>
<p>Please check the URL or go back to the <a href="/">homepage</a>.</p>
<p>Or check <a href="https://arduinogetstarted.com/tutorials/arduino-web-server-multiple-pages"> Arduino Web Server</a> tutorial.</p>
</body>
</html>
)"""";
Haz clic en el botón Subir en el IDE de Arduino para subir código al Arduino
Accede a las páginas web de la placa Arduino a través del navegador web una por una como antes. Verás todas las páginas web como se muestran a continuación:
※ Nota:
Si realizas cambios en el contenido HTML dentro del archivo index.h pero no modificas nada en el archivo ArduinoWebServer.ino, el IDE de Arduino no actualizará ni refrescará el contenido HTML cuando compiles y subas el código al ESP32.
Para forzar al IDE de Arduino a actualizar el contenido HTML en esta situación, debes realizar una modificación en el archivo ArduinoWebServer.ino. Por ejemplo, puedes añadir una línea en blanco o insertar un comentario. Esta acción hace que el IDE reconozca que ha habido cambios en el proyecto, asegurando que tu contenido HTML actualizado se incluya en la subida.
※ NUESTROS MENSAJES
No dude en compartir el enlace de este tutorial. Sin embargo, por favor no use nuestro contenido en otros sitios web. Hemos invertido mucho esfuerzo y tiempo en crear el contenido, ¡por favor respete nuestro trabajo!