Servidor Web de Cadena de Consulta para ESP32 - Parámetros de URL Dinámicos

Ejemplo de WebServerQueryStrings - Servidor dinámico de múltiples páginas

Visión general

Este ejemplo demuestra cómo crear un servidor web dinámico de varias páginas que utiliza parámetros de consulta de la URL para proporcionar contenido interactivo y funcionalidad de control con una navegación entre páginas fluida.

Características

  • Navegación entre varias páginas con contenido dinámico basado en parámetros de URL
  • Conversión de unidades de temperatura (°C/°F) mediante parámetros de consulta
  • Control de LED con parámetros de cadena de consulta
  • Generación de contenido dinámico basada en la entrada del usuario
  • Diseño profesional de varias páginas con navegación consistente
  • Análisis y validación de parámetros de URL

Hardware Requerido

1×Módulo de Desarrollo ESP32 ESP-WROOM-32
1×Cable USB Tipo-A a Tipo-C (para PC USB-A)
1×Cable USB Tipo-C a Tipo-C (para PC USB-C)
1×(Recomendado) Placa de Expansión de Terminales de Tornillo para ESP32
1×(Recomendado) Breakout Expansion Board for ESP32
1×(Recomendado) Divisor de Alimentación para ESP32

Or you can buy the following kits:

1×DIYables ESP32 Starter Kit (ESP32 included)
1×DIYables Sensor Kit (30 sensors/displays)
1×DIYables Sensor Kit (18 sensors/displays)
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.

Instalación de la biblioteca

Siga estas instrucciones paso a paso:

  • Si es la primera vez que usas el ESP32, consulta el tutorial sobre configurar el entorno para ESP32 en el IDE de Arduino.
  • Conecta la placa ESP32 a tu computadora usando un cable USB.
  • Inicia el IDE de Arduino en tu computadora.
  • Selecciona la placa ESP32 adecuada (p. ej., ESP32) y el puerto COM.
  • Abre el Administrador de Bibliotecas haciendo clic en el icono del Administrador de Bibliotecas en el lado izquierdo del IDE de Arduino.
  • Busca Web Server for ESP32 y localiza el mWebSockets de DIYables.
  • Haz clic en el botón Instalar para agregar la biblioteca mWebSockets.
Biblioteca del servidor web ESP32

Ejemplo de Cadenas de Consulta del Servidor Web

  • En el IDE de Arduino, ve a Archivo Ejemplos Servidor web para ESP32 WebServerQueryStrings ejemplo para abrir el código de ejemplo

Estructura del código

  1. home.h: Plantilla HTML de la página de inicio
  2. temperature.h: Plantilla de la página de monitoreo de temperatura
  3. led.h: Plantilla de la página de control del LED
  4. WebServerQueryStrings.ino: Lógica principal del servidor

Conexión del circuito

No se requieren componentes externos; este ejemplo utiliza el LED integrado en el pin 13.

Características de los parámetros de consulta

Parámetros de la página de temperatura

  • unit=c o unit=celsius - Mostrar la temperatura en grados Celsius
  • unit=f o unit=fahrenheit - Mostrar la temperatura en grados Fahrenheit
  • Sin parámetro - Por defecto en Celsius

Parámetros de Control de LED

  • state=on - Encender LED
  • state=off - Apagar LED

Instrucciones de configuración

1. Configuración de red

Editar las credenciales de WiFi directamente en el archivo WebServerQueryStrings.ino:

const char WIFI_SSID[] = "YOUR_WIFI_SSID"; const char WIFI_PASSWORD[] = "YOUR_WIFI_PASSWORD";

2. Subir código y monitorear la salida

  1. Conecta tu ESP32 a tu computadora
  2. Selecciona la placa y el puerto correctos en Arduino IDE
  3. Carga el sketch WebServerQueryStrings.ino
  4. Abre el Monitor Serial (velocidad de 9600 baudios)
  5. Espera la conexión WiFi
  6. Anota la dirección IP que se muestra
  7. Si no ves la dirección IP en el monitor serial, presiona el botón de reinicio en la placa ESP32

Ejemplos de uso

