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

Возможно тема уже «расжована» вдоль и поперек, но полагаю лишним не будет тестовый проект.
Немного о датчиках:
Датчики DH11 и DH22 не отличаются высоким быстродействием, однако могут найти свое применение в радиолюбительских проектах из-за своей невысокой стоимости. Датчики состоят из емкостного датчика влажности и термистора.
Датчик DHT имеет 4 вывода стандарта 2,54 мм:
1 — VDD (от 3В до 5 В);
2 — DATA (данные);
3 — NC;
4 — GND (общий).
Протокол обмена — однопроводный, по структуре очень похож на DS18B20, но очень упрощённый и неимеет возможности соединения датчиков в сеть (подключение на одну линию) — каждый датчик должен подключен к отдельному выводу.

DHT11:

• питание и I/O: 3–5 В;
• определение влажности 20–80 % с точностью 5 %;
• определение температуры 0–50 °С с точностью 2 %;
• частота опроса не более 1 Гц (не более одного раза в 1 сек.);
DHT22:

• питание и I/O: 3–5 В;
• определение влажности 0–100 % с точностью 2–5 %;
• определение температуры –40…+125 °С с точностью ±0,5 °С;
• частота опроса не более 0,5 Гц (не более одного раза в 2 сек);
Как видно из характеристик датчик DHT22 лучше, но он немного и дороже. Например если DHT11 на AliExpress можно купить за 25-30грн то за DHT22 уже придется отдать раза в два больше 55-60грн.
Перейдем к нашему тестовому проекту и коду соответственно.
Схема тестового стенда предоставлена ниже, она имеет минимум элементов.

Приведу здесь часть кода, которая отвечает за общение с датчиком:
/*****************************************************
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.
Скачать
Ого как все запущено…
товарисч, вы забыли сделать фото собранной схемы
нихрена не работает функция одни нолики выдает что я не так делаю?
а можете приводить пример как выводить покозания датчика на дисплей 5110нокиа, или хотя бы откуда брать результат дачика.т.е ответ от датчика
имею в ввиду где храниться результат датчика
I’m sorry. Все работает и при отрицательных и перестал ругаться компилятор, если записать так:
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;
Автору респект! Человек делится знаниями безвозмездно, а мы тут еще и ворчим:-)
Спасибо и Вам! Хороший вариант! Файлы обновил.
При положительных температурах все отлично показывает, но при отрицательных беда
I’m sorry при отрицательных тоже все работает, компилятору понравилась такая форма записи:
h = (float) (data[0]<<8);
h = h + data[1];
h = h/10;
t = (float) (data[2]<<8);
t = t + data[3];
if(t<0)
{
t = t+32768;
t = -t;
}
t = t/10;
Автору Респект! Такие люди вызывают уважение. Мало того что поделился своими наработками так еще и спокойно и сдержано реагирует на коментарии таких барбосов как я:-)
У меня в Протеусе показывает значение влажности и температуры 0.
Нашел ошибку. Фьюзы стояли на 1 МГц. На 8 МГц все хорошо заработало.
Можете ли выслать ваш проект.
Там же заниты ножки хтал1 и 2.
У меня получается как у мадо.
I want to change the port pins of lcd but it doesn’t display result just the message of mega.avr and dht 1%f
// Alphanumeric LCD Module functions
#include — ругается на строку
#include — так нормально но на дисплее ничего нет
А есть код с более полными комментариями? а то далеко не все понятн
А часть кода приведена, потому что полного здесь и не было никогда. Статья просто передрана из какого-то другого источника, поэтому ни у кого и не работает)
У кого руки растут из нужного места — у тех работает все) Проект приведен полностью и архив прикреплен.
Не работает с отрицательными температурами!!!!!
DHT22 умеет работать с отрицательной температурой, посмотрите даташит.
А при чем даташит DHT22? Понятно что датчик может в минусовую температуру. Ваш код не работает с отрицательными значениями!
А в статье и не сказано было что тестовый стенд обязан работать с отрицательной температурой! Да тут и школьнику это понятно.
Сама функция чтения позволяет работать как с отрицательной так и с положительной температурой, а для вывода на дисплей достаточно немного изменить вывод данных и преобразовать их:
h = (float) (data[0]< <8) + data[1];h = h/10;t = (float) (data[2]< <8) + data[3];if(t<0) //если температура ниже 0{t = t+32768; //убираем лишнееt = -t; //преобразуем в отрицательную}t = t/10;Спасибо Вам!
Полезная информация)
Пытаюсь воспользоваться вашим примером в ардуино и получил только нулевые значения.
Подключал к Digital1 (TX)