encender-un-led-rgb-con-un-formulario-web-con-el-esp8266

Encender un LED RGB con un formulario Web con el ESP8266 o ESP32

Empezamos con el cuarto y último tutorial dedicado a formularios web en el ESP8266 y el ESP32 viendo cómo encender un LED RGB a través de una página web servida al cliente.

Haremos referencia al ESP8266, pero el mismo código es compatible para el ESP32, ajustando el nombre de las librerías. Al final tenéis el código tanto para el ESP8266 como para el ESP32.

En las entradas anteriores hemos visto cómo recibir un texto, cómo encender y apagar un LED, y cómo variar la intensidad de un LED mediante PWM, todo ello a través de formularios web.

Como hemos dicho en todas estas entradas, existen muchas formas de comunicar una página web cliente con el ESP8266 como backend. Los formularios web son una de las primeras y más sencillas, pero no necesariamente la mejor para tu proyecto.

Estos tutoriales nos están sirviendo para introducir progresivamente conceptos y ver cómo organizar el código de forma que no sea un “spaghetti code”, y que luego necesitaremos cuando veamos otras formas como Ajax o Websockets.

En estas última entrada de los formularios web vamos a ver cómo encender un LED RGB, lo cuál no deja de ser un poco una excusa para, realmente, para ver cómo trabajar con colores entre una página web y el ESP8266.

De hecho, en el ejemplo sólo vamos a mostrar los RGB recibidos por puerto serie. Hacer ‘algo con ellos’ dependerá de vuestro proyecto

El motivo es que es muy frecuente usar el ESP8266 en proyectos de iluminación (con LED individuales, o tiras LED, WS2182b (Neopixel), matrices, paneles, etc) y usar una página web para que cambie el color, la intensidad, o la animación…

El otro motivo para dedicarle una entrada es que normalmente las páginas web trabajan con colores en formato hexadecimal codificado en una cadena de texto (por ejemplo, #DC30FF). Y eso “amenaza con complicarnos la vida”

Afortunadamente tenemos la librería Arduino ColorConverter que tiene una función, precisamente, para tratar con representaciones hexadecimales como las que se emplean en página web.

Así que ¡manos a la obra!

Como de costumbre, nuestro programa principal sigue igual que en los ejemplos anteriores

#include <ESP8266WiFi.h>
#include <ESPAsyncWebServer.h>
#include <FS.h>

#include "ColorConverterLib.h"
#include "config.h"  // Sustituir con datos de vuestra red
#include "Server.hpp"
#include "ESP8266_Utils.hpp"

void setup(void)
{
  Serial.begin(115200);
  SPIFFS.begin();
  
  ConnectWiFi_STA();

  InitServer();
}

void loop(void)
{
}

Respecto al fichero ‘Server.hpp’, tenemos definido un Endpoint para ‘/RGB’ bajo el método POST, asociada a la función de callback ‘handleFormLed(…)‘. En esta función, usamos la función ‘HexToRgb(…)’ de la librería ColorConverter para transformar el color recibido, codificado una cadena de texto con un valor hexadecimal, en tres valores R, G y B de tipo uint8_t (0-256). Finalmente, mostramos los valores por puerto serie.

AsyncWebServer server(80);

void handleFormLed(AsyncWebServerRequest *request)
{
  String rgb = request->arg("rgb");

  uint8_t red = 0;
  uint8_t green = 0;
  uint8_t blue = 0;

  ColorConverter::HexToRgb(rgb, red, green, blue);

  Serial.println(red);
  Serial.println(green);
  Serial.println(blue);

  request->redirect("/");
}

void InitServer()
{
  server.serveStatic("/", SPIFFS, "/").setDefaultFile("index.html");

  server.on("/RGB", HTTP_POST, handleFormLed);

  server.onNotFound([](AsyncWebServerRequest *request) {
    request->send(400, "text/plain", "Not found");
  });

  server.begin();
  Serial.println("HTTP server started");
}

Finalmente, la página web ‘index.html’ ubicada en ‘data’ que subiremos al ‘SPIFFS’ queda,

<!DOCTYPE html>
<html class="no-js" lang="">
   <head>
      <meta charset="utf-8">
      <meta http-equiv="x-ua-compatible" content="ie=edge">
      <title>ESP8266 Forms</title>
      <meta name="description" content="">
      <meta name="viewport" content="width=device-width, initial-scale=1">
   </head>
 
   <body>
    <h1>Form example</h1>
    <form action="/RGB" method="post">
      Color:<br>
      <input type="color" id="colorSelector" name="rgb"></br>
      <button type="submit" value="submit">Send</button>
    </form> 
    </body>
</html>

Donde vemos que hemos definido un input de tipo ‘color’. Y aquí viene otra de las partes graciosas de los selectores de color, que no están estandarizado, y la representación varia entre el sistema operativo y navegador que estéis usando. Además, se pueden modificar con librerías y estilos. Pero, en este ejemplo, dejaremos el control “por defecto” del navegador.

Cuando pulsemos el botón de ‘Send’ el valor RGB seleccionado se enviará como valor hexadecimal gracias a la asociación ‘name=“rgb”‘.

Resultado

Ahora, si cargamos nuestra (oh sí! incluso más fea que antes) página web, vemos nuestro selector de color. Como hemos dicho, la representación va a ser diferente dependiendo del navegador y del sistema operativo.

esp8266-server-rgb-html

Si pulsamos el botón de ‘Send’ vemos que los valores RGB se muestran en el puerto serie, como tres números de 0 a 256 independientes. Ahora, por supuesto, faltaría mandar cada valor a un PWM, o a un controlador de tiras LED, o lo que uséis en vuestro proyecto (esta parte debería ser trivial).

esp8266-server-rgb-serial-port

Más fácil de lo que parecía ¿verdad? Pues la parte importante en la que convertimos el código hexadecimal en valores R, G, B podéis usarlo en cualquier tipo de proyecto, ya sea por formulario web o por cualquier otra forma de comunicación que veamos.

Y ahora sí, le decimos adios a nuestros viejos (literalmente, viejos) amigos los formularios web, porque en la siguiente entrada veremos cómo emplear Ajax y en la siguiente cómo usar Websockets. ¡Se pone interesante! Hasta la próxima.

Descarga el código

Todo el código de esta entrada está disponible para su descarga en Github.

github-full

Versión para el ESP8266: https://github.com/luisllamasbinaburo/ESP8266-Examples

Versión para el ESP32: https://github.com/luisllamasbinaburo/ESP32-Examples