Em um post anterior, ESP8266: Gravando dados permanentes na memória flash, aprendemos como usar a memória Flash SPI presente no módulo Wemos D1 Mini Pro, para salvar dados de maneira permanente. Como exemplo mostramos como salvar o estado de um LED, que persiste mesmo na falta de energia. Aprendemos também como salvar e carregar da memória flash uma página Web bem simples. Neste post, vamos usar vários desses conceitos para criar um circuito para controlar fita de leds por wifi, usando o ESP8266.
Iremos gravar uma página Web na Flash que contém uma interface de controle de cores para fitas de LED RGB endereçável. Iremos também agregar um novo conceito: uma técnica de comunicação entre página Web (cliente) e o ESP8266 (servidor) usando XMLHTTPRequest.
Controle de fita de leds por wifi – Material utilizado
Para realizar este tutorial foram usados os seguintes materiais:
- Placa WiFi Wemos D1 Mini Pro ESP8266
- Fita de LEDs RGB WS2812
- Fonte DC 5V 2A plug P4
- Mini protoboard 170 pontos
O circuito foi montado da seguinte maneira:
Biblioteca I2S para controle de LEDs endereçáveis
Um desenvolvedor, JoDaNI, desenvolveu uma biblioteca para controle de LEDs endereçáveis utilizando a interface I2S presente no ESP8266. A biblioteca pode ser usada dentro da IDE Arduino e envolve conceitos de uso da RAM para armazenar os dados a serem enviados aos LEDs e DMA(Direct Memory Access) para acessar esses dados e transferi-los a interface I2S.
Uma das vantagens de usar I2S é que este pino é o mesmo pino Rx presente nos módulos ESP8266 inclusive no ESP-01. Uma desvantagem é que seria necessário desconectar qualquer coisa do pino Rx quando o módulo fosse programado usando interface serial.
Baixe a biblioteca esp8266_ws2812_i2s para a pasta libraries da IDE Arduino.
A utilização da biblioteca é bem simples. Comece incluindo-a no seu sketch:
#include <ws2812_i2s.h>
Declare algumas configurações iniciais da biblioteca, como um nome qualquer para identificar a fita de LED e o número de LEDs presentes na fita:
static WS2812 ledstrip; static Pixel_t pixels[NUM_LEDS];
Para mudar as cores da fita basta seguir a lógica abaixo:
int i; for(i=0;i<NUM_LEDS;i++) { pixels[i].R = <valor tom de vermelho>; pixels[i].G = <valor tom de verde>; pixels[i].B = <valor tom de azul>; } ledstrip.show(pixels);
O loop for irá percorrer o número de LEDs da fita colocando os valores de tons de vermelho, verde e azul.
Por exemplos se quisermos ligar apenas o primeiro LED da fita na cor vermelha, usamos o seguinte:
pixels[0].R = 255; pixels[0].G = 0; pixels[0].B = 0; ledstrip.show(pixels);
Interface Web de controle RGB
Para este tutorial desenvolvemos uma página Web que irá controlar a cor dos LEDs da fita. Essa página ficará salva na memória Flash do Wemos. Já aprendemos a fazer isso no post Gravando dados na memória Flash. Essa página irá conter uma interface com um selecionador de cores RGB e em seu backend usaremos XMLHTTPRequest para enviar os dados do selecionador de cores ao ESP8266. O resultado da página será o seguinte:
<!DOCTYPE html> <html> <head> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/css/materialize.min.css"> <script src="https://cdn.rawgit.com/giobauermeister/836975dcbe2fd05a5a2a9dcee6bcec4d/raw/49db24b1ecb60d361f3119ba7e2519f9e2b39101/iro.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/js/materialize.min.js"></script> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head> <body> <div class="container"> <h2 id="title" class="light center">Wemos Color Picker</h2> <div class="centered"> <div id="color-picker-container"></div> </div> <div class="centered"> <input placeholder="IP Address" id="ipAddress" type="text" class="validate" style="text-align: center;"> </div> </div> <script> var xhttp = new XMLHttpRequest(); var demoColorPicker = new iro.ColorPicker("#color-picker-container", { width: 300, height: 300, color: "#5b9aff" }); demoColorPicker.on("color:change", function (color, changes) { console.log(color.rgb); var ipAddress = document.getElementById("ipAddress").value; var url = "http://" + ipAddress + "/colordata"; document.getElementById('title').style.color = color.hexString; xhttp.open("POST", url); xhttp.send(JSON.stringify(color.rgb)); }); </script> <style> .centered { margin: 0 auto; max-width: 300px; } </style> </body> </html>
Selecionador de cores em javascript
Para selecionar as cores utilizamos o Iro.js, um belo color picker em javascript. Com ele podemos obter as cores em formato RGB. As linhas abaixo definem as configurações de tamanho(300×300) e cor inicial(#5b9aff) do color picker:
var demoColorPicker = new iro.ColorPicker("#color-picker-container", { width: 300, height: 300, color: "#5b9aff" });
E as linhas abaixo monitoram o evento color:change, enviando os dados RGB em formato Json para o servidor do ESP8266, através de requisição HTTP POST.
demoColorPicker.on("color:change", function (color, changes) { console.log(color.rgb); var ipAddress = document.getElementById("ipAddress").value; var url = "http://" + ipAddress + "/colordata"; document.getElementById('title').style.color = color.hexString; xhttp.open("POST", url); xhttp.send(JSON.stringify(color.rgb)); });
A documentação completa do color picker Iro.js pode ser encontrada aqui.
XMLHTTPRequest
Para que a página Web se comunique com o ESP8266 e controle a fita de leds por wifi, iremos utilizar um recurso da linguagem Javascript chamado XMLHTTPRequest. Isso nos possibilita realizar requisições GET e POST ao servidor rodando no ESP8266. Basta que o ESP8266 esteja programado para receber tais requisições.
Primeiramente criamos um novo objeto XMLHTTPRequest:
var xhttp = new XMLHttpRequest();
Definimos a URL do ESP8266.
var url = "http://" + ipAddress + "/colordata";
Lembre-se de digitar na página Web o IP que seu ESP8266 recebeu ao conectar-se ao roteador, assim a variável ipAddress vai conter o IP do ESP8266. A URL ficará como a seguir:
“http://192.168.0.xx/colordata”
Quando fazemos alguma mudança de cor na página Web, abrimos uma conexão POST na URL definida acima:
xhttp.open("POST", url);
E finalmente enviamos ao ESP8266 os dados de cor RGB em formato JSON:
xhttp.send(JSON.stringify(color.rgb));
Programa Servidor ESP8266 Wemos D1 mini
Para que o sistema mostrado acima usando XMLHTTPRequest funcione, o ESP8266 precisa atender as requisições de acordo.
Para isso foi desenvolvido um pequeno Webserver que atende a requisições POST nas URLs raiz “/” e “/colordata”.
// aguarda por requisições na URL raiz "/" ou "/colordata" server.on("/", handleRoot); server.on("/colordata", handleColorData);
Quando acessamos o ESP8266 através de seu IP usando um navegador, o navegador faz uma requisição GET na raiz “/”, o que faz o ESP8266 executar a função handleRoot. Essa função basicamente retorna ao navegador a página Web com nossa interface de controle RGB. Então cada vez que mudamos a cor no color picker, o navegador envia uma requisição POST com os dados RGB na URL “/colordata”. O ESP8266 por sua vez chama a função handleColorData, que faz a mudança de cores nos LEDs.
// envia a página Web quando algum cliente conecta na raiz "/" void handleRoot() { server.send(200, "text/html", webPage); } // recebe os dados RGB, imprime na serial e chama funcao para mudanca de cor da fita de LED void handleColorData() { String data = server.arg("plain"); server.send(204,""); StaticJsonBuffer<200> jBuffer; JsonObject& jObject = jBuffer.parseObject(data); int colorR = jObject["r"]; int colorG = jObject["g"]; int colorB = jObject["b"]; Serial.print(colorR); Serial.print(" : "); Serial.print(colorG); Serial.print(" : "); Serial.println(colorB); changeColor(colorR, colorG, colorB); digitalWrite(led, !digitalRead(led)); } // muda a cor da fita de LED void changeColor(int r, int g, int b) { int i; for(i=0;i<NUM_LEDS;i++) { pixels[i].R = r; pixels[i].G = g; pixels[i].B = b; } ledstrip.show(pixels); }
Veja o código completo do servidor abaixo:
//Programa: Controle de fita de leds por wifi #include <FS.h> #include <ArduinoJson.h> #include <ws2812_i2s.h> #include <ESP8266WiFi.h> #include <WiFiClient.h> #include <ESP8266WebServer.h> #include <ESP8266mDNS.h> #define NUM_LEDS 30 //quantidade de LEDs presentes na fita const char* ssid = "nome da rede WiFi"; const char* password = "senha da rede WiFi"; String webPage = ""; int led = LED_BUILTIN; static WS2812 ledstrip; static Pixel_t pixels[NUM_LEDS]; ESP8266WebServer server(80); // envia a página Web quando algum cliente conecta na raiz "/" void handleRoot() { server.send(200, "text/html", webPage); } // recebe os dados RGB, imprime na serial e chama funcao para mudanca de cor da fita de LED void handleColorData() { String data = server.arg("plain"); server.send(204,""); StaticJsonBuffer<200> jBuffer; JsonObject& jObject = jBuffer.parseObject(data); int colorR = jObject["r"]; int colorG = jObject["g"]; int colorB = jObject["b"]; Serial.print(colorR); Serial.print(" : "); Serial.print(colorG); Serial.print(" : "); Serial.println(colorB); changeColor(colorR, colorG, colorB); digitalWrite(led, !digitalRead(led)); } // muda a cor da fita de LED void changeColor(int r, int g, int b) { int i; for(i=0;i<NUM_LEDS;i++) { pixels[i].R = r; pixels[i].G = g; pixels[i].B = b; } ledstrip.show(pixels); } //Faz a leitura do arquivo HTML void readFile(void) { File rFile = SPIFFS.open("/index.html","r"); Serial.println("Lendo arquivo HTML..."); webPage = rFile.readString(); rFile.close(); } void setup() { pinMode(led, OUTPUT); Serial.begin(9600); SPIFFS.begin(); if(SPIFFS.exists("/index.html")) { Serial.println("\n\nfile exists!"); } else Serial.println("\n\nNo File :("); readFile(); WiFi.begin(ssid, password); // Wait for connection while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.print("Connected to "); Serial.println(ssid); Serial.print("IP address: "); Serial.println(WiFi.localIP()); if (MDNS.begin("iotlamp")) { Serial.println("MDNS responder started"); } // aguarda por requisições na URL raiz "/" ou "/colordata" server.on("/", handleRoot); server.on("/colordata", handleColorData); server.begin(); ledstrip.init(NUM_LEDS); } void loop() { server.handleClient(); }
Conclusão
Neste tutorial aprendemos como criar uma interface Web para controle de fitas de LED por wifi, utilizando recursos Web como o color picker Iro.js e XHTMLRequest para comunicação cliente-servidor.
Veja abaixo o projeto de controle de fita de leds por wifi, onde montamos uma estrutura de luminária DIY e colocamos a fita de LED juntamente com o Wemos D1 Mini Pro. Utilizamos um papel fosco para dar um aspecto difuso à fita de LED. Coloque sua criatividade em ação montando uma luminária bem legal com as fitas de LED.
Gostou do projeto de controle de fita de leds por wifi? Ajude-nos a melhorar o blog comentando abaixo sobre este tutorial.
Muito legal! Essa fita do link funciona com Raspberry também?
Caio,
É possível, mas vocÊ precisa utilizar um divisor de tensão para ter uma tensão de 3,3V chegando no Pi.
Abraços!
Diogo – Equipe MakerHero
Olá.
Estou com esse erro! Podem me ajudar?
exit status 1
‘class ArduinoJson6152_0000010::StaticJsonDocument’ has no member named ‘parseObject’
Parece que mudou a versão do Json (5 para o 6) e alguns comandos eles mudaram.
Um outro comando consegui alterar de acordo com o site (https://arduinojson.org/v6/doc/upgrade/) mas esse ele ainda para com os erros.
Olá. Ainda não consegui solução… Alguém tem.uma dica ou a solução?
Estou tentando com a W2812 de 8 Leds para tentar juntar ao projeto de analizador de Wifi…
Giovane,
Voce já tentou usar uma versão mais antiga tanto da IDE, quanto da placa ESP (na IDE)?
Abraços!
Diogo – Equipe MakerHero
Não! Utilizei somente a versão da IDE atual!
Achei esse link, mas ele programa em LUA e não consegui converter!
https://randomnerdtutorials.com/esp8266-rgb-color-picker/
Existe um outro caminho, parecido com o do link, para programar em IDE em ESP8266?
Se o value do input não funcionar(que foi o meu caso), rola de fazer assim também, para passar um IP fixo:
“
input value=”192.168.0.101″ placeholder=”IP Address” id=”ipAddress” type=”text” class=”validate” style=”text-align: center;”
onfocus=”if (this.value == ‘192.168.0.101’) {this.value = ”;}” onblur=”if (this.value == ”) {this.value = ‘192.168.0.101’;}”
Brunin,
Você salvou a página HTML em questão na memória da Wemos?
Abraços!
Diogo – Equipe MakerHero
Não, pq não conseguir fazer a ferramente de upload funcionar.
https://github.com/esp8266/arduino-esp8266fs-plugin
Brunin,
Refaça o tutorial passo a passo e se der erro, favor iniciar um tópico no nosso fórum para que eu possa acompanhar melhor os problemas 🙂
Abraços!
Diogo – Equipe MakerHero
Excelente!!! No site MakerHero os projetos são sempre muito com!!! Parabéns
*bons
Olá Marcelo!
É sempre bom saber que nosso trabalho ajuda as pessoas!
Abraços!
André – Equipe MakerHero
Boa noite, belo projeto, voce teria algum relacionado com termometro que mostre a temperatura com esta placa de wif?
Olá Enio! Obrigado pela leitura.
Infelizmente não temos nenhum tutorial de temperatura com ESP8266
Mas pela internet você pode encontrar vários tutoriais sobre o tema. Por exemplo: https://randomnerdtutorials.com/esp8266-dht11dht22-temperature-and-humidity-web-server-with-arduino-ide/
Abraço!
Olá, vou deixar algumas dicas pra quem for tentar fazer:
1- Utilize a biblioteca ArduinoJson.h na versão 5.13.2 ou inferior, as versões 6.x.x o código não compila.
2- No meu caso estou utilizando o lolin nodemcu v3 e para o programa funcionar é necessário uma alimentação externa para placa independente da quantidade de leds (no meu caso 8), como comentado nesse trecho do artigo “Uma desvantagem é que seria necessário desconectar qualquer coisa do pino Rx quando o módulo fosse programado usando interface serial.”
3- Eu programei meu ESP para ter um ip fixo, o que facilita na hora de acessar, basta adicionar essas linhas no código:
const char* ssid = “nome da rede WiFi”;
const char* password = “senha da rede WiFi”;
IPAddress ip(192, 168, 0, 101); // escolha um ip fixo pro esp
IPAddress gateway(192, 168, 0, 1); // gateway da sua rede
IPAddress subnet(255, 255, 255, 0); // máscara da sua rede
WiFi.config(ip, gateway, subnet);
WiFi.begin(ssid, password);
4- Alterei a página html para que o campo ip já venha preenchido com o ip fixo do ESP, basta alterar esta linha:
Por essa:
Coloque o ip fixo do seu esp no campo value.
5 – O código está configurado o mDNS do ESP neste trecho:
if (MDNS.begin(“iotlamp”)) {
Serial.println(“MDNS responder started”);
}
Caso queira outro dns basta alterar o campo iotlamp
Então pelo seu navegador você consegue acessar o ESP pelo endereço iotlamp.local caso você tenha MAC, com o windows você tem que instalar o software Bonjour da apple.
Obrigado pelo artigo Giovanni.
Obrigado pelas dicas Viktor!
olá, belo post!
uma dúvida, é possível controlar mais do que uma fita de led simultâneamente e de forma independente cada fita?
tipo assim:
static WS2812 ledstrip1;
static WS2812 ledstrip2;
abraço
https://github.com/FastLED/FastLED/blob/master/examples/Multiple
acho que com essa biblioteca rola, vc faria um teste com varias fitas em um esp8266?
agradeço desde já 🙂
Obrigado pela ideia de biblioteca! Iremos avaliar a viabilidade do teste. 🙂
Olá André!
Infelizmente não fizemos teste declarando mais de um objeto da classe WS2812 para usar com mais de uma fita de LED.
O problema é que o ESP8266 tem apenas um pino I2S que é o pino RX0. Aì de qualquer maneira as duas fitas de LED estariam no mesmo pino e os dados enviados seriam os mesmos para as duas.
Mas creio que não há necessidade de usar mais de uma fita de LED. Os LEDs são endereçáveis então é possível ligar o LED que desejar de forma independente.
Caso tiver mais dúvidas sobre a biblioteca creio que o próprio autor responderia muito melhor que nós. Entre em contato por aqui com ele: https://github.com/cnlohr/esp8266ws2812i2s
Olá, muito bom este post e simples o circuito, gostei. Minha única dúvida seria quanto ao código da página web. Onde é gravado não fica junto com o software do arduino ? isso realmente não entendi. Obrigado.
Olá Ricardo!
Veja na introdução do post o seguinte trecho:
“Em um post anterior, ESP8266: Gravando dados permanentes na memória flash, aprendemos como usar a memória Flash SPI presente no módulo Wemos D1 Mini Pro, para salvar dados de maneira permanente. Como exemplo mostramos como salvar o estado de um LED, que persiste mesmo na falta de energia. Aprendemos também como salvar e carregar da memória flash uma página Web bem simples. Neste post, vamos usar vários desses conceitos para criar um circuito para controlar fita de leds por wifi, usando o ESP8266.
Iremos gravar uma página Web na Flash que contém uma interface de controle de cores para fitas de LED RGB endereçável. Iremos também agregar um novo conceito: uma técnica de comunicação entre página Web (cliente) e o ESP8266 (servidor) usando XMLHTTPRequest.”
Agora, como gravar a página Web na memória Flash? Isso você aprende no seguinte post:
https://www.makerhero.com/blog/esp8266-gravando-dados-memoria-flash/
Obrigado pela leitura! Abraço e bons estudos!