DHT11 no Arduino: leituras confiáveis dentro do que o sensor consegue medir
Saiba a precisão real do DHT11, onde montar para não medir o calor da placa, como tratar falha de leitura, conferir contra referência e quando trocar de sensor.
A estufa de mudas mostra 31 °C no display, o ventilador liga, e o termômetro de mercúrio pendurado ao lado marca 27 °C. O DHT11 está colado no regulador de tensão da placa, que esquenta. A resposta curta: o DHT11 serve para acompanhar tendência de temperatura e umidade com erro de alguns graus e alguns pontos percentuais; monte-o longe de fontes de calor, leia no máximo uma vez por segundo, trate falha como "sem leitura" e confira contra uma referência antes de tomar decisões com ele. Se a decisão exige precisão, o sensor é outro.
O exemplo deste guia é essa estufa: um Arduino Uno, um DHT11 em módulo de três pinos e um ventilador comandado pela temperatura.
O que o DHT11 promete e o que não promete
As folhas de dados típicas do DHT11 indicam faixa de temperatura de 0 a 50 °C com precisão em torno de ±2 °C, umidade relativa numa faixa intermediária com precisão em torno de ±5 pontos percentuais, e no máximo uma leitura por segundo. Confira a folha do fabricante do seu lote, porque há variações. A resolução que aparece no display também engana: ver "24,0" não significa que o sensor acerta o décimo.
O DHT22 (também vendido como AM2302) tem faixa maior e precisão melhor, mas aceita leituras com intervalo maior, de cerca de dois segundos. Sensores digitais I2C como SHT3x e BME280 são alternativas quando você precisa de mais exatidão e de uma interface mais robusta. Para comparar com outros sensores e entender unidade e atraso de leitura, veja o guia sobre sensor de temperatura no Arduino.
Por que a leitura sai errada mesmo com o sensor bom
O sensor mede o ar que está em volta dele, que pode não ser o ar da estufa. Três fontes de erro aparecem quase sempre:
- Calor da própria eletrônica: regulador de tensão, módulo relé, LEDs e o microcontrolador aquecem o ar em volta. Dentro de uma caixa fechada, a diferença pode ser de vários graus.
- Sol direto: a carcaça do sensor absorve radiação e mede mais quente que o ar.
- Ar parado: sem ventilação, o sensor responde devagar e mostra a temperatura de um bolsão, não do ambiente.
Há ainda o protocolo. O DHT11 conversa por um único fio, com temporização rígida. Fio longo, ruído ou interrupção atrapalhando a leitura produzem falha de checksum, e a biblioteca devolve um valor inválido. Se o seu código transforma isso em zero, o display mostra 0 °C e o ventilador desliga no meio da tarde.
Como montar e ler do jeito certo
- Ligue o sensor com fio de alguns centímetros a algumas dezenas de centímetros, longe do regulador e do relé. Se puder, deixe-o fora da caixa da eletrônica.
- Confirme o resistor de pull-up na linha de dados. Módulos de três pinos geralmente já trazem; o sensor solto de quatro pinos precisa de um externo, tipicamente entre 4,7 kΩ e 10 kΩ para o positivo.
- Proteja do sol direto e deixe o ar circular em volta.
- Leia a cada alguns segundos. A temperatura de uma estufa não muda em milissegundos.
- Descarte leituras inválidas e use a média das últimas válidas para decidir.
- Mostre na tela quando não há leitura, em vez de um número inventado.
Com a biblioteca DHT da Adafruit (instale também a Adafruit Unified Sensor, da qual ela depende), um código que segue essas regras fica assim:
#include <DHT.h>
const uint8_t PINO_DHT = 4;
const uint8_t PINO_VENTILADOR = 7;
const unsigned long INTERVALO_MS = 5000;
const uint8_t AMOSTRAS = 5;
const float LIGAR_ACIMA = 30.0;
const float DESLIGAR_ABAIXO = 28.0;
DHT dht(PINO_DHT, DHT11);
float historico[AMOSTRAS];
uint8_t quantidade = 0;
uint8_t posicao = 0;
uint8_t falhasSeguidas = 0;
unsigned long ultimaLeitura = 0;
bool ventiladorLigado = false;
void setup() {
Serial.begin(9600);
pinMode(PINO_VENTILADOR, OUTPUT);
digitalWrite(PINO_VENTILADOR, LOW);
dht.begin();
}
void loop() {
if (millis() - ultimaLeitura < INTERVALO_MS) return;
ultimaLeitura = millis();
float t = dht.readTemperature();
float u = dht.readHumidity();
if (isnan(t) || isnan(u)) {
falhasSeguidas++;
Serial.println("Leitura falhou");
if (falhasSeguidas >= 3) {
ventiladorLigado = false;
digitalWrite(PINO_VENTILADOR, LOW);
Serial.println("Sensor sem resposta: ventilador em estado seguro");
}
return;
}
falhasSeguidas = 0;
historico[posicao] = t;
posicao = (posicao + 1) % AMOSTRAS;
if (quantidade < AMOSTRAS) quantidade++;
float soma = 0;
for (uint8_t i = 0; i < quantidade; i++) soma += historico[i];
float media = soma / quantidade;
if (!ventiladorLigado && media > LIGAR_ACIMA) ventiladorLigado = true;
if (ventiladorLigado && media < DESLIGAR_ABAIXO) ventiladorLigado = false;
digitalWrite(PINO_VENTILADOR, ventiladorLigado ? HIGH : LOW);
Serial.print("T media: ");
Serial.print(media, 1);
Serial.print(" C U: ");
Serial.print(u, 0);
Serial.println(" %");
}
O estado seguro depende da aplicação. Na estufa do exemplo, desligar o ventilador quando o sensor some foi a escolha; numa sala de servidores, talvez fosse ligar. Decida isso de propósito, não por acidente. Se o ventilador for de tomada, a ligação segue relé no Arduino e a rede elétrica.
Como conferir o seu sensor contra uma referência
Para temperatura, deixe o DHT11 e um termômetro confiável lado a lado, à sombra, com ar circulando, por meia hora. Anote os pares de valores em momentos diferentes. Se o DHT11 marca sistematicamente 1,5 °C acima, você pode aplicar essa correção no código, sabendo que ela vale para aquela unidade e aquela faixa.
Para umidade, um teste caseiro conhecido usa sal de cozinha: um pote fechado com um pouco de sal úmido, uma pasta com sal sobrando sem dissolver, tende a ficar perto de 75% de umidade relativa em temperatura ambiente. Coloque o sensor no pote, sem encostar no sal, espere algumas horas e compare. Exemplo fictício: o DHT11 marcou 69%, ou seja, cerca de 6 pontos abaixo. Isso está na margem de erro esperada, e agora você sabe para que lado ele erra.
Erros comuns
- Sensor colado na placa ou dentro da caixa da eletrônica: a leitura sobe vários graus e o controle reage ao calor do próprio circuito.
- Ler a cada volta do loop: o sensor não responde mais rápido que o intervalo mínimo, e o código fica cheio de falhas ou valores repetidos.
- Tratar NaN como zero: o display mostra 0 °C e a lógica de controle toma a decisão errada.
- Confiar no décimo do display: a precisão é de graus, e ajustar a estufa por 0,1 °C é decidir com ruído.
- Esquecer o pull-up no sensor solto: leituras falham de forma intermitente.
- Usar DHT11 onde o erro custa caro: medicamentos, alimentos ou processos com tolerância apertada pedem instrumento à altura e, quando aplicável, calibrado.
Checklist
- O sensor está longe do regulador, do relé e do sol direto, com ar circulando.
- Há pull-up na linha de dados, no módulo ou externo.
- O intervalo entre leituras é de alguns segundos.
- Leituras inválidas são descartadas e contadas.
- Há um estado seguro definido para quando o sensor para de responder.
- A decisão usa média e dois limiares, não a leitura crua.
- O sensor foi comparado com uma referência e o desvio está anotado.
Coloque a mão perto do seu DHT11 agora e olhe em volta dele: qual é o componente mais quente a menos de cinco centímetros, e quantos graus ele está somando à sua leitura?
Referência: http://blog.filipeflop.com/sensores/monitorando-temperatura-e-umidade-com-o-sensor-dht11.html