Датчики влажности и температуры DHT11 — DHT22. Подключение и правильное чтение данных DHT в CVAVR.

Сегодня рассмотрим датчики DHT11 и DHT22, а также сделаем тестовый проект в котором будем измерять температуру и влажность.

dht-in

Возможно тема уже «расжована» вдоль и поперек, но полагаю лишним не будет тестовый проект.

Немного о датчиках:

Датчики DH11 и DH22 не отличаются высоким быстродействием, однако могут найти свое применение в радиолюбительских проектах из-за своей невысокой стоимости. Датчики  состоят из емкостного датчика влажности и термистора.

Датчик DHT имеет 4 вывода стандарта 2,54 мм:

1 — VDD (от 3В до 5 В);

2 — DATA (данные);

3 — NC;

4 — GND (общий).

Протокол обмена — однопроводный, по структуре  очень похож на DS18B20, но очень упрощённый и неимеет возможности соединения датчиков в сеть (подключение на одну линию) — каждый датчик должен подключен к отдельному выводу.

dht-data

DHT11:

dht11

• питание и I/O: 3–5 В;

• определение влажности 20–80 % с точностью 5 %;

• определение температуры 0–50 °С с точностью 2 %;

• частота опроса не более 1 Гц (не более одного раза в 1 сек.);

DHT22:

dht22

• питание и I/O: 3–5 В;

• определение влажности 0–100 % с точностью 2–5 %;

• определение температуры –40…+125 °С с точностью ±0,5 °С;

• частота опроса не более 0,5 Гц (не более одного раза в 2 сек);

Как видно из характеристик датчик DHT22 лучше, но он немного и дороже. Например если DHT11 на AliExpress можно купить за 25-30грн то за DHT22 уже придется отдать раза в два больше 55-60грн.

Перейдем к нашему тестовому проекту и коду соответственно.

Схема тестового стенда предоставлена ниже, она имеет минимум элементов.

dht11-dht22-1

Приведу здесь часть кода, которая отвечает за общение с датчиком:

/*****************************************************
Chip type               : ATmega8
Program type            : Application
AVR Core Clock frequency: 8,000000 MHz
Memory model            : Small
External RAM size       : 0
Data Stack size         : 256
*****************************************************/

#include <mega8.h>
#include <stdint.h>
#include <stdio.h>
#include <delay.h>

#define DHT22       //если незакоментировано то считается что подключен датчик DHT22 иначе DHT11

#define DHT_PORT        PORTD
#define DHT_DDR         DDRD
#define DHT_PIN         PIND
#define DHT_BIT         1

#asm
   .equ __lcd_port=0x12 //PORTD
#endasm
// Alphanumeric LCD Module functions
#include <alcd.h>

unsigned char buff [16];  //буфер дисплея
 float h=0;
 float t=0;
 bit hum=0;
 uint8_t data[5]={0,0,0,0,0};

int read_dht_hum()   //функция чтения данных датчика
{

unsigned char i,j;

//=============MCU send START
DHT_DDR|=(1<<DHT_BIT); //pin as output
DHT_PORT&=~(1<<DHT_BIT); //0
delay_ms(18);
DHT_PORT|=(1<<DHT_BIT); //1
DHT_DDR&=~(1<<DHT_BIT); //pin as input
//=============check DHT11 response
delay_us(50);
if (DHT_PIN&(1<<DHT_BIT))
    {
    return 0;
    }
delay_us(80);
if (!(DHT_PIN&(1<<DHT_BIT)))
    {
    return 0;
    }
//===============receive 40 data bits
while (DHT_PIN&(1<<DHT_BIT));
for (j=0; j<5; j++)
    {
    data[j]=0;
    for(i=0; i<8; i++)
        {
        while (!(DHT_PIN&(1<<DHT_BIT)));
        delay_us (30);
        if (DHT_PIN&(1<<DHT_BIT))
            data[j]|=1<<(7-i);
        while (DHT_PIN&(1<<DHT_BIT));
        }
    }

return 1; 
//DHT11 data[0]-humidity, data[2]-temperature 
//DHT22 data[0]-data[1]-humidity, data[2]-data[3]-temperature
}

void dht_read()
{
   hum=0;
       #asm("cli")
        hum = read_dht_hum();
       #asm("sei")
    if(hum==1)
    { 
      #ifdef DHT22
      h = (float) (data[0]<<8);
      h = h + data[1];
      h = h/10;
      t = (float) (data[2]<<8);
      t = t + data[3];
      if(t<0) //если температура ниже 0
     {
      t = t+32768; //убираем лишнее
      t = -t; //преобразуем в отрицательную
     }
     t = t/10;  
     #else
     h =  data[0];
     t =  data[2];
     #endif
     }
}


void pr()
{
   dht_read();
    lcd_gotoxy(0,0);              //перешли
   sprintf(buff,"MEGA-AVR.COM.UA ");
   lcd_puts(buff);
   lcd_gotoxy(0,1);              //перешли  
   #ifdef DHT22
   sprintf(buff,"DHT22 %.1f%C/%.1f%%  ",t,h);
   #else
   sprintf(buff,"DHT11 %.1f%C/%.1f%%  ",t,h);
   #endif
   lcd_puts(buff);
}

void main(void)
{
PORTB=0x00;
DDRB=0xF0;

PORTC=0x00;
DDRC=0x00;

PORTD=0x00;
DDRD=0xE0;

lcd_init(16);

while (1)
      {
       pr();
      }
}

В приложенной ниже программе реализована работа с датчиком DHT11, а так же с датчиком DHT22. Переключение между датчиками происходит при компиляции в #define.

Скачать 

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *