Сегодня рассмотрим датчики 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)