Servidor WEB com NodeMcu – ESP
Vamos aprender à criar um Servidor WEB usando HTML e TCP/IP em nosso pequeno ESP8266 ou ESP32. Para essa experiência usaremos o NodeMcu, mas daremos as instruções para você fazer o mesmo projeto com o ESP32. Um servidor web é, como o nome sugere, um servidor de informações que serão fornecidas pelo MCU através da internet ou até LAN. Podemos acessar estes dados em computadores, celulares ou outros MCU’s, e também enviar informações e instruções para o MCU.
Aplicação prática
Acionar LEDs, motores, luzes, ventiladores, etc. Você terá uma interface HMI (Interface Homem-Máquina) e com isso, conseguirá manipular seu sistema das mais diversas formas. Ver status de funcionamento de sensores ou atuadores, as possibilidades são muitas, depende de você. Mostraremos apenas o básico, o controle de um LED por botão, porém, após você entender o funcionamento deste sistema, conseguira fazer muitas coisas!
Para este projeto, você verá o básico necessário para implementar com sucesso um acionamento (transmissão de dados SITE->MCU).
TCP
O protocolo TCP/IP (Transmission Control Protocol) é um protocolo para transmissão orientado à conexão, ou seja, permite que as maquinas se comuniquem e gerenciem o estado atual da transmissão.
Uma característica muito importante sobre o TCP é seu gerenciamento do status da rede e os dados, com isto, podemos saber se o dado enviado foi realmente entregue ao destinatário, também garante a entrega ordenada das informações sem que haja colisões e perdas imperceptíveis.
De um jeito mais fácil, TCP será nosso “Caminhão”, que irá levar as informações até o navegador de quem acessar nosso IP.
HTML
HTML é uma linguagem de marcação utilizada em sites da WEB e são interpretadas pelos navegadores (http request). Quando o usuário se conectar ao IP do ESP pelo navegador, o mesmo irá enviar os dados no formato do HTML via TCP e com isso, após o navegador receber os dados, irá mostrar a página web!
Clique aqui para ver mais Informações sobre HTML
Mãos à obra
Componentes necessários
- 1 – ESP8266 (Usaremos o NodeMCU).
- LED OnBoard
Hardware
Vamos acender o LED_BUILTIN do NodeMCU, este LED OnBoard, está conectado ao pino D4 do NodeMCU.
Código do projeto
Não se esqueça de colocar suas credenciais do WiFi na linha 14 para o funcionamento do código!
#include <ESP8266WiFi.h>//Biblioteca que gerencia o WiFi. #include <WiFiServer.h>//Biblioteca que gerencia o uso do TCP. WiFiServer servidor(80);//Cria um objeto "servidor" na porta 80 (http). WiFiClient cliente;//Cria um objeto "cliente". String html;//String que armazena o corpo do site. void setup() { Serial.begin(9600);//Inicia comunicaçao Serial. WiFi.mode(WIFI_STA);//Habilita o modo STATION. WiFi.begin("SUA REDE", "SUA SENHA");//Conecta no WiFi (COLOQUE O NOME E SENHA DA SUA REDE!). Serial.println(WiFi.localIP());//Printa o IP que foi consebido ao ESP8266 (este ip que voce ira acessar). servidor.begin();//Inicia o Servidor. pinMode(D4, OUTPUT);//Define o LED_BUILTIN como Saida. } void loop() { http();//Sub rotina para verificaçao de clientes conectados. } void http()//Sub rotina que verifica novos clientes e se sim, envia o HTML. { cliente = servidor.available();//Diz ao cliente que há um servidor disponivel. if (cliente == true)//Se houver clientes conectados, ira enviar o HTML. { String req = cliente.readStringUntil('\r');//Faz a leitura do Cliente. Serial.println(req);//Printa o pedido no Serial monitor. if (req.indexOf("/LED") > -1)//Caso o pedido houver led, inverter o seu estado. { digitalWrite(D4, !digitalRead(D4));//Inverte o estado do led. } html = "";//Reseta a string. html += "HTTP/1.1 Content-Type: text/html\n\n";//Identificaçao do HTML. html += "<!DOCTYPE html><html><head><title>ESP8266 WEB</title>";//Identificaçao e Titulo. html += "<meta name='viewport' content='user-scalable=no'>";//Desabilita o Zoom. html += "<style>h1{font-size:2vw;color:black;}</style></head>";//Cria uma nova fonte de tamanho e cor X. html += "<body bgcolor='ffffff'><center><h1>";//Cor do Background //Estas linhas acima sao parte essencial do codigo, só altere se souber o que esta fazendo! html += "<form action='/LED' method='get'>";//Cria um botao GET para o link /LED html += "<input type='submit' value='LED' id='frm1_submit'/></form>"; html += "</h1></center></body></html>";//Termino e fechamento de TAG`s do HTML. Nao altere nada sem saber! cliente.print(html);//Finalmente, enviamos o HTML para o cliente. cliente.stop();//Encerra a conexao. } }
Entendendo a fundo
Software
-Função WiFiServer::available()
cliente = servidor.available();
Aqui, estamos dizendo ao cliente que há um servidor disponível para conexão.
-Detectando clientes conectados
if (cliente == true){}
Com esta condicional, é verificado a existência de clientes conectados no ESP, e se sim, enviará o HTML para o cliente.
-Enviando a estrutura do HTML
cliente.print(html);
Após a criação da estrutura do HTML, precisamos enviar para o cliente. É feito com um simples print().
-Fechando conexão
cliente.stop();
Após o envio do HTML, encerramos a conexão pois não é necessário se manter conectado.
Foi usado um botão do tipo SUBMIT para fazer uma requisição GET ao Host, para entender melhor como funcionam os botoes no HTML, veja ESTE tutorial.
Fechamento
Com a possibilidade de receber e enviar dados pela internet, nossos horizontes ficam bem amplos. Podemos tanto controlar o MCU para por exemplo acionar o portão da garagem, ou descobrir se esta chovendo com sensores e etc. Dúvidas? Sugestões? Críticas? Comente abaixo!
Muito bom o tutorial, mas estava querendo fazer esse controle por uma via externa, tem alguma dica?
Ótimo tutorial, vou testar. Estou testando códigos no Esp32 enquanto aguardo chegar os NodeMCU V3. Tenho dois projetos em andamento. O que estou estudando agora é para automatizar o portão da minha casa. A placa do motor possui dois bornes para uso com botoeira. Ao medir a tensão entre eles, encontrei 3 V. Pelo que li no manual da placa, ao lançar um pulso no GND, ele dispara o comando de abrir o portão. Assim, inicio o Esp com um único botão com função pulsante. Teoricamente esse botão vai funcionar como o botão do controle convencional.
Aguardando resposta!
Primeiramente, obrigado pelo tutorial. Eu tenho um sketch arduino que, resumindo, solicita dados da web para mostrar Hora e Data em um display tft e, no sketch, além do SSID e Senha, tem a seguinte linha: #define HTTP_SERVER “http://10.0.0.159/iotServer.php” mas, logicamente, esse endereço não me serve, portanto, faço a pergunta: o que devo colocar nessa linha, entre aspas, pois entendo que deve ser um servidor brasileiro mas, não entendo qual ou o que devo colocar.
Parte do sketch:
// — HTTP CLIENT ————————————————————————
// This is my intranet server, which is running a REST API. You’ll need one of these.
#define HTTP_SERVER “http://10.0.0.159/iotServer.php”
typedef enum {TIME_INFO, DATE_INFO} DatetimeInfo;
HTTPClient http;
Muito obrigado
Não utilizo essa biblioteca HTTP, entretanto, me parece que você deve colocar o link de onde o mcu irá puxar as informações, visto que isso é um “client http”.
Mais um otimo post, obrigado
Olá. Estou com um problema. Copiei exatamente seu código. Porém, quando refresco a página o led também muda de estado,exatamente como se clicasse no botão LED. Como agreguei um comando HTML para refrescar periodicamente, o led fica piscando o tempo todo, independentemente que quando clico no botão também muda de estado
Isso acontece pois o navegador re-envia a requisição HTTP, trocando o método do botão para POST deve resolver!
Bom dia, sabe se è possível enviar dados para 100 esp em uma rede?
Se o roteador aguentar tantos devices, claro!
Boa noite, estou fazendo o teste com um ESP32 porém estou tendo problemas.
O ESP se conecta na rede normalmente, está recebendo o ip 192.168.15.123, mas eu não consigo abrir a página no navegador.
Estou entrando com o ip dele na barra de navegação porém aparece que nenhum dado foi enviado pelo ip dele.
Como faria pra acessa a página dele? Está correto desta forma?
Obrigado!!
Boa noite! Consegui criar uma pagina Web através do ESP32, para alguns comandos de automação. Gostaria de saber como faço para por uma imagem no fundo da pagina?
As duas opções mais simples são (atributo background do html):
1-) Adicionar o link de referência da imagem, mas provavelmente precisará de conexão com a internet.
2-) Codificar a imagem em base64 e usar essa “string” para o background, assim a imagem ficará salva dentro do MCU, permitindo acesso local OFFLINE.
otimo artigo! uma duvida: sera que consigo colocar script tags no html?
oi! respondendo a minha propria pergunta, caso alguem esteja com a mesma pergunta:
tanto o markup (html css) quanto ao javascript sao interpretados no cliente, nao no servidor. entao o script deve funcionar bem :)
Parabéns. Obrigado por compartilhar. Texto simples e claro até para mim que mal conheço o arduino. Além do conhecimento técnico voce tem o dom pra explicar.
Já tenho alguma experiência com ESP8266. Comprei um NodeMCU com 12E e estou sofrendo uma barbaridade para criar a WebServer. Já analisei seu código e está muito bom, mas não consigo conectar na rede e obter um IP. Deveria funcionar.
Usei o código do Access Point e funcionou muito bem
Meu cérebro travou e agora não sei mais o que tentar e estou com um projeto importante parado.
Se puder dar uma dica, agradeceria muito.
Não há muito que posso falar além de que teste parte a parte da criação do WEBServer, vá analisando ponto a ponto e vendo onde você esta errando.
show show ..
Parabéns, código muito bem escrito, claro e comentado, bem didático. O primeiro com facilidade para quem está entrando em contato com o esp8266.
Seria muito interessante se desse continuidade aos seus códigos unindo estação com access point, e ir aumentando com senha, autoconectividade e etc. Fica a sugestão.
Abraço
Boa noite!
Sou Fábio e estou aprendendo muito com os posts que são bem comentados neste site, já consegui fazer algumas coisas simples com o ESP8266.
Por exemplo, ligar um led através de um botão criado em uma pagina html pelo próprio ESP8266 , que quando pressionado envia uma função http://192.168.0.10/?function=pino_0_on e acende o led.
Agora pretendo fazer outro ESP8266 também conectado a rede que um dos pinos será entrada e quando este pino estiver em zero volts ele enviara esta mesma função para o primeiro ESP8266.
Parte do código já esta funcionando
Primeiro tem a parte que conecta ele a minha rede e o roteador lhe da um IP fixo 192.168.0.11
Depois criei uma variável que recebera o valor do pino 2 que esta configurado como entrada com pullup ativado
Agora falta conseguir fazer enviar a função para o outro ESP8266 que tem o ip 192.168.0.10 quando for pressionado o botão …
void loop() {
estado_pin2 = digitalRead(2);
delay(1);
if (estado_pin2 == LOW) {
pretendo criar uma conexão com o roteador e enviar a função
http://192.168.0.10/?function=pino_0_on quando o pino estiver em zero volts
para o outro ESP8266 também conectado a rede
}
}
Obrigado pela atenção e por compartilhar o conhecimento !!