Servidor HTTP y WiFi en ESP32 para chat LoRa

Resumen

Conectar tu ESP32 a una red WiFi y montar un servidor HTTP es el paso que transforma un sistema de mensajería punto a punto en una aplicación de chat real. Aquí descubrirás cómo integrar WiFi, servidor web y archivos embebidos sobre el código LoRa que ya tenías funcionando, para que tu tarjeta devuelva una página HTML y el logo de Platzi desde su propia IP.

Esta guía te sirve si ya completaste las clases previas de mensajería LoRa y quieres avanzar al proyecto final: un chat controlado desde el navegador de tu celular o laptop.

Qué librerías necesitas para habilitar WiFi y HTTP en el ESP32

Antes de tocar la lógica del servidor, hay que preparar el entorno con las dependencias correctas dentro del ESP-IDF.

En las primeras líneas del archivo principal se importan cuatro piezas clave que aparecen alrededor del minuto [2:30]:

  • La librería de configuración WiFi para inicializar el módulo de radio.
  • NVS (Non-Volatile Storage) para guardar SSID y contraseña en la memoria flash.
  • Protocol Examples Common, el helper que ya trae el ESP-IDF para simplificar la conexión WiFi.
  • La librería de servidor HTTP para exponer rutas como / o /logo.png.

¿Qué es Protocol Examples Common? Es una librería incluida en el ESP-IDF que abstrae todo el flujo de conexión WiFi en una sola función llamada exampleConnect, evitando que reescribas el handshake desde cero.

Cómo embeber archivos HTML y PNG en el binario del ESP32

Para que tu tarjeta sirva una página web sin necesidad de almacenamiento externo, los archivos se compilan directamente dentro del binario.

En las líneas 14 a 17 del código se declaran referencias a las direcciones de inicio y fin del index.html y del logo.png. Estos dos archivos viven en la misma carpeta que el .c principal: el HTML es una página minimalista con el título LoraChat y un Hola, mundo, mientras que el PNG es el logo de Platzi con fondo transparente.

La magia ocurre en el CMakeLists.txt. Allí, en la línea 3, se agrega la instrucción que indica al compilador incluir esos dos archivos como parte del binario. De esta manera, cuando subes el programa a la tarjeta, los recursos viajan con el firmware y quedan accesibles en memoria.

En el CMakeLists.txt raíz del proyecto se añade además la línea 7 que apunta a la ubicación de Protocol Examples Common, tal como se explica alrededor del [4:50].

Cómo configurar la red WiFi desde menuconfig

El truco para no quemar credenciales en el código es usar menuconfig, la herramienta de configuración del ESP-IDF.

Desde la terminal ejecutas idf.py menuconfig y entras a Example Connection Configuration. Ahí editas dos campos:

  1. El SSID, que es el nombre de la red.
  2. La contraseña asociada a esa red.

Guardas con la tecla S y sales con Q. Para este proyecto la recomendación es crear un hotspot desde tu celular usando la opción de compartir red, así tu teléfono y la tarjeta quedan en la misma subred y puedes navegar al servidor sin complicaciones.

¿Por qué guardar credenciales en NVS? Porque la memoria flash no se borra al reiniciar la tarjeta. Una vez configurada la red, el ESP32 reconecta solo después de cualquier corte de energía.

Cómo se inicializa el WiFi y se obtiene la IP en el código

Dentro de app_main el flujo sigue un orden estricto que conviene respetar.

Primero se inicializa la pantalla OLED y se limpia, luego se configura la red LoRa que ya venía funcionando con los pings entre tarjetas. A partir de ahí entra la lógica WiFi alrededor del [6:40]:

  • Inicialización de NVS para leer credenciales desde flash.
  • Arranque de la red y creación del event loop por defecto, donde corre todo el ciclo de eventos WiFi.
  • Llamada a exampleConnect, que ejecuta el handshake completo con el router.

Una vez conectado, el código pide la interfaz activa. Si no encuentra ninguna, imprime un error. Si la encuentra, muestra en la OLED y por terminal el SSID al que se conectó, el RSSI (intensidad de señal en dBm) y la IP asignada por el módem. Estos datos se imprimen en los renglones 0 y 2 de la pantalla, mientras que el RSSI vive en el renglón 4 y el conteo de paquetes en el renglón 6.

Cómo actualizar el RSSI y el conteo de paquetes en la OLED

La función task_rx, que ya recibía mensajes LoRa, se ajustó para escribir el RSSI en el renglón 4 y el contador de paquetes en el renglón 6. Al inicio aparecen dos rayitas y un cero porque todavía no llega ningún mensaje, pero en cuanto el ping entre tarjetas vuelve a fluir, los valores se actualizan en tiempo real.

Cómo crear el servidor HTTP que devuelve el HTML y el logo

La segunda mitad del programa monta el servidor web sobre la conexión ya establecida.

La función web_server_init, ubicada justo arriba de app_main, sigue cuatro pasos:

  1. Declarar una variable para el handle del servidor.
  2. Cargar la configuración por defecto del servidor HTTP.
  3. Iniciar el servidor y validar que arranque correctamente.
  4. Registrar los handlers que responden a cada URL.

En las líneas 106 a 110 se registra la ruta raíz / para devolver el HTML, y en las líneas 112 a 116 la ruta /logo.png para servir la imagen. Ambas responden a peticiones tipo GET.

Las funciones que materializan la respuesta están en las líneas 88 a 104. Cada una define el tipo de contenido (HTML o PNG), usa las referencias de inicio y fin del archivo embebido para leerlo desde memoria, y lo entrega en el cuerpo de la respuesta HTTP.

¿Qué es un handler en un servidor HTTP del ESP32? Es una función que se ejecuta cuando llega una petición a una URL específica. El servidor mapea la ruta al handler y este decide qué devolver al cliente.

Cómo probar el chat LoRa desde tu navegador

Después de compilar y subir el firmware a las dos tarjetas, la OLED muestra el SSID, la IP, el RSSI y el conteo de mensajes. Conectas tu laptop o celular a la misma red WiFi, escribes la IP de la tarjeta en el navegador y ves el Hello, world del HTML. Si entras a /logo.png, aparece el logo de Platzi con fondo transparente.

Con esta base ya puedes experimentar: animar la OLED, rediseñar el HTML o preparar el terreno para los endpoints de la API que enviarán y recibirán mensajes en la siguiente clase. Comparte tus avances en los comentarios y cuéntame qué efectos visuales o cambios al frontend estás probando.