Abre tu navegador web e introduce la dirección IP que se muestra en el Monitor Serial para acceder al servidor web.

Cadenas de consulta del servidor web ESP32

Prueba la función de monitoreo de la temperatura:

  • Haz clic en el menú "Temperatura".
  • Mira la pantalla de temperatura. Haz clic en cada botón para cambiar la unidad de temperatura.
Cadenas de consulta de temperatura del servidor web ESP32

Prueba la función de control del LED:

  • Haz clic en el menú "Control de LED". Verás la interfaz web como se muestra a continuación:
Cadenas de consulta de la página de control de LED
  • Enciende y apaga el LED utilizando los botones proporcionados.
  • Observa al instante el estado del LED integrado en la placa ESP32.

Accediendo a diferentes páginas

Página de inicio
  • URL: http://your-esp32-ip/
  • Características: Página de bienvenida con un menú de navegación
Página de Temperatura (Predeterminado - Celsius)
  • URL: http://your-esp32-ip/temperature
  • Visualización: Temperatura en Celsius con selector de unidades
Temperatura en grados Fahrenheit
  • URL: http://your-esp32-ip/temperature?unit=f
  • URL: http://your-esp32-ip/temperature?unit=fahrenheit
  • Visualización: Temperatura convertida a Fahrenheit
Control de LED
  • Encender: http://your-esp32-ip/led?state=on
  • Apagar: http://your-esp32-ip/led?state=off

Explicación del código

Procesamiento de parámetros de consulta

