No tutorial de hoje vamos utilizar um
ESP-01, que é o ESP8266 na configuração 01 (com somente 2 GPIOs), para a leitura
de temperatura e umidade de um sensor DHT22. Mostro a vocês um esquema elétrico e
a parte da programação do ESP como um arduino. O exemplo é simples, de fácil
compreensão, e ainda disponibilizo o PDF utilizado no vídeo para auxiliar na
sua montagem.
No projeto temos, então, o ESP01, a
fonte que converte 110 ou 220 em 5 volts, um regulador de tensão de 3v3 e o DHT22,
que é o sensor. Na tela de um smartphone, você terá o endereço IP local, além do
código JavaScript fornecido pelo ESP. Esta tela, portanto, vai receber os parâmetros
de temperatura e umidade e vai imprimir esses valores, que serão atualizados a
cada cinco segundos. Para este trabalho não será necessário nenhum aplicativo
em celulares e tablets tanto do sistema operacional Android quanto do IOS.
Montagem
O esquema elétrico é bastante simples,
assim como a parte da montagem, que vai envolver o ESP01 como um servidor, o
qual será programado como se ele fosse um arduino, ou seja, através da
linguagem C. Destaco que parte do código é de um print do browser. Isso quer dizer
que ele manda um código em JavaScript para o browser. Explico melhor mais
abaixo como isso funciona.
Voltando ao esquema elétrico, coloquei
uma fonte chaveada de 5 volts ligada a um regulador de tensão 3v3 para alimentar
o ESP01. Temos ainda o DHT22 com quatro pinos, sendo que um deles, o de dados,
não é utilizado, mas leva um resistor de pull up.
Código
O primeiro passo é incluir as libs que
iremos utilizar. A lib do DHT pode ser adicionada pela opção Sketch >
Incluir Biblioteca > Gerenciar Bibliotecas...
Na janela que abrir procure por DHT
sensor library.
Depois disso criamos uma variável do
tipo ESP8266WebServer que será o nosso servidor que irá responder as
requisições http (porta 80).
Criamos também uma variável do tipo
DHT com os parâmetros 0 (que é o pino GPIO 0) e o tipo (no nosso caso DHT22)
#include <ESP8266WiFi.h> #include <WiFiClient.h> #include <ESP8266WebServer.h> #include <DHT.h> //Criamos uma variável do tipo ESP8266WebServer que já possui funções //que auxiliam na criação das rotas que o ESP8266 vai responder ESP8266WebServer server(80); //Variável do tipo DHT que possui funções para controlarmos o módulo dht //permitindo ler a temperatura e a umidade DHT dht(0, DHT22);
Setup
No setup, vamos inicializar o Serial
apenas para que tenhamos um log, caso o ESP8266 esteja conectado ao computador
através da serial para utilizarmos o monitor serial.
Iremos fazer com que o ESP8266 se
conecte na nossa rede. No nosso caso, usamos a rede TesteESP com a senha
87654321, mas você terá que alterar de acordo com a rede que irá utilizar.
//Inicialize a Serial apenas caso esteja com o ESP8266 conectado ao computador pela serla queira ter um log //para facilitar saber o que está acontecendo com o ESP8266 Serial.begin(115200); //Instrução para o ESP8266 se conectar à rede. //No nosso caso o nome da rede é TesteESP e a senha é 87654321. //Você deve alterar com as informações da sua rede WiFi.begin("TesteESP", "87654321" ); //Feedback caso esteja usando o Monitor Serial Serial.println(""); Serial.print("Conectando");
Aguardamos o ESP8266 se conectar à
rede e, após ele se conectar, enviamos as configurações da rede. Altere conforme
a sua rede.
//Esperamos até que o módulo se conecte à rede while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } //Configurações do IP fixo. Você pode alterar conforme a sua rede IPAddress ip(192, 168, 3, 11); IPAddress gateway(192, 168, 3, 1); IPAddress subnet(255, 255, 255, 0); Serial.print("Configurando IP fixo para : "); Serial.println(ip); //Envia a configuração WiFi.config(ip, gateway, subnet);
Os próximos comandos são apenas para
caso esteja com o ESP8266 conectado ao computador pela serial para que você
tenha um feedback pelo Monitor Serial.
Você pode conferir o IP que o ESP8266
recebeu para ver se é o mesmo que está nas configurações.
//Mostramos no Monitor Serial o ip com o qual o esp8266 se conectou para ver se está de acordo com o que configuramos Serial.println(""); Serial.println("Connectado"); Serial.print ("IP: "); Serial.println(WiFi.localIP());
Aqui começamos a definir quais funções
serão executadas para cada requisição.
Na instrução abaixo, toda vez que o
ESP8266 receber uma requisição http do tipo GET no caminho /temperature a
função getTemperature irá ser executada.
//Aqui definimos qual a função será executada para o caminho e tipo dado. //Nesse caso quando houver uma requisição http do tipo GET no caminho http://192.168.2.8/temperature //(pode ser outro ip dependendo da sua configuração) a função getTemperature será executada server.on("/temperature", HTTP_GET, getTemperature);
Nessa outra instrução, toda vez que o
ESP8266 receber uma requisição http do tipo GET no caminho /humidity a função
getHumidity irá ser executada.
//Nesse outo caso quando houver uma requisição http do tipo GET no caminho http://192.168.2.8/humidity //(pode ser outro ip dependendo da sua configuração) a função getHumidity será executada server.on("/humidity", HTTP_GET, getHumidity);
Nessa instrução, toda vez que o
ESP8266 receber uma requisição http do tipo GET no caminho /monitor a função
showMonitor irá ser executada.
A função showMonitor é a responsável
por retornar o html principal que irá mostrar os valores da temperatura e da
umidade.
//Nesse caso quando houver uma requisição http do tipo GET no caminho http://192.168.2.8/monitor //(pode ser outro ip dependendo da sua configuração) a função showMonitor será executada. //Esta função retornará a página principal que mostrará os valores //da temperatura e da umidade e recarregará essas informações de tempos em tempos server.on("/monitor", HTTP_GET, showMonitor);
Aqui é a definição da função que deve
ser executada quando o caminho requisitado não for encontrado.
//Aqui definimos qual função será executada caso o caminho que o cliente requisitou não tenha sido registrado server.onNotFound(onNotFound);
Aqui inicializamos o nosso servidor
que declaramos anteriormente na porta 80.
Com isso terminamos o setup.
//Inicializamos o server que criamos na porta 80 server.begin(); Serial.println("Servidor HTTP iniciado"); }Loop
Graças a lib ESP8266WebServer, não
precisamos ficar verificando no loop se há clientes e qual o caminho da
requisição. Apenas precisamos chamar handleClient() e o objeto verificará se algum cliente
está fazendo alguma requisição e irá redirecionar para a função correspondente
que registramos anterirormente.
void loop() { //Verifica se há alguma requisição de algum cliente server.handleClient(); }
Requisição
não encontrada
Essa é a função que registramos
anteriormente para ser executada quando o cliente fizer alguma requisição que
não foi registrada.
A função apenas volta o código 404
(código padrão para quando um recurso não é encontrado), o tipo de dado
retornado (no caso texto puro) e um texto com os dizeres “Not Found”.
//Função que definimos para ser chamada quando o caminho requisitado não foi registrado void onNotFound() { server.send(404, "text/plain", "Not Found" ); }
Retornando a temperatura
Essa é a função que retornará um json
com os dados da temperatura quando o cliente fizer uma requisição do tipo GET
em /temperature.
//Função que definimos que será executada quando o cliente fizer uma requisição //do tipo GET no caminho http://192.168.2.8/temperature (pode ser outro ip dependendo da sua configuração) void getTemperature() { //Fazemos a leitura da temperatura através do módulo dht float t = dht.readTemperature(); //Cria um json com os dados da temperatura String json = "{\"temperature\":"+String(t)+"}"; //Envia o json para o cliente com o código 200, que é o código quando a requisição foi realizada com sucesso server.send (200, "application/json", json); }
Retornando a umidade
Essa é a função que retornará um json
com os dados da umidade quando o cliente fizer uma requisição do tipo GET em
/humidity.
//Função que definimos que será executada quando o cliente fizer uma requisição //do tipo GET no caminho http://192.168.2.8/humidity (pode ser outro ip dependendo da sua configuração) void getHumidity() { //Fazemos a leitura da umidade através do módulo dht float h = dht.readHumidity(); //Cria um json com os dados da umidade String json = "{\"humidity\":"+String(h)+"}"; //Envia o json para o cliente com o código 200, que é o código quando a requisição foi realizada com sucesso server.send(200, "application/json", json); }
HTML
Essa é a função que retornará o html
quando o cliente acessar /monitor. Esta página mostrará os valores da
temperatura e umidade e recarregará os dados de tempos em tempos. A parte que
está entre <style type=‘text/css’> e </style> definem a aparência
da página e você pode alterar conforme queira.
//Função que definimos que será executada quando o cliente fizer uma requisição //do tipo GET no caminho http://192.168.2.8/monitor (pode ser outro ip dependendo da sua configuração) void showMonitor() { String html = "<html>" "<head>" "<meta name='viewport' content='width=device-width, initial-scale=1, user-scalable=no'/>" "<title>DHT Monitor</title>" "<style type='text/css'>" "body{" "padding: 35px;" "background-color: #222222;" "}"
Continuação do style do HTML
"h1{" "color: #FFFFFF;" "font-family: sans-serif;" "}" "p{" "color: #EEEEEE;" "font-family: sans-serif;" "font-size:18px;" "}" "</style>" "</head>"
Aqui temos a parte principal do html.
Nele temos dois parágrafos que irão mostrar a temperatura e a umidade. Atenção
para os IDs dos parágrafos, pois é através deles que iremos recuperar estes
parágrafos para inserir os valores da temperatura e umidade após as
requisições.
"<body>" "<h1>DHT Monitor</h1>" "<p id='temperature'>Temperature: </p>" "<p id='humidity'>Humidity: </p>" "</body>"
Aqui começamos a definir o script que
vai de tempos em tempos ler os valores da temperatura e umidade. A função
refresh() chama as funções refreshTemperature() e refreshHumdity() e o
setInterval chama a função refresh a cada 5000 milisegundos (5 segundos).
"<script type='text/javascript'>" "refresh();" "setInterval(refresh, 5000);" "function refresh()" "{" "refreshTemperature()" "refreshHumidity();" "}"
A função refreshTemperature() faz uma
requisição à /temperature e faz o parse da informação contida no json e
adiciona no parágrafo com id temperature.
"function refreshTemperature()" "{" "var xmlhttp = new XMLHttpRequest();" "xmlhttp.onreadystatechange = function() {" "if (xmlhttp.readyState == XMLHttpRequest.DONE && xmlhttp.status == 200){" "document.getElementById('temperature').innerHTML = 'Temperature: ' + JSON.parse(xmlhttp.responseText).temperature + 'C';" "}" "};" "xmlhttp.open('GET', 'http://192.168.2.8/temperature', true);" "xmlhttp.send();" "}"
A função refreshHumidity() faz uma
requisição à /humidity e faz o parse da informação contida no json e adiciona
no parágrafo com id humidity. E, com isso, finalizamos o html que enviaremos nas
requisições em /monitor.
"function refreshHumidity()" "{" "var xmlhttp = new XMLHttpRequest();" "xmlhttp.onreadystatechange = function() {" "if (xmlhttp.readyState == XMLHttpRequest.DONE && xmlhttp.status == 200){" "document.getElementById('humidity').innerHTML = 'Humidity: ' + JSON.parse(xmlhttp.responseText).humidity + '%';" "}" "};" "xmlhttp.open('GET', 'http://192.168.2.8/humidity', true);" "xmlhttp.send();" "}" "</script>" "</html>";
Finalizando showMonitor
Agora que a string com o html que
enviaremos está pronta podemos enviar para o cliente. Com isso, finalizamos a
função showMonitor e o código.
//Envia o html para o cliente com o código 200, que é o código quando a requisição foi realizada com sucesso server.send(200, "text/html", html); }
Testando
Agora, abra seu navegador e digite
http://192.168.2.8/monitor (pode ser outro ip dependendo da sua configuração).
Arquivos para download:
21 Comentários
Boa noite!!! Tenho como colocar mais de um sensor? Se sim até quantos sensores é possível colocar em cada placa?
ResponderExcluirBoa noite!!! Tenho como colocar mais de um sensor? Se sim até quantos sensores é possível colocar em cada placa?
ResponderExcluirEu gostaria muito de ver uma rede com vários esp8266 ou esp32 conectada a um servidor central e fazendo a leitura dos sensores espalhados e um ambiente de aplicação.
ResponderExcluirEu gostaria muito de ver uma rede com vários esp8266 ou esp32 conectada a um servidor central e fazendo a leitura dos sensores espalhados e um ambiente de aplicação.
ResponderExcluirTestei o codigo, mas apesar de ver a temperatura e umidade pelo acesso /Temperature /humidity, nao mostra nada pelo acesso a pag /monitor, somente a pagina sem as medidas. faltou algo?
ResponderExcluirClaudio.
ExcluirFaltou um ; na linha 1444: refreshTemperature(); seria o correto
Substituí o .ino por um já com a correção. Dê uma olhada lá, por favor!
Boa tarde. Gostaria de de tirar uma duvida. Se eu quiser manter registros da temperatura na tela, sem apagar os anteriores, mudaria muita coisa?
ResponderExcluirMuito obrigado! me ajudou muito!
ResponderExcluirOlá. Sou novato no assunto, mas no esp01, você pode colocar até 4 sensores de leitura digital. As portas são de 0 à 4. Geralmente as portas utilizadas são a 0 para ativar a programação, a 2 livre e a 1 e 4 são o TX e RX (não lembro se é nessa ordem a 1 e 4, tem que ver). Sendo assim, 4 sensores.
ResponderExcluiraquela biblioteca ta sobrando ali, ela esta gerando conflito no server, no mais funciona o código.
ResponderExcluircorrigindo a biblioteca WiFiClient.h esta gerando conflito
Excluircomo corrigir?
Excluirapaga ela e gg, ainda não descobri para que ela serve
Excluirta apresentando este erro:
ResponderExcluirexit status 1
Erro compilando para a placa NodeMCU 1.0 (ESP-12E Module)
Tive problemas ao ligar iniciar meu NodeMCU com o DHT22 ligado. Não faço ideia do que pode ser, abri um tópico no seu fórum (http://forum.fernandok.com/viewtopic.php?f=7&t=12995). Grande abraço
ResponderExcluircaso eu queira mandar os dados de temperatura para uma plataforma online, no caso a thinkspeak eu posso utilizar apenas o esp ou é necessário o uso do arduino, pois em todos os projetos da internet vejo o uso do arduino.Obrigado
ResponderExcluirExcelente demonstração, obrigado por compartilhar! gostaria muito de tentar replicar aqui porém após 2,5hrs tentando acabar com os erros de arquivos .h e/ou .cpp não encontrados, ainda me aparecem mtos erros ao compilar...jogando a toalha por hj.
ResponderExcluirQue programa você usa para fazer esse esquema de montagem?
ResponderExcluirMuito legal o projeto, mas gostaria de saber qual a biblioteca do DHT foi usada? Instalei uma pelo gerenciador do Arduino (da Adafruit), porém, quando acesso a rota /temperature, retorna NaN...
ResponderExcluirLiguei o sensor na porta A0 (estou usando uma NodeMCU).
Agradeço qq ajuda!
Só complementado, meu sensor é um HDT11.
Excluiressa que ele usou foi a da adafruit, usa um pino digital, na lib tem um exemplo, fica mais claro, na instalaçao a adafruit pede para instalar outra junto, recomendo aceitar, aqui funcionou
Excluir