Главная » Статьи » Как подключить

Работа с датчиком влажности DHT11 в Bascom-AVR
  Датчик DHT11 является самым дешевым цифровым датчиком, позволяющий измерять температуру и влажность окружающей среды. При цене меньше одного бакса от него нельзя многого ожидать, но для домашнего показометра он вполне сгодится. 
 
Купить сей датчик можно здесь
 
Технические характеристики:
Предел измерения температур: 0-50°С (±2°С)
Предел измерения влажности: 20-80% ( ±5%)
Напряжение питания: 3-5,5V
Энергопотребление:
Измерение: 0,5-2,5мА
Передача данных: 0,2-1мА
Ожидание: 0,1-0,15 мА
Опрос датчика с частотой не чаще 1 раз в секунду

 Для связи с контроллером используется однопроводная шина с открытым коллектором, поэтому обязательна подтяжка резистором 5-10кОм к плюсу питания.
 
          

 Ниже приведены временные диаграммы занятости шины. Для инициирования измерений, контроллер должен подать стартовый сигнал - прижать шину к земле на 18-20 мс. после чего отпустить линию и следить за уровнем на ней. Датчик, обнаружив сигнал и подождав пока уровень снова станет высоким, сам прижимает шину к земле. Он будет держать низкий уровень все время пока идет измерение и преобразование результатов. Как только преобразования закончились, датчик отпускает линию, тем самым сообщая о готовности к передаче данных. Контроллер, в свою очередь, зафиксировав этот сигнал, начинает принимать данные. 
 
 
кликабельно
 
 
 
 
 
 
 
 
 Перед отправкой каждого бита датчик прижимает шину к земле на 50 мкс . Передающиеся по шине единицы и нули отличаются друг от друга длительностью высокого уровня, который держится на линии после начала передачи.

Передача бита «0»
 

 
 
 
 
Передача бита «1»
 
 
 
 
 
 
 Данные от датчика передаются в виде посылки, состоящих из 40 бит идущих в таком порядке:
8 бит целая часть влажности + 8 бит десятая часть влажности + 8 бит целая часть температуры + 8 бит десятая часть температуры + 8 бит контрольной суммы.

Программа для работы с датчиком DHT11 в Bascom-AVR приведена ниже:
 
$regfile = "m8def.dat"
$crystal = 16000000

'конфигурация подключения дисплея к портам МК
Config Lcd = 16 * 2
Config Lcdpin = Pin,Rs=Portc.5,E=Portc.4,Db4=Portc.3,Db5=Portc.2,Db6=Portc.1,Db7=Portc.0
Cursor Off
Cls

'объявление подпрограммы
Declare Sub Get_th(As Byte , H As Byte)

Config Serialin = Buffered , Size = 128
Config Serialout = Buffered , Size = 128

'подключение датчика к PortD.6
Dht_put Alias Portd.6
Dht_get Alias Pind.6
Dht_io_set Alias Ddrd.6

Dim T As Byte                        'перееменная для хранения температуры
Dim H As Byte                        'переменная для хранения влажности
Dim Crc As Byte                      'переменная для хранения байта четности
Dim Mybyte As Byte
Dim Sensor_data As String * 40    'сюда будут записываться данные отсылаемые датчиком
Dim Tmp_str8 As String * 8
Dim Count As Byte                    'переменная для подсчета принятых бит

Enable Interrupts

Set Dht_io_set
Set Dht_put

Lcd "AVRproject.ru"
Lowerline
Lcd "DHT11 sensor"

Do
   Waitms 1500
   Call Get_th(, H)
   Cls
   Lcd "TMP: " ; T ; "C"
   Lowerline
   Lcd "PHP: " ; H ; "%"

Loop

Sub Get_th(As Byte , H As Byte)

 Count = 0
 Sensor_data = ""
 Set Dht_io_set                                         'делаем PD.6 выходом
 Reset Dht_put                                          'прижимаем шину к земле
 Waitms 25                                              'ждем не менее 18мс

 Set Dht_put                                            'отпускаем шину
 Waitus 40
 Reset Dht_io_set                                       'делаем PD.6 входом
 Waitus 40                                              'ждем 40 мкс
 If Dht_get = 1 Then                                    'если на нем по прежнему 1
    H = 1                                               'значит датчик не ответил
    Exit Sub                                            'выходим из подпрограммы
 End If

'если датчик ответил и прижал шину к земле продолжаем работу
  Waitus 80                                             'ждем еще 80 мкс
  If Dht_get = 0 Then                                   'если на линии по прежнему 0
    H = 2                                               'значит датчик сошел с ума
    Exit Sub                                            'выходим из подпрограммы
  End If

'если все нормально и датчик ответил правильно, тогда продолжаем

  While Dht_get = 1 : Wend                'ждем пока на шине появится 1

   Do                                     'начинаем принимать 40 бит данных
    While Dht_get = 0 : Wend              'ждем появления на шине 0
    Waitus 30                             'после появления 0 ждем 30мкс
     If Dht_get = 1 Then                  'если на шине 1
       Sensor_data = Sensor_data + "1"    'записываем в переменную эту единицу
       While Dht_get = 1 : Wend           'и ждем пока датчик отправит следующий бит
       Else                               'иначе, если там был 0
       Sensor_data = Sensor_data + "0"    'записываем этот 0 в переменную
    End If
    Incr Count                            'увеличиваем счетчик на 1
   Loop Until Count = 40                  'повторяем пока счетчик не досчитает до 40

   Set Dht_io_set
   Set Dht_put

'начинаем раскладывать полученные данные

   Tmp_str8 = Left(sensor_data , 8)                'берем левые 8 символов переменной
   H = Binval(tmp_str8)                            'это целая часть влажности

   Tmp_str8 = Mid(sensor_data , 17 , 8)            'вытаскиваем 8 символов из середины
   T = Binval(tmp_str8)                            'это целая часть температуры

   Tmp_str8 = Right(sensor_data , 8)               'правые 8 символов
   Crc = Binval(tmp_str8)                          'проверочные данные

'проверка контрольной суммы

   Mybyte = T + H                      'складываем значение температуры и влажности
   If Mybyte <> Crc Then               'если контрольная сумма не сошлась
      H = 3                            'значит полученные данные не верны
   End If

End Sub                                      'возвращаемся в главный цикл программы
 

 Датчик подключен к микроконтроллеру к выводу PortD.6, и выводит на дисплей целые части температуры и влажности. Схему подключения не привожу, так как думаю все ясно из кода выше. Результат:

 
 
 
 
 
 
 
Категория: Как подключить | Добавлено: 06.04.2012
Просмотров: 52663 | Комментарии: 67 | Теги: измерения, датчик влажности, ATmega8, dht11 | Рейтинг: 5.0/14
Всего комментариев: 671 2 3 »
67 sany2   (01.10.2014 00:35) [Материал]
Radan,нет датчика попробовать.Как тут написано опрашивать не чаще раза в секунду,но ведь сам опрос идёт вряд ли больше секунды.Попробуйте завести таймер на одну секунду,и обрабатывайте датчик.

66 radan   (29.09.2014 22:55) [Материал]
DHT22 по времени обрабатывается 2-3 секунды. Можно ли как-то ускорить этот процесс, чтобы вложиться меньше чем в одну секунду? Если нельзя, то можно ли вклинить свой код в цикл получения данных? Другими словами, насколько критично получение потоком всех 40 байт? Или всё же можно так: получили 8 байт - мой код, опять 8 байт, опять мой код и т.д.?

65 NCy   (24.09.2014 20:14) [Материал]
Я таскал макетку на работу и сравнивал в одном помещении. Датчик DHT11. Надо будет DHT22 скачать.

0  
64 exersizze   (23.09.2014 08:26) [Материал]
Вполне нормальная влажность, учитывайте еще погрешность датчика в 5% (а если вспомнить откуда он родом может и все 10% ). Как я понял показания с датчика у вас домашние, а гигрометр на работе; попробуйте сравнить показания этого датчика в одном помещении с гигрометром.

63 NCy   (22.09.2014 22:49) [Материал]
Собрал на DHT11.
Влажность показывает 36%, как впрочем во многих проектах у автора. А не мало ли?
На работе посмотрел по гигрометру было порядка 60%.

+1   Спам
62 шанти   (10.01.2014 00:00) [Материал]
может кому будет интересно 2 дня с DHT22 промучился пока в DHT22_kip96 в строке
Waitms 10 ' wait 20 ms
с 20 на 10 не поставил ,смотрел на нули,заработал ))),планирую его в логер температуры 2 применить в место DHT11.

61 max-x   (07.12.2013 00:47) [Материал]
Спасибо за подробное пояснение. Буду пробовать.

60 exersizze   (06.12.2013 08:23) [Материал]
Это настройка буфера для работы uart, первоначально в коде был вывод показаний в терминал. Потом переделал на работу с дисплеем а эти строчки остались. В общем пробуйте.

59 max-x   (04.12.2013 01:08) [Материал]
С этими настройками компилируется только если убрать строки
Config Serialin = Buffered , Size = 128
Config Serialout = Buffered , Size = 128
как написал exersizze.
Я не понял, какое назначение этих двух строк, если можно, поясните.

58 sany2   (04.12.2013 00:11) [Материал]
max-x попробуй так:

$regfile = "attiny2313.dat"
$hwstack = 32
$swstack = 8
$framesize = 16

57 max-x   (03.12.2013 23:06) [Материал]
При попытке перекомпилировать под Tiny компилятор выдает ошибку 22:Out of SRAM. Чем это может быть вызвано?

56 exersizze   (03.12.2013 20:45) [Материал]
В восьмой меге код занимает всего 17%, так что думаю можно. Еще можно убрать строчки
Config Serialin = Buffered , Size = 128
Config Serialout = Buffered , Size = 128

но попробовать пока не начем, точно сказать не могу.

55 max-x   (03.12.2013 17:59) [Материал]
А до размера памяти ATTiny2313 код уменьшить возможно?

+1   Спам
54 trololo   (11.11.2013 22:23) [Материал]
Собрал я прибор с датчиком DHT11, показывает точно как температуру, так и влажность.

53 exersizze   (27.10.2013 21:24) [Материал]
частота здесь  не критична, поэтому можно поменять

$crystal = 16000000
на
$crystal = 8000000

52 trololo   (27.10.2013 14:12) [Материал]
Скажите, можно ли поменять частоту на 8000000, если можно то что менять надо в коде?

+1   Спам
51 exersizze   (31.07.2013 10:54) [Материал]
Мерцание происходит из-за большого промежутка времени после очистки дисплея и последующим выводом информации на него. Можно или ускорить вывод данных (использовать 8и битное подключение, убрать все задержки) или избавиться от предварительной очистки. Убрать команду CLS и зразу выводить, а чтобы не оставался мусор от прошлых значений, неиспользуемые знакоместа забивать пробелами.

50 domrustika   (31.07.2013 01:45) [Материал]
как убрать мигание(обновление) экрана при показе данных?

49 exersizze   (30.07.2013 20:25) [Материал]
Угу, работает не правильно. Надо ставить 16МГц.
Можно попробовать перекомпилировать программу под 8МГц и попробовать так.
Чуть ниже Skull   привел польский код, попробуй его зашить.

UPD: вспомнил, прочитав старые комментарии http://avrproject.ru/publ....ent2331 , что иногда программа висла перед главным циклом. Спасало добавление небольшой задержки в 1 секунду после команды LCD

48 Polurival   (30.07.2013 19:43) [Материал]
Спасибо за подсказку, $crystal = 16000000 изменил на 8000000 и виснуть перестало. Сейчас показывает следующее:
TMP: 0C
PHP: 1%
то есть что-то работает неправильно, есть идеи что не так?

47 exersizze   (29.07.2013 16:07) [Материал]
частота меги установлена 16МГц ?

46 Polurival   (29.07.2013 13:58) [Материал]
Использовал код статьи один в один. Выводятся надписи "AVRproject.ru" и "DHT11 sensor" и дальше ничего не происходит. Датчик DHT11, микроконтроллер Atmega8A-PU. В чем может быть проблема? Может быть такое что 5 датчиков, которые я заказал на aliexpress все нерабочие)?

+1   Спам
45 Skull   (09.07.2013 00:33) [Материал]
Накопал у поляков , так короче, и работает на 2313
Declare Sub Get_dht11(t_dht As Byte , Rh_dht As Byte)

Dht_put Alias Porta.0
Dht_get Alias Pina.0
Dht_io_set Alias Ddra.0

Dim T_dht11 As Byte
Dim Rh_dht11 As Byte

Set Dht_io_set
Set Dht_put

Print
Print "DHT11 test"
Do
Waitms 2500
Call Get_dht11(t_dht11 , Rh_dht11)
' Print "T=" ; T_dht11 ; "'C"
' Print "Rh=" ; Rh_dht11 ; "%"
' Print
Loop

End 'end program

Sub Get_dht11(t_dht As Byte , Rh_dht As Byte)
Dim A_dht As Byte , L_dht As Byte , Vl(5) As Byte
Dim Mybyte As Byte
Set Dht_io_set
Reset Dht_put
Waitms 18 '20

'20-40us
Set Dht_put
Waitus 40
Reset Dht_io_set
Waitus 40
If Dht_get = 1 Then
Rh_dht = 255
Exit Sub
End If

Waitus 80 '80us
If Dht_get = 0 Then
Rh_dht = 255
Exit Sub
End If

While Dht_get = 1 : Wend

For A_dht = 1 To 5
For L_dht = 7 To 0 Step -1
While Dht_get = 0 : Wend
'26-28us
'70us
Waitus 30 '30us
If Dht_get = 1 Then
Vl(a_dht).l_dht = 1

While Dht_get = 1 : Wend
Else
Vl(a_dht).l_dht = 0

End If

Next
Next

Set Dht_io_set
Set Dht_put

Mybyte = Vl(1) + Vl(3)
If Mybyte <> Vl(5) Then
Vl(1) = 255
End If
Print Bin(mybyte) ; "crc1" 'samo za test

T_dht = Vl(3)
Rh_dht = Vl(1)
For A_dht = 1 To 5 'samo za test
Print Bin(vl(a_dht))
Next
' Print Vl(1)
' Print Vl(3)
End Sub

44 max   (23.05.2013 15:50) [Материал]
7-8%.

43 exersizze   (22.05.2013 22:04) [Материал]
Ну так чувствительнее, это же хорошо) Показания сильно отличаются у обоих?

42 max   (22.05.2013 18:50) [Материал]
Мне пришел DHT22. После сравнения показаний(для DHT11 использовал код exersizze, для DHT22 - kip96) мне, если честно, больше понравился DHT11. DHT22 очень чувствительный, показания сильно скачут, так же, как у kip96. Поэтому склоняюсь к DHT11.

+1   Спам
41 kip96   (21.05.2013 20:15) [Материал]
Пришёл мне DHT11.
Отличается форматом передачи данных. Как и писал exersizze: первые 8 бит - целая часть влажности + 8 бит десятая часть влажности + 8 бит целая часть температуры + 8 бит десятая часть температуры + 8 бит контрольной суммы. При этом дробные части всегда по нулям. 22-ой же передаёт в формате WORD+WORD+BYTE. Т.е., к примеру влажность 65,6% передаёт как целое число 656. Но контрольная сумма складывается по байтно. На один контроллер повесил оба датчика. Показывют в пределах погрешности, но реакция у 22 на порядок больше. он реагирует даже когда к ниму подходишь. http://yadi.sk/d/45HjXvFe52IhU На видео реакция на влажную руку.

40 Polle   (12.05.2013 16:28) [Материал]
Вот если кому надо более подробный PDF на DHT22 : http://mk90.ru/files/datasheets/AM2302.pdf Судя по этому документу отличие от DHT11
в длительности стартового импульса: для DHT11 не менее 18мс, а для DHT22 1мс максимум 20мс.

+1   Спам
39 Polle   (12.05.2013 09:14) [Материал]
Спасибо всем за помощь, мои часы с датчиком DHT22 заработали. Оказалось что данные с датчика идут головой вперёд: сперва старший бит старшего байта влажности ... и заканчивается пакет младшим битом байта контрольной суммы т.е. вот так:
>>>первые 8 бит - целая часть влажности + 8 бит десятая часть влажности + 8 бит целая часть температуры + 8 бит десятая часть температуры + 8 бит контрольной суммы.

38 max   (11.05.2013 18:03) [Материал]
Для DHT22 - не спорю, для DHT11 код прямо из статьи:
'начинаем раскладывать полученные данные
Tmp_str8 = Left(sensor_data , 8) 'берем левые 8 символов переменной
H = Binval(tmp_str8) 'это целая часть влажности
Tmp_str8 = Mid(sensor_data , 17 , 8) 'вытаскиваем 8 символов из середины
T = Binval(tmp_str8) 'это целая часть температуры
Tmp_str8 = Right(sensor_data , 8) 'правые 8 символов
Crc = Binval(tmp_str8) 'проверочные данные

1-30 31-60 61-67
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]






авторизация
Логин:
Пароль: