Control remoto de tira LED usando ESP32, API Flask y Render

En esta práctica se desarrolló un sistema para controlar una tira de LEDs mediante un ESP32 y una interfaz web. El proyecto se implementó en tres etapas. Primero se probó el funcionamiento de forma local utilizando Flask como servidor en la computadora y una página web para enviar los comandos de color y número de LEDs.

Posteriormente se separaron los componentes del sistema, manteniendo el backend en la computadora mientras que el frontend se publicó en GitHub Pages, permitiendo controlar el sistema desde otros dispositivos dentro de la misma red.

Finalmente, el backend se desplegó en la nube mediante Render, mientras que la interfaz web permaneció en GitHub. Con esto se logró enviar información desde la interfaz web hacia el servidor y almacenarla correctamente, demostrando el uso de Flask para lectura y escritura de datos a través de la web.


Parte 1

1. Desarrollo del servidor Flask y página web

1.1 Estructura del proyecto

Primero se creó la estructura del proyecto dentro de Visual Studio Code, donde se organizaron los archivos necesarios para el funcionamiento del servidor Flask y la interfaz web.

El proyecto contiene una carpeta llamada static, donde se guardan los archivos de la interfaz (HTML, CSS y JavaScript). También se incluyen los archivos del servidor Flask y el archivo donde se almacenará el estado de los LEDs.

Los archivos principales del proyecto son:

  • app.py → servidor Flask encargado de manejar las peticiones.
  • state.json → archivo donde se guarda el estado actual del sistema.
  • index.html → estructura de la página web.
  • styles.css → diseño visual de la página.
  • app.js → lógica de interacción de la página web.

Esta estructura permite separar claramente backend y frontend, facilitando el desarrollo y mantenimiento del sistema.

⬇ Descargar códigos VS

1.2 Configuración del servidor Flask

Posteriormente se programó el servidor Flask, el cual es responsable de manejar la comunicación entre la interfaz web y el sistema que controla los LEDs.

El servidor cuenta con varias rutas principales:

  • / → carga la página principal de la interfaz web.
  • /api/state → permite consultar el estado actual del sistema.
  • /api/set → permite modificar el color y la cantidad de LEDs encendidos.
  • /static → permite servir los archivos estáticos de la interfaz.

El servidor también utiliza un archivo llamado state.json para almacenar la información actual del sistema, como el color seleccionado y la cantidad de LEDs activos.

Además, el servidor se ejecuta en el puerto 5000, permitiendo que otros dispositivos dentro de la misma red puedan acceder a él.

1.3 Comunicación con el servidor

Una vez ejecutado el servidor, este comienza a recibir peticiones desde el navegador. En la terminal de Visual Studio Code se pueden observar las solicitudes que realiza la página web al servidor.

Estas solicitudes utilizan el método GET para consultar el estado actual del sistema a través de la ruta:

/api/state

Cada vez que la página se actualiza o consulta el estado, el servidor responde enviando la información almacenada en el archivo state.json.

Esto permite mantener sincronizada la interfaz web con el estado real del sistema.

1.4 Configuración de red para comunicación con ESP32

Para que el microcontrolador ESP32 pudiera comunicarse con el servidor Flask, se configuró la dirección IP de la computadora donde se estaba ejecutando el servidor.

Esta dirección IP permite que el ESP32 acceda al servidor a través de la red WiFi y pueda consultar el estado del sistema mediante la ruta:

http://IP_DEL_SERVIDOR:5000/api/state

En el código del microcontrolador se especifica esta dirección junto con la configuración de la red WiFi a la cual se conecta el dispositivo.

De esta forma, el ESP32 puede obtener la información enviada desde la interfaz web y actualizar el estado de los LEDs.

⬇ Descargar cod_colores1.ino

Recuerda que para inicializar el código para que aparezca la IP y la pagina empiece a funcionar debes correr el archivo app.py en terminal así como se muestra en la imagen, das clic derecho y debe salir esta configuración de correr en terminal.

Video de la parte 1

Parte 2

2. Separación del backend local y frontend en GitHub Pages

2.1 Cambio de arquitectura del sistema

En esta segunda parte ya no se utilizó otra computadora para correr la parte visual del proyecto. En su lugar, se decidió mantener el backend de Flask ejecutándose de forma local en la computadora, mientras que el frontend se publicó en GitHub Pages.

Con esta modificación, la interfaz web pudo abrirse desde un repositorio publicado en GitHub, mientras que la lógica de guardado y consulta del estado continuó realizándose desde el servidor Flask local.

Esto permitió separar el sistema en dos partes:

  • Backend local → servidor Flask encargado de guardar y entregar el estado del sistema.
  • Frontend en GitHub Pages → interfaz web para seleccionar color y cantidad de LEDs.

Esta estrategia evitó ocupar otra computadora únicamente para mostrar el frontend y facilitó el acceso a la interfaz desde otros dispositivos conectados a la misma red.

⬇ Descargar front de GitHub

2.2 Ajuste del servidor Flask para permitir acceso externo

Para que el frontend publicado en GitHub pudiera comunicarse correctamente con el servidor local, fue necesario modificar el archivo app.py.

En esta versión se agregó la librería flask_cors y se habilitó CORS(app), permitiendo que una página cargada desde otro origen pudiera hacer peticiones al servidor Flask local. También se mantuvo el archivo state.json para guardar el color, la cantidad de LEDs y la fecha de actualización del sistema .

Además, el servidor se ejecutó con:

  • host="0.0.0.0" → para permitir acceso desde otros dispositivos en red.
  • port=5000 → puerto de comunicación del servidor.
  • ssl_context="adhoc" → para habilitar HTTPS local durante esta etapa del proyecto.

Con esto, el servidor pudo seguir recibiendo y entregando información al frontend, ahora cargado desde GitHub Pages :contentReference[oaicite:2]{index=2}.

⬇ Descargar códigos VS

2.3 Consulta del estado desde la red

Una vez configurado el servidor, se comprobó que el estado del sistema podía consultarse desde la red mediante la ruta /api/state. Al abrir esa dirección en el navegador, se mostraba un archivo en formato JSON con la información actual del sistema.

Los datos consultados incluían:

  • color → color seleccionado para los LEDs.
  • count → cantidad de LEDs encendidos.
  • updated → fecha y hora de la última actualización.

Esto permitió corroborar que los cambios realizados desde la interfaz web realmente sí estaban llegando al servidor y quedaban almacenados correctamente en el estado del sistema :contentReference[oaicite:3]{index=3}.

2.4 Comunicación con el ESP32 en esta etapa

El microcontrolador continuó consultando el estado del sistema a través del servidor Flask, utilizando la dirección de red correspondiente y el código cargado en Arduino. De esta manera, el ESP32 seguía leyendo el color y la cantidad de LEDs definidos desde la interfaz, pero ahora con el frontend alojado en GitHub Pages.

Así, aunque la interfaz ya no corría localmente en la misma computadora, el flujo de comunicación se mantuvo:

  • el usuario modificaba el estado desde GitHub Pages,
  • Flask lo recibía y lo guardaba en state.json,
  • y el ESP32 consultaba ese estado para reflejarlo en los LEDs .
⬇ Descargar código ESP32

Video de la parte 2

Parte 3

3. Despliegue del backend en Render y comunicación con GitHub

3.1 Creación del repositorio del backend

En la tercera parte del proyecto se decidió mover el backend del servidor Flask a la nube utilizando la plataforma Render. Para ello primero se creó un nuevo repositorio en GitHub que contendría los archivos necesarios del backend.

Este repositorio incluyó principalmente el archivo app.py, donde se encuentra la lógica del servidor Flask, así como el archivo requirements.txt que permite a Render instalar automáticamente las librerías necesarias para ejecutar la aplicación.

Una vez creado el repositorio, este se utilizó como base para desplegar el servicio web dentro de Render.

⬇ Descargar backend para Render

3.2 Conexión de Render con el repositorio de GitHub

Posteriormente se configuró un nuevo servicio web en Render conectándolo directamente con el repositorio de GitHub creado previamente. De esta forma, cada vez que se realiza un cambio en el repositorio, Render puede actualizar automáticamente el servidor.

Render detectó que el proyecto utiliza Python y procedió a instalar las dependencias indicadas en el archivo requirements.txt. Después de este proceso, el servicio quedó desplegado y disponible a través de una dirección pública en internet.

3.3 Verificación del servidor en Render

Una vez desplegado el servidor, se verificó su funcionamiento accediendo a la dirección pública generada por Render. En esta página se podía observar un mensaje indicando que el servidor Flask estaba funcionando correctamente y que las rutas disponibles eran /api/state y /api/set.

Además, al acceder a la ruta /api/state, el servidor devolvía un objeto en formato JSON con el estado actual del sistema.

  • color → color actual configurado para los LEDs.
  • count → cantidad de LEDs encendidos.
  • updated → fecha y hora de la última actualización.

3.4 Integración del frontend con el backend en Render

Para completar la integración del sistema, se utilizó el mismo frontend desarrollado en la parte anterior y publicado en GitHub Pages. Sin embargo, se realizó una pequeña modificación en el archivo app.js, cambiando la dirección del servidor para que las peticiones se enviaran ahora al backend alojado en Render.

De esta forma, cuando el usuario selecciona un color o la cantidad de LEDs desde la interfaz web, la información se envía al servidor en Render, el cual guarda el estado y lo mantiene disponible para que el ESP32 pueda consultarlo.

El enlace del frontend quedó disponible en:

https://camilasg25.github.io/LEDS_ESP32_PARTE2/

⬇ Descargar frontend utilizado

3.5 Código final del ESP32

Finalmente se actualizó el código del ESP32 para que en lugar de consultar el servidor local, realizara las peticiones directamente al servidor desplegado en Render.

De esta manera, el microcontrolador podía obtener el estado actual del sistema desde internet, permitiendo que los LEDs respondieran a los cambios realizados desde la interfaz web publicada en GitHub Pages.

⬇ Descargar código final ESP32

Video de la parte 3


Siguiente sección

Base de datos en la nube con Firebase y Flask