03 fevereiro 2015

Sensor de temperatura e umidade DHT22 (AM2302)

O sensor de temperatura e umidade DHT22 (ou AM2302), é uma evolução do DHT11, do qual já falamos algumas vezes aqui no Arduino e Cia.

É um sensor com baixo consumo de corrente (2,5 mA durante medições, e 100-150µA em standby), e  que possui internamente um sensor de umidade capacitivo e um termistor, além de um conversor analógico/digital para comunicação com o microcontrolador.

Sensor de umidade e temperatura DHT22


O sensor DHT22 (datasheet) é semelhante ao DHT11 (embora um pouco maior). Ambos utilizam apenas 1 pino de dados para conexão ao microcontrolador,  mas internamente eles possuem diferenças significativas.

O DHT22, por exemplo, é mais lento do que o DHT11, porém ele é capaz de medir uma faixa mais ampla de temperatura e umidade.

Para ilustrar isso montei uma tabela com as principais características de cada um :

Tabela comparativa DHT11 x DHT22

Assim como seu antecessor, o DHT22 também possui 4 pinos, dos quais apenas 3 são usados para conexão ao microcontrolador :

DHT22 - Pinagem

Utilizar esse sensor com o Arduino é muito fácil. Vamos montar um circuito usando o Arduino Uno e um display LCD 16x2. Um resistor de 10 K é utilizado no pino de dados do sensor como resistor pull-up.O pino de dados do sensor será ligado ao pino digital 7 do Arduino :

Circuito Arduino Uno - Sensor de temperatura DHT22


Antes de carregar o programa que vai mostrar o valor da temperatura e umidade no display, como mostrado na imagem acima, baixe a biblioteca DHT nesse link. Descompacte o arquivo, renomeie a pasta para DHT e coloque-a dentro da pasta Libraries da IDE do Arduino.

Essa biblioteca também serve para outros sensores DHT, como o DHT11 e o DHT21. No início do programa, logo após a definição do pino do sensor, altere a linha #define DHTTYPE de acordo com o sensor que você está utilizando.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
// Programa : Sensor de temperatura DHT22
// Autor : Arduino e Cia

#include <DHT.h>
#include <LiquidCrystal.h>

// Pino conectado ao pino de dados do sensor
#define DHTPIN 7

// Pinos do display
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

// Utilize a linha de acordo com o modelo do sensor
//#define DHTTYPE DHT11   // Sensor DHT11
#define DHTTYPE DHT22   // Sensor DHT 22  (AM2302)
//#define DHTTYPE DHT21   // Sensor DHT 21 (AM2301)

// Definicoes do sensor : pino, tipo
DHT dht(DHTPIN, DHTTYPE);

// Array simbolo grau
byte grau[8] ={ B00001100, 
                B00010010, 
                B00010010, 
                B00001100, 
                B00000000, 
                B00000000, 
                B00000000, 
                B00000000,}; 

void setup() 
{
  // Inicializa o display
  lcd.begin(16, 2);
  lcd.clear();
  // Cria o caracter customizado com o simbolo do grau
  lcd.createChar(0, grau); 
  // Informacoes iniciais no display
  lcd.setCursor(0,0);
  lcd.print("Temp. : ");
  lcd.setCursor(13,0);
  // Mostra o simbolo do grau
  lcd.write(byte(0));
  lcd.print("C");
  lcd.setCursor(0,1);
  lcd.print("Umid. : ");
  lcd.setCursor(14,1);
  lcd.print("%");

  Serial.begin(9600); 
  Serial.println("Aguardando dados...");
  // Iniclaiza o sensor DHT
  dht.begin();
}

void loop() 
{
  // Aguarda 2 segundos entre as medicoes
  delay(2000);
  
  // Leitura da umidade
  float h = dht.readHumidity();
  // Leitura da temperatura (Celsius)
  float t = dht.readTemperature();
  
  // Verifica se o sensor esta respondendo
  if (isnan(h) || isnan(t))
  {
    Serial.println("Falha ao ler dados do sensor DHT !!!");
    return;
  }

  // Mostra a temperatura no serial monitor e no display
  Serial.print("Temperatura: "); 
  Serial.print(t);
  lcd.setCursor(8,0);
  lcd.print(t);
  Serial.print(" *C  ");
  // Mostra a umidade no serial monitor e no display
  Serial.print("Umidade : "); 
  Serial.print(h);
  Serial.println(" %");
  lcd.setCursor(8,1);
  lcd.print(h);
}

