Recents in Beach


Receba o meu conteúdo GRATUITAMENTE


ESP8266: como monitorar temperatura e umidade



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:



Postar um comentário

21 Comentários

  1. Boa noite!!! Tenho como colocar mais de um sensor? Se sim até quantos sensores é possível colocar em cada placa?

    ResponderExcluir
  2. Boa noite!!! Tenho como colocar mais de um sensor? Se sim até quantos sensores é possível colocar em cada placa?

    ResponderExcluir
  3. Eu 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.

    ResponderExcluir
  4. Eu 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.

    ResponderExcluir
  5. Testei 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?

    ResponderExcluir
    Respostas
    1. Claudio.
      Faltou um ; na linha 1444: refreshTemperature(); seria o correto

      Substituí o .ino por um já com a correção. Dê uma olhada lá, por favor!

      Excluir
  6. Boa tarde. Gostaria de de tirar uma duvida. Se eu quiser manter registros da temperatura na tela, sem apagar os anteriores, mudaria muita coisa?

    ResponderExcluir
  7. Olá. 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.

    ResponderExcluir
  8. aquela biblioteca ta sobrando ali, ela esta gerando conflito no server, no mais funciona o código.

    ResponderExcluir
    Respostas
    1. corrigindo a biblioteca WiFiClient.h esta gerando conflito

      Excluir
    2. apaga ela e gg, ainda não descobri para que ela serve

      Excluir
  9. ta apresentando este erro:
    exit status 1
    Erro compilando para a placa NodeMCU 1.0 (ESP-12E Module)

    ResponderExcluir
  10. 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

    ResponderExcluir
  11. caso 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

    ResponderExcluir
  12. Excelente 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.

    ResponderExcluir
  13. Que programa você usa para fazer esse esquema de montagem?

    ResponderExcluir
  14. Muito 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...
    Liguei o sensor na porta A0 (estou usando uma NodeMCU).
    Agradeço qq ajuda!

    ResponderExcluir
    Respostas
    1. Só complementado, meu sensor é um HDT11.

      Excluir
    2. essa 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