void handleTemperature(WiFiClient& client, const String& method, const String& request, const QueryParams& params, const String& jsonData) { // Check for query parameter "unit" String unit = "C"; for (int i = 0; i < params.count; i++) { if (String(params.params[i].key) == "unit") { unit = params.params[i].value; } } // Generate temperature display based on unit String temperatureDisplay = "Simulated temperature: 25°" + unit; // Use the TEMPERATURE_PAGE template and replace placeholder String response = TEMPERATURE_PAGE; response.replace("%TEMPERATURE_VALUE%", temperatureDisplay); server.sendResponse(client, response.c_str()); }

Control de LED con Parámetros de Consulta

void handleLed(WiFiClient& client, const String& method, const String& request, const QueryParams& params, const String& jsonData) { // Check for query parameter "state" String state = ""; for (int i = 0; i < params.count; i++) { if (String(params.params[i].key) == "state") { state = params.params[i].value; break; } } // Control LED based on state if (state == "on") { ledState = HIGH; digitalWrite(LED_PIN, ledState); } else if (state == "off") { ledState = LOW; digitalWrite(LED_PIN, ledState); } else if (state == "") { // No state parameter provided, just show current status } else { // Invalid state parameter client.println("HTTP/1.1 400 Bad Request"); client.println("Connection: close"); client.println(); client.print("Invalid state parameter. Use ?state=on or ?state=off"); return; } // Get current LED state String ledStatus = (ledState == HIGH) ? "ON" : "OFF"; // Use the LED_PAGE template and replace placeholders String response = LED_PAGE; response.replace("%LED_STATUS%", ledStatus); server.sendResponse(client, response.c_str()); }

Validación de parámetros

// Helper function to find query parameter value String getQueryParam(const QueryParams& params, const String& key) { for (int i = 0; i < params.count; i++) { if (String(params.params[i].key) == key) { return params.params[i].value; } } return ""; } // Validation functions bool isValidTemperatureUnit(String unit) { unit.toLowerCase(); return (unit == "c" || unit == "celsius" || unit == "f" || unit == "fahrenheit" || unit == ""); } bool isValidLedState(String state) { return (state == "on" || state == "off" || state == ""); }

Plantillas HTML con Contenido Dinámico

Plantilla de página de temperatura

<div class="temperature-display"> <h2>Current Temperature</h2> <div class="temp-value">%TEMPERATURE% %UNIT%</div> <div class="unit-selector"> <p>Display in:</p> <a href="/temperature?unit=c" class="unit-btn">Celsius</a> <a href="/temperature?unit=f" class="unit-btn">Fahrenheit</a> </div> </div>

Plantilla de control de LED

<div class="led-control"> <h2>LED Control</h2> <div class="status">Status: <span>%LED_STATUS%</span></div> <div class="controls"> <a href="/led?state=on" class="btn btn-on">Turn ON</a> <a href="/led?state=off" class="btn btn-off">Turn OFF</a> </div> </div>

Funciones avanzadas

Configuración de la ruta

void setup() { Serial.begin(9600); pinMode(LED_PIN, OUTPUT); ledState = LOW; digitalWrite(LED_PIN, ledState); // Initialize web server with credentials server.begin(WIFI_SSID, WIFI_PASSWORD); server.printWifiStatus(); // Add routes server.addRoute("/", handleHome); server.addRoute("/temperature", handleTemperature); server.addRoute("/led", handleLed); // Set custom 404 handler server.setNotFoundHandler(handleNotFound); }

Funciones auxiliares de parámetros de consulta

// Extract parameter from QueryParams structure String getParam(const QueryParams& params, const String& key, const String& defaultValue = "") { for (int i = 0; i < params.count; i++) { if (String(params.params[i].key) == key) { return params.params[i].value; } } return defaultValue; } // Check if parameter exists bool hasParam(const QueryParams& params, const String& key) { for (int i = 0; i < params.count; i++) { if (String(params.params[i].key) == key) { return true; } } return false; }

Ayudantes para la construcción de URLs

// Helper to build URLs with parameters String buildLedUrl(String state) { return "/led?state=" + state; } String buildTempUrl(String unit) { return "/temperature?unit=" + unit; }

Notas de Implementación Reales

Limitaciones actuales

La implementación real es más simple en comparación con un servidor web completo con todas las funciones:

  • Solo admite la extracción de un único parámetro por manejador
  • Simulación de temperatura basada en texto simple (sin conversión de unidades)
  • Control básico de LED con solo estados de encendido y apagado
  • Utiliza el pin 9 en lugar del pin 13 estándar

Solución de problemas

Problemas Comunes

Parámetros no funcionan

  • Verificar el formato de la URL: page?param=value
  • Verificar que los nombres de los parámetros coincidan exactamente (sensible a mayúsculas y minúsculas)
  • La implementación actual utiliza state para el LED, no action

Problemas con los pines LED

  • Este ejemplo usa el pin 9, no el pin 13
  • Verifica que la constante LED_PIN coincida con tu hardware

Acceso a Parámetros de Consulta

  • Utiliza la estructura QueryParams, no server.arg()
  • Recorre params.params[i] para encontrar parámetros específicos

Salida de depuración

void debugParameters(const QueryParams& params) { Serial.println("=== Request Parameters ==="); Serial.println("Params count: " + String(params.count)); for (int i = 0; i < params.count; i++) { Serial.print(" "); Serial.print(params.params[i].key); Serial.print(" = "); Serial.println(params.params[i].value); } Serial.println("========================"); }

Personalización

Añadir un nuevo manejador con parámetros

void handleCustomPage(WiFiClient& client, const String& method, const String& request, const QueryParams& params, const String& jsonData) { String theme = getParam(params, "theme", "light"); String lang = getParam(params, "lang", "en"); // Process parameters and generate response String response = "<html><body>"; response += "<h1>Custom Page</h1>"; response += "<p>Theme: " + theme + "</p>"; response += "<p>Language: " + lang + "</p>"; response += "</body></html>"; server.sendResponse(client, response.c_str()); } // Register the new route in setup() server.addRoute("/custom", handleCustomPage);

Mejora del Sistema de Plantillas

La implementación real utiliza un reemplazo sencillo de marcadores de posición:

String response = TEMPERATURE_PAGE; response.replace("%TEMPERATURE_VALUE%", temperatureDisplay); // Add more replacements as needed response.replace("%UNIT%", unit); response.replace("%TIMESTAMP%", String(millis()));

Próximos pasos

  • Explorar WebServerJson.ino para el desarrollo de API REST
  • Probar WebServerWithWebSocket.ino para la comunicación en tiempo real
  • Implementar el manejo de formularios con parámetros POST

Recursos de aprendizaje

※ 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!