Caso queira utilizar o circuito sem o display, os dados sobre temperatura e umidade também são enviados ao serial monitor :

Serial Monitor - DHT22

Veja como utilizar o sensor de temperatura também no Raspberry no artigo Como ligar o sensor de temperatura DHT22 ao Raspberry Pi B+.


22 comentários:

  1. como eu faço para os valores sejam mostrados em apenas 3 digitos, ex: 27.3 graus, e não 27.35 com 4 digitos
    ja mudei o codigo para int em vez de float, mas dai ele mostra apenas 2 digitos ex: 27 graus.

    alguem pode me ajudar

    ResponderExcluir
    Respostas
    1. Boa noite,

      Mantenha o formato em float, e adicione um parâmetro no lcd.print() para que ele mostre apenas 1 digito :

      lcd.print(t,1);

      O numero 1 indica que você quer mostrar apenas 1 digito depois do ponto decimal.

      Abraço !

      Excluir
    2. Novamente, era exatamente o que eu procurava...sempre acho aqui no blog. auahahuahu obrigado!

      Excluir
    3. Opa !!! fico contente em ajudar. :)

      Valeu. Abraço!

      Excluir
  2. what is the value for the potentiometer? i wait for your response here: jose.gonzalez141992gmail.com

    ResponderExcluir
    Respostas
    1. Hi Jose,

      You can use any value that you have, but I recommend 10K, 50K or 100K, that are the most common types.

      Best Regards !

      Excluir
  3. Bom dia. Mais uma vez recorro aos que sabem muito mais.Estou montando uma pequena "estação" com Clock DS1307; LCD 128X64 ST7920; DHT22 (AM2302);
    Não estou consiguindo fazer a função temperatura e humidade na tela, como faço para inserir os valores. A data e hora tudo bem, eu consigo. Só estou encontrando esta dificuldade com o DHT22. Já com o DHT11 tudo bem.

    //EMAIL: ROBERTOCARLOSALVARENGA@HOTMAIL.COM


    ResponderExcluir
  4. SKETCK USANDO DHT11; LCD 128X64; DS1307


    //------------------DHT11_CLOCK_DS1307_LCD_128X64_ST7920-----------------------------------
    //------------------------USAR PLACA UNO R3
    //D7-NC
    //D6-E
    //D5-R/W
    //D4-RS
    //GND-BLK
    //BLA-VCC
    //PSB-GND
    //V0- MEIO DO POTENCIOMETRO ----
    //-----------------------------------------------------------------
    #include
    #include
    #include // Comes with Arduino IDE
    #include "U8glib.h"
    U8GLIB_ST7920_128X64_1X u8g(6, 5, 4 ,7); //Enable, RW, RS, RESET
    int display = 1;
    DS1307 rtc(A4, A5);//SDA to A4, SCL to A5 on Arduino




    #define DHT11PIN 2
    dht11 DHT11 ; //Inicializa o sensor




    void draw(void) {
    // graphic commands to redraw the complete screen should be placed here
    u8g.setFont(u8g_font_unifont);
    //u8g.setFont(u8g_font_osb21);
    u8g.drawStr( 0, 10, "Data:" );
    u8g.setFont(u8g_font_robot_de_niro);
    u8g.drawStr( 0, 25, "UMIDADE:" );
    u8g.setPrintPos(40, 25);///posição onde irá aparecer o valor da umidade
    u8g.setFont(u8g_font_unifont);
    u8g.print((float)DHT11.humidity);////umidade
    u8g.setFont(u8g_font_robot_de_niro);
    u8g.drawStr( 85, 25, "%" );
    u8g.drawStr( 0, 45, "TEMPERATURA:" );
    u8g.drawStr( 102, 45, "*C" );
    u8g.setPrintPos(60, 45);////posição onde irá aparecer o valor da temperatura
    u8g.setFont(u8g_font_unifont);
    u8g.print((float)DHT11.temperature);////temperatura
    u8g.setFont(u8g_font_robot_de_niro);
    u8g.drawStr( 0, 35, "Versao.:22-05-2015-A" );
    u8g.setFont(u8g_font_unifont);
    u8g.drawStr( 40, 10, rtc.getDateStr(FORMAT_SHORT)); // DATA
    u8g.drawStr( 0, 60, "Hr:" );
    u8g.drawStr( 30, 60,rtc.getTimeStr()); // RELOGIO
    u8g.drawStr( 93, 60, "," );
    u8g.drawStr( 100, 60, rtc.getDOWStr(FORMAT_SHORT)); // DIA DA SEMANA
    }

    void setup(void) {


    // flip screen, if required
    // u8g.setRot180(); // COMANDO PARA LIGAR A TELA EM 180 GRAUS

    // set SPI backup if required
    //u8g.setHardwareBackup(u8g_backup_avr_spi);

    //Aciona o relogio
    rtc.halt(false);




    //As linhas abaixo setam a data e hora do modulo
    //e podem ser comentada apos a primeira utilizacao

    // rtc.setDOW(MONDAY); //Define o dia da semana para ajuste do relogio
    // rtc.setTime(20, 40, 47); //Define o horario para ajuste do relogio
    // rtc.setDate(18, 8, 2014); //Define o dia, mes e ano para ajuste do relogio

    //Definicoes do pino SQW/Out
    rtc.setSQWRate(SQW_RATE_1);
    rtc.enableSQW(true);

    // assign default color value
    if ( u8g.getMode() == U8G_MODE_R3G3B2 ) {
    u8g.setColorIndex(255); // white
    }
    else if ( u8g.getMode() == U8G_MODE_GRAY2BIT ) {
    u8g.setColorIndex(3); // max intensity
    }
    else if ( u8g.getMode() == U8G_MODE_BW ) {
    u8g.setColorIndex(1); // pixel on
    }
    else if ( u8g.getMode() == U8G_MODE_HICOLOR ) {
    u8g.setHiColorByRGB(255,255,255);
    }
    }

    void loop(void) {

    DHT11.read(DHT11PIN); //Lê as informações do sensor

    // picture loop
    u8g.firstPage();
    do {
    draw();
    } while( u8g.nextPage() );

    // rebuild the picture after some delay
    delay(500);
    }


    //EMAIL: ROBERTOCARLOSALVARENGA@HOTMAIL.COM

    ResponderExcluir
  5. //DHT22_CLOCK_DS1307_LCD_128X64_ST7920


    //----SENSOR DHT22---- Pino conectado ao pino DIGITAL de dados do sensor
    #define DHTPIN 2
    // Utilize a linha de acordo com o modelo do sensor
    //#define DHTTYPE DHT11 // Sensor DHT11
    #define DHTTYPE DHT22 // Sensor DHT 22 (AM2302)
    //#define DHTTYPE DHT21 // Sensor DHT 21 (AM2301)
    // Definicoes do sensor : pino, tipo
    DHT dht(DHTPIN, DHTTYPE);
    //---------------------------------------------------------------
    //------SENSOR DHT11-----------
    ///////#define DHT11PIN 2
    //////// dht11 DHT11 ; //Inicializa o sensor
    //-----------------------------------------------------------------------------------------
    int t;
    int h;



    void draw(void) {
    // graphic commands to redraw the complete screen should be placed here
    u8g.setFont(u8g_font_unifont);
    //u8g.setFont(u8g_font_osb21);
    u8g.drawStr( 0, 10, "Data:" );
    u8g.setFont(u8g_font_robot_de_niro);
    u8g.drawStr( 0, 25, "UMIDADE:" );
    u8g.setPrintPos(40, 25);///posição onde irá aparecer o valor da umidade
    u8g.setFont(u8g_font_unifont);
    ///////// u8g.print((float)DHT11.humidity);////umidade
    // u8g.print((float)DHT22.h);////umidade
    // u8g.print((float)DHT22.H);////umidade
    u8g.print(h);
    //u8g.print((float)dht22.Humidity);////umidade
    // u8g.print((float)DHT22.humidity);////umidade
    u8g.setFont(u8g_font_robot_de_niro);
    u8g.drawStr( 85, 25, "%" );
    u8g.drawStr( 0, 45, "TEMPERATURA:" );
    u8g.drawStr( 102, 45, "*C" );
    u8g.setPrintPos(60, 45);////posição onde irá aparecer o valor da temperatura
    u8g.setFont(u8g_font_unifont);
    ///////////// u8g.print((float)DHT11.temperature);////temperatura
    u8g.print(t);
    u8g.setFont(u8g_font_robot_de_niro);
    u8g.drawStr( 0, 35, "Versao.:22-05-2015-A" );
    u8g.setFont(u8g_font_unifont);
    u8g.drawStr( 40, 10, rtc.getDateStr(FORMAT_SHORT)); // DATA
    u8g.drawStr( 0, 60, "Hr:" );
    u8g.drawStr( 30, 60,rtc.getTimeStr()); // RELOGIO
    u8g.drawStr( 93, 60, "," );
    u8g.drawStr( 100, 60, rtc.getDOWStr(FORMAT_SHORT)); // DIA DA SEMANA
    }

    void setup(void) {


    // flip screen, if required
    // u8g.setRot180(); // COMANDO PARA LIGAR A TELA EM 180 GRAUS

    // set SPI backup if required
    //u8g.setHardwareBackup(u8g_backup_avr_spi);

    //Aciona o relogio
    rtc.halt(false);
    // Iniclaiza o sensor DHT
    dht.begin();



    //As linhas abaixo setam a data e hora do modulo
    //e podem ser comentada apos a primeira utilizacao

    // rtc.setDOW(MONDAY); //Define o dia da semana para ajuste do relogio
    // rtc.setTime(20, 40, 47); //Define o horario para ajuste do relogio
    // rtc.setDate(18, 8, 2014); //Define o dia, mes e ano para ajuste do relogio

    //Definicoes do pino SQW/Out
    rtc.setSQWRate(SQW_RATE_1);
    rtc.enableSQW(true);

    // assign default color value
    if ( u8g.getMode() == U8G_MODE_R3G3B2 ) {
    u8g.setColorIndex(255); // white
    }
    else if ( u8g.getMode() == U8G_MODE_GRAY2BIT ) {
    u8g.setColorIndex(3); // max intensity
    }
    else if ( u8g.getMode() == U8G_MODE_BW ) {
    u8g.setColorIndex(1); // pixel on
    }
    else if ( u8g.getMode() == U8G_MODE_HICOLOR ) {
    u8g.setHiColorByRGB(255,255,255);
    }
    }




    void loop(void) {

    /////////// DHT11.read(DHT11PIN); //Lê as informações do sensor

    //---------------------DHT22

    // Aguarda 2 segundos entre as medicoes
    delay(2000);

    // Leitura da umidade
    float h = dht.readHumidity();
    // Leitura da temperatura (Celsius)
    float t = dht.readTemperature();

    // Verifica se o sensor esta respondendo
    if (isnan(h) || isnan(t))
    {
    Serial.println("Falha ao ler dados do sensor DHT !!!");
    return;
    }

    //-----------------------------------------------------------------------
    // picture loop
    u8g.firstPage();
    do {
    draw();
    } while( u8g.nextPage() );

    // rebuild the picture after some delay
    delay(500);
    }

    ResponderExcluir
  6. Amigo montei o sensor tudo direitinho e sempre me dá erro de DHT dht(DHTPIN, DHTTYPE); o que tenho que fazer? Abraço e obrigado pela sua atenção. o Meu E-mail é magalhaes.tecnologia@hotmail.com


    // Programa : Sensor de temperatura DHT22
    // Autor : Arduino e Cia

    #include
    #include

    // Pino conectado ao pino de dados do sensor
    #define DHTPIN 7

    // Pinos do display
    LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

    // Utilize a linha de acordo com o modelo do sensor
    //#define DHTTYPE DHT11 // Sensor DHT11
    #define DHTTYPE DHT22 // Sensor DHT 22 (AM2302)
    //#define DHTTYPE DHT21 // Sensor DHT 21 (AM2301)

    // Definicoes do sensor : pino, tipo
    DHT dht(DHTPIN, DHTTYPE);

    // Array simbolo grau
    byte grau[8] ={ B00001100,
    B00010010,
    B00010010,
    B00001100,
    B00000000,
    B00000000,
    B00000000,
    B00000000,};

    void setup()
    {
    // Inicializa o display
    lcd.begin(16, 2);
    lcd.clear();
    // Cria o caracter customizado com o simbolo do grau
    lcd.createChar(0, grau);
    // Informacoes iniciais no display
    lcd.setCursor(0,0);
    lcd.print("Temp. : ");
    lcd.setCursor(13,0);
    // Mostra o simbolo do grau
    lcd.write(byte(0));
    lcd.print("C");
    lcd.setCursor(0,1);
    lcd.print("Umid. : ");
    lcd.setCursor(14,1);
    lcd.print("%");

    Serial.begin(9600);
    Serial.println("Aguardando dados...");
    // Iniclaiza o sensor DHT
    dht.begin();
    }

    void loop()
    {
    // Aguarda 2 segundos entre as medicoes
    delay(2000);

    // Leitura da umidade
    float h = dht.readHumidity();
    // Leitura da temperatura (Celsius)
    float t = dht.readTemperature();

    // Verifica se o sensor esta respondendo
    if (isnan(h) || isnan(t))
    {
    Serial.println("Falha ao ler dados do sensor DHT !!!");
    return;
    }

    // Mostra a temperatura no serial monitor e no display
    Serial.print("Temperatura: ");
    Serial.print(t);
    lcd.setCursor(8,0);
    lcd.print(t);
    Serial.print(" *C ");
    // Mostra a umidade no serial monitor e no display
    Serial.print("Umidade : ");
    Serial.print(h);
    Serial.println(" %");
    lcd.setCursor(8,1);
    lcd.print(h);
    }

    ResponderExcluir
  7. ola tenho uma dúvida:
    faz diferença não usar o resistor de pull-up conectando o data com o VCC?

    ResponderExcluir
  8. Boa tarde.
    Possuo o kit de desenvolvimento NodeMCU 1.0, cujo qual embarca o chip ESP8266-12E. Ao carregar este exemplo através da interface Arduino surge o seguinte erro: "undefined reference to `__ieee754_sqrt'"

    Já procurei em diversos foruns, e pelo que entendi este chip não suporta a função "sqrt", função matemática de raiz quadrada. Tentei encontrar na biblioteca DHT.h o local onde pudesse ter esta referência, mas não encontrei.

    Alguém já tentou fazer este exemplo com o ESP8266? Algum outro método para leitura de temperatura e umidade do DHT utilizando o ESP?

    Grato desde já!

    ResponderExcluir
  9. por favor gostaria de realizar o codigo para dois sensores dht22, como eu faço?

    ResponderExcluir
    Respostas
    1. Bom dia,

      Crie uma nova linha para cada sensor DHT22, da mesma forma que está no código, por exemplo:

      #define DHTPIN 7
      crie uma linha com
      #define DHTPIN_2 6 (segundo DHT22 ligado na porta 6)

      #define DHTTYPE_2 DHT22

      DHT dht(DHTPIN_2, DHTTYPE_2);

      E assim por diante.

      Abraço!

      Excluir
    2. Olá... Quando eu chamo a função umidade ou temperatura, como fazer para definir qual dos sensores será lido?

      Obrigado

      Excluir
    3. Neste ponto do código...

      // Leitura da umidade
      float h = dht.readHumidity();
      // Leitura da temperatura (Celsius)
      float t = dht.readTemperature();

      Como especificar qual o sensor?

      Obrigado novamente

      Excluir
    4. Oi Luis,

      Se você criou uma outra instância do DHT no programa, como na linha 19, basta chamar o segundo sensor, por exemplo:
      float h2 = dht2.readHumidity();
      float t2 = dht2.readTemperature();

      Abraço!

      Excluir
  10. desculpem, entendo pouco de programaçao, mas é possivel escrever as mediçoes com os horarios em que foram realizadas? desde ja obrigado

    ResponderExcluir
    Respostas
    1. Bom dia leonardo,

      É possível sim, eu recomendo colocar um módulo RTC no seu circuito, como o DS1307, DS3231 ou o DS1302. Tenho posts sobre eles aqui no blog.

      Abraço!

      Adilson

      Excluir
  11. Desculpem, sou iniciante em programaçao, mas é possivel registrar os horarios em que as mediçoes foram feitas? desde ja obrigado

    ResponderExcluir
    Respostas
    1. Oi Leonardo,

      Sim, eu recomendo que você coloque no circuito um módulo RTC. A gravação pode ser feita, por exemplo, em um cartão SD.

      Abraço!

      Excluir
  12. Boa noite,
    Gostaria dois cooler e controlar a velocidade de rotação nesse circuito
    Devo criar o código e usar a função include ?
    Estou começando a aprender a mexer no programa e tenho algumas dúvidas. Seria possível, a ideia e controlar a temperatura.
    email :kaike-costa@hotmail.com
    Se puder da alguma dica ou conselho. Fico grato

    ResponderExcluir