Администрация форума не несёт ответственности за достоверность информации и оставляет за собой право редактировать или в особых случаях даже удалять посты без предупреждения. Спасибо за понимание.

Программирование ATMEL в BASCOM.

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » Программирование ATMEL в BASCOM. » Исходники » Библиотека для DHT22


Библиотека для DHT22

Сообщений 1 страница 26 из 26

1

Написал небольшую библиотеку для датчика температуры и влажности DHT22. Проверена в железе и протеусе, работает нормально. Может кому-то пригодится.

Версия для Bascom 2.0.7.8.

Код:
$nocompile

Dht_port Alias Portc.2
Dht_pin Alias Pinc.2
Dht_ddr Alias Ddrc.2

Declare Function Dht_crc(buff() As Byte , Byval Size As Byte) As Byte
Declare Function Dht_read(byref Thermo As Integer , Byref Humidity As Integer) As Byte

Const Dht_ok = 0                                  ' Ошибок нет.
Const Dht_not_sensor = 1                          ' Датчик не обнаружен.
Const Dht_crcerr = 2                              ' Ошибка контрольной суммы.
Const Dht_timeout = 3                             ' Датчик вовремя не ответил и произошел выход по таймауту.

Const Dht_maxcount = 250

Dim Dht_i As Byte
Dim Dht_pinstate As Byte

Goto Dht_m1

Dht_pinwait:
  For Dht_i = 0 To Dht_maxcount
    If Dht_pin = Dht_pinstate.0 Then
      Exit For
    End If
  Next Dht_i
Return

Macro Dht_waitpin
  Gosub Dht_pinwait
  If Dht_i >= Dht_maxcount Then
    Exitcode = Dht_timeout
    Exit Do
  End If
End Macro

Function Dht_crc(buff() As Byte , Byval Size As Byte) As Byte
  Local Crc As Byte , I As Byte
  Crc = 0
  For I = 1 To Size
    Crc = Crc + Buff(i)
  Next I
  Dht_crc = Crc
End Function

Function Dht_read(byref Thermo As Integer , Byref Humidity As Integer) As Byte
   Local Exitcode As Byte , Temp As Long , Crc As Byte , Count As Byte

   Exitcode = Dht_ok
   Thermo = 0
   Humidity = 0
   Temp = 0
   Crc = 0

   Dht_ddr = 1                                    ' Настраиваем порт на выход.
   Dht_port = 0                                   ' Логический 0 на выходе.
   Waitms 20
   Dht_ddr = 0                                    ' Настраиваем порт на вход.
   Waitus 40

   If Dht_pin = 0 Then                            ' Датчик установил лог.0 на выводе.

     Waitus 80

     If Dht_pin = 1 Then                          ' Датчик установил лог.1 на выводе.

        Dht_pinstate = 0
        Gosub Dht_pinwait
        If Dht_i < Dht_maxcount Then

           Count = 32

           Do
              Decr Count
              Dht_pinstate = 1
              Dht_waitpin
              Waitus 34
              If Dht_pin = 1 Then
                Temp.count = 1
                Dht_pinstate = 0
                Dht_waitpin
              End If
           Loop Until Count = 0

           Count = 8

           Do
              Decr Count
              Dht_pinstate = 1
              Dht_waitpin
              Waitus 34
              If Dht_pin = 1 Then
                Crc.count = 1
                Dht_pinstate = 0
                Dht_waitpin
              End If
           Loop Until Count = 0

           If Exitcode = Dht_ok Then
              If Dht_crc(temp() , 4) = Crc Then
                Thermo = Temp
                If Thermo.15 = 1 Then             ' Отрицательная температура.
                   Thermo = Thermo Xor &H7FFF
                   Thermo = Thermo + 1
                End If
                Humidity = Highw(temp)
              Else
                Exitcode = Dht_crcerr
              End If
           End If

        Else
          Exitcode = Dht_timeout
        End If

     Else
       Exitcode = Dht_not_sensor
     End If

   Else
     Exitcode = Dht_not_sensor
   End If

   Dht_read = Exitcode
End Function


Dht_m1:

Версия для Bascom 2.0.7.7.

Код:
$nocompile

Dht_port Alias Portc.2
Dht_pin Alias Pinc.2
Dht_ddr Alias Ddrc.2

Declare Function Dht_crc() As Byte
Declare Function Dht_read(byref Thermo As Integer , Byref Humidity As Integer) As Byte

Const Dht_ok = 0                                  ' Ошибок нет.
Const Dht_not_sensor = 1                          ' Датчик не обнаружен.
Const Dht_crcerr = 2                              ' Ошибка контрольной суммы.
Const Dht_timeout = 3                             ' Датчик вовремя не ответил и произошел выход по таймауту.

Const Dht_maxcount = 250

Dim Dht_i As Byte
Dim Dht_pinstate As Byte
Dim Dht_inbytes As Long
Dim Dht_inbytes_arr(4) As Byte At Dht_inbytes Overlay

Goto Dht_m1

Dht_pinwait:
  For Dht_i = 0 To Dht_maxcount
    If Dht_pin = Dht_pinstate.0 Then
      Exit For
    End If
  Next Dht_i
Return

Macro Dht_waitpin
  Gosub Dht_pinwait
  If Dht_i >= Dht_maxcount Then
    Exitcode = Dht_timeout
    Exit Do
  End If
End Macro

Function Dht_crc() As Byte
  Local Crc As Byte , I As Byte
  Crc = 0
  For I = 1 To 4
    Crc = Crc + Dht_inbytes_arr(i)
  Next I
  Dht_crc = Crc
End Function

Function Dht_read(byref Thermo As Integer , Byref Humidity As Integer) As Byte
   Local Exitcode As Byte , Crc As Byte , Count As Byte , Tempb As Byte

   Exitcode = Dht_ok
   Thermo = 0
   Humidity = 0
   Dht_inbytes = 0
   Crc = 0

   Dht_ddr = 1                                    ' Настраиваем порт на выход.
   Dht_port = 0                                   ' Логический 0 на выходе.
   Waitms 20
   Dht_ddr = 0                                    ' Настраиваем порт на вход.
   Waitus 40

   If Dht_pin = 0 Then                            ' Датчик установил лог.0 на выводе.

     Waitus 80

     If Dht_pin = 1 Then                          ' Датчик установил лог.1 на выводе.

        Dht_pinstate = 0
        Gosub Dht_pinwait
        If Dht_i < Dht_maxcount Then

           Count = 32

           Do
              Decr Count
              Dht_pinstate = 1
              Dht_waitpin
              Waitus 34
              If Dht_pin = 1 Then
                Dht_inbytes.count = 1
                Dht_pinstate = 0
                Dht_waitpin
              End If
           Loop Until Count = 0

           Count = 8

           Do
              Decr Count
              Dht_pinstate = 1
              Dht_waitpin
              Waitus 34
              If Dht_pin = 1 Then
                Crc.count = 1
                Dht_pinstate = 0
                Dht_waitpin
              End If
           Loop Until Count = 0

           If Exitcode = Dht_ok Then
              Tempb = Dht_crc()
              If Tempb = Crc Then
                Thermo = Dht_inbytes
                If Dht_inbytes.15 = 1 Then        ' Отрицательная температура.
                   Dht_inbytes = Thermo Xor &H7FFF
                   Thermo = Thermo + 1
                End If
                Humidity = Highw(dht_inbytes)
              Else
                Exitcode = Dht_crcerr
              End If
           End If

        Else
          Exitcode = Dht_timeout
        End If

     Else
       Exitcode = Dht_not_sensor
     End If

   Else
     Exitcode = Dht_not_sensor
   End If

   Dht_read = Exitcode
End Function



Dht_m1:

Вывод к которому подключен датчик, указывается в этих строках.

Код:
Dht_port Alias Portc.2
Dht_pin Alias Pinc.2
Dht_ddr Alias Ddrc.2

В данном случае, датчик подключен к выводу  PortC.2.

Пример использования.

Код:
$regfile = "m8def.dat"
$crystal = 4000000
$hwstack = 96
$swstack = 64
$framesize = 64

$include "DHT_Lib.bas"

Config Lcd = 16 * 2                               ' Дисплей 2 строки по 16 символов
Config Lcdbus = 4
Config Lcdmode = Port
Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portb.1 , Db6 = Portb.2 , Db7 = Portb.3 , Rs = Portb.4 , E = Portb.5

Cls
Cursor Off
Wait 2


Dim Thermo As Integer , Humidity As Integer
Dim T As Single , H As Single
Dim Errcode As Byte

Do
   Cls
   Errcode = Dht_read(thermo , Humidity)
   If Errcode = Dht_ok Then

      T = Thermo / 10
      H = Humidity / 10

      Lcd "Thermo " ; Fusing(t , "###.#") ; " C"  '
      Lowerline
      Lcd "Humidity " ; Fusing(h , "###.#") ; " %"
   Else
     Lcd "Error code " ; Errcode
   End If

   Wait 2

Loop

End

Функция Dht_read() вернет одно из следующих значений.

Dht_ok - Ошибок нет.
Dht_not_sensor - Датчик не обнаружен.
Dht_crcerr -  Ошибка контрольной суммы.
Dht_timeout - Датчик вовремя не ответил и произошел выход по таймауту.

Отредактировано Пётр (2015-02-03 19:52:30)

+3

2

100 баллов из 5-ти возможных, так держать!

А, что значит,  - "в Протеусе работает"?, ведь модели-то нет, или есть?

0

3

Модель есть и работает, но еще не до конца закончена.

+1

4

Пётр написал(а):

Модель есть и работает, но еще не до конца закончена.


Агааааааааааааааааа, вот значит как!

Надеюсь поделитесь с народом?

0

5

Ждем модель!!!! А работа на все +++++++++(10 шт +)

0

6

Библиотека компилируется только в Bascom 2.0.7.8, в ранних версиях нет поддержки массивов в функциях и процедурах.

Отредактировано sasha_1973 (2015-01-08 10:57:17)

0

7

Чтобы код компилировался в версиях ниже 2.0.7.7, нужно эту строку

Код:
Function Dht_crc(buff() As Byte , Byval Size As Byte) As Byte

Заменить на эту

Код:
Function Dht_crc(buff As Byte , Byval Size As Byte) As Byte

, а эту

Код:
If Dht_crc(temp() , 4) = Crc Then

на эту.

Код:
If Dht_crc(temp , 4) = Crc Then

Сейчас у меня нет установленных ранних версий баскома. Проверите у кого есть и напишите решило ли это проблему.

0

8

Модели DHT 11 DHT 22 для протеуса. http://pure-basic.narod.ru/forum_files/ … roteus.zip
К сожалению тема закрыта и там выложить не могу.

Для установки модели нужно скопировать папки LIBRARY и MODELS в папку с протеусом чтобы файлы из этих папок попали в одноименные папки протеуса.
Примеры в папке Example.

http://s017.radikal.ru/i409/1501/e2/2505660779cf.png

Отредактировано Пётр (2015-01-10 01:03:35)

+6

9

Пётр написал(а):

Модели DHT 11 DHT 22 для протеуса.

Большое Вам СПАСИБО за Ваш ТРУД!!!

Пётр написал(а):

К сожалению тема закрыта и там выложить не могу.

Ветку открыл, перенесите пожалуйста.

0

10

Разместил там ссылку на модель. Заодно обновил файлы модели. Теперь сохраняются результаты изменения значений с помощью кнопок на модели.

0

11

Добавил в первое сообщение темы, версию библиотеки для Bascom 2.0.7.7.
В этой версии баскома похоже есть ошибка потому что такой код не работает правильно.

Код:
If Dht_crc() = Crc Then

А такой работает без проблем.

Код:
Tempb = Dht_crc()
If Tempb = Crc Then

В версии 2.0.7.8 нормально работают оба варианта.

+1

12

Модель для протеуса некорректно работает с отрицательными температурами.
Для температуры -10.1 выдает значения 0х80 и 0х64, хотя согласно описанию должно быть 0х80 и 0х65
Для всех отрицательных температур та же ошибка в 0.1 градуса.

Соответственно в программе Thermo = Thermo Xor &H7FFF, тоже не верно, необходимо сбросив старший бит, просто заменить знак на отрицательный.

Вот обсуждении на другом форуме DHT22

Отредактировано CodeNameHawk (2015-04-12 17:24:11)

0

13

CodeNameHawk написал(а):

Соответственно в программе Thermo = Thermo Xor &H7FFF, тоже не верно, необходимо сбросив старший бит, просто заменить знак на отрицательный.

Не совсем так. Эта строка не сбрасывает биты, а инвертирует все биты кроме старшего (15-го). Т. е. выполняет побитовое исключающее ИЛИ. Установленный старший бит означает что температура отрицательная.

В исходнике модели для протеуса нужно найти строки в процедуре ResData

Код:
  If *This\OutBuff\Thermo & $8000 ; Температура отрицательная.
    *This\OutBuff\Thermo ! $7FFF
  EndIf

И после *This\OutBuff\Thermo ! $7FFF добавить *This\OutBuff\Thermo + 1 Т. е. должно быть

Код:
  If *This\OutBuff\Thermo & $8000 ; Температура отрицательная.
    *This\OutBuff\Thermo ! $7FFF
    *This\OutBuff\Thermo + 1
  EndIf

Такая коррекция (прибавление 1) необходима потому что отрицательные числа хранятся в доп. коде. Это я забыл учесть.
Если это нужно срочно, можете скачать PureBasic 5.24 Windows x86 и внести эти изменения в файл Src\DLL\DHT22.pb
Компиляция выполняется кликом по пункту "Создать приложение" и меню "Компилятор".

Чуть позже исправлю и обновлю архив.

+1

14

CodeNameHawk написал(а):

необходимо сбросив старший бит, просто заменить знак на отрицательный.

Просто имел ввиду, что то типа этого (пишу в основном на С)

Код:
f = ((datadht[2]& 0x7F) << 8) | datadht[3];
f *= -1;

Добавьте

Код:
Thermo = Thermo +1

и в код ваших библиотек, после

Код:
If Thermo.15 = 1 Then             ' Отрицательная температура.
Thermo = Thermo Xor &H7FFF

Отредактировано CodeNameHawk (2015-04-13 09:47:23)

0

15

Постараюсь в ближайшее время сделать.

0

16

Обновил библиотеку. Скачать можно по ссылке выше.

0

17

Спасибо большое!!!
Воспользовался библиотекой, та, что в архиве для Протеус. Температура в норме, но показания 1.2% влажности вместо 25-35%, если подуть, то сразу все 64-77%
Перевёл тут и даже не понял, 2 часа в сухом месте, после 5 часов во влажном + свет влияет на показания....

Внимания Внимания Внимания Внимания применения: применение: применение: применение:
(1) Условия эксплуатации и хранения
Мы не рекомендуем претендуете RH-диапазон за пределы диапазона, указанного в данном описании. Датчик AM2302
может восстановиться после работы в ненормальном рабочем состоянии к калиброванного состояния, но ускорит старение датчиков.
(2) вниманий химических материалов
Пар из химических материалов могут создавать помехи чувствительные-элементы AM2302 и AM2302 опошлить чувствительность в.
(3) Утилизация, когда (1) и (2) происходит
Шаг первый: Держите датчик AM2302 при условии температуры 50 ~ 60Celsius, влажность <10% относительной влажности в течение 2-х часов;
Шаг второй: После того, как один шаг, держать датчик AM2302 при условии температуры 20 ~ 30Celsius, влажность
> 70% относительной влажности в течение 5 часов.
(4) Внимание к привязанностью котемпературной в
Относительная влажность воздуха сильно зависит от температуры, поэтому мы используем технологию температурной компенсации для
обеспечить точное измерение относительной влажности. Но это все-таки гораздо лучше держать датчик на той же температуре, когда
зондирования.
AM2302 должен быть установлен на месте, насколько это возможно из частей, которые могут вызвать изменение температуры.
(5) Внимания к свету
Длительное воздействие время сильного света и ультрафиолета может опошлить производительность AM2302 в.
(6) Внимания к соединению проводов
Качество соединительных проводов "будет влиять на качество связи и расстояние в, высокое качество экранирования-провод
рекомендуемые.
(7) Другие знаки внимания
* Сварка температура должна быть ниже 260Celsius.
* Избегайте использования датчика при условии росы.
* Не используйте этот продукт в устройствах безопасности или аварийной остановки или любого другого случая, что выход из строя AM2302 может
привести к травмам.

Использовал перед этим DTH-11 (другой иходнок, тот, что текст "1010101" набирает 40 символов), он показывал 22% влажности, а этот DTH-22 всего 2-3%, но стоит взять его в руки, как влажность сразу на десятки вверх. Может брак попался, температуру показывает нормально.

Отредактировано Ev3658 (2017-02-07 18:24:01)

0

18

Возможно датчик влажности неисправен.

0

19

Пётр написал(а):

Возможно датчик влажности неисправен.

Подключил другой, еле нашел. Тоже самое. Температуру показывает нормально, но влажность сама падает.
Правда у более нового до единицы, у залежалого пару лет до 4%
Стоит пальцами взять, как через 4ре измерения до 35%, отпускаю - медленно...медленно до минимума.
Вероятно как-то х обучить надо, наверно есть в нём чего-то для автокалибровки.

0

20

Тогда не помешало бы посмотреть логическим анализатором что выдает датчик. В протеусе нормально работает?

0

21

Пётр написал(а):

Тогда не помешало бы посмотреть логическим анализатором что выдает датчик. В протеусе нормально работает?

Я не пробовал. Протеус на столе лежит. Так-то если бы проблемы с передачей были бы, то проверка бы не прошла.
Опробовала разные резисторы 5-10км., другой порт, не, влажность минимальная, может я в сухом помещении нахожусь.
Разберусь чей. Просто думаю, вдруг кто сталкивался с этим. (температура +20/22 влажность 1-4%)

0

22

Китайский вариант датчика, бывает, как вариант, попробуйте так.

Перейдите на BME280  -  3 в одном  -  температура, давление, влажность.

Отредактировано sasha_1973 (2017-02-08 06:27:32)

0

23

Поставил ряд экспериментов, до 12-15% он очень врёт, выше уже вполне хорошо показывает. Если из холода поместить в тепло, отходит за несколько минут.
Мне их 4 штуки в 1 контроллер надо запихнуть.

0

24

Решил по Datasheet вкурить и сделать более компактный код.
Вот только не пойму, как реализовать контрольную проверку.
Вот мой кусочек кода, работает хорошо, но нужна проверка:
Шапка:

Код:
'--------------------------------------------------------------------------------------------------------------------------------------- Порты
Dthout1 Alias Porte.2                                       'выход пина порта данных на датчик
Dthin1 Alias Pine.2                                         'вход пина порта данных с датчика
Dthddr1 Alias Ddre.2                                        'переключатель порта на вход или выход

'--------------------------------------------------------------------------------------------------------------------------------------- Переменные
Dim Dthtemp As Integer                                      'данные температуры с датчика DTH
Dim Dthvlaga As Word                                        'данные влажности с датчика DTH
Dim Dthtest As Word                                         'для байта чётности (ещё не использовал)
Dim Dthbyte As Byte                                         'номер принимаемого бита
Dim Dthnomer As Byte                                        'номер принимаемого байта
Const Dthporog = 200                                        'допустимое время ожидания ответа с датчика
Dim Dthtim As Byte                                          'таймер временного ограничения в приёме информации с датчика DTH
Dim T As Single 
Dim H As Single

А это GoSub подпрогармма:

Код:
Dth1: 'Метка
Set Dthddr1                                                 'устанавливаем порт на выход
Reset Dthout1                                               'прижимаем к нулю
Waitms 2                                                    'ждём минимум 1-2ms
Set Dthout1                                                 'подаём единицу в датчик
Waitus 40                                                   'ждём 20-40us
Reset Dthddr1                                               'устанавливаем порт на вход
Reset Dthout1                                               'убираем единицу на всякий случай

Dthtim = 0                                                  'сбрасываем сторожевой счётчик
Do
   Incr Dthtim                                              'прибавляем сторожевой счётчик
   Waitus 1                                                 'пауза для подсчёта сторожевого счётчика
   If Dthtim = Dthporog Then                                'если долго нет ответа, выходим с ошибкой
      H = 0
      T = 0
      Return
   End If
Loop Until Dthin1 = 0                                       'продолжаем, если датчик подтянул к массе

'подготавливаем переменные
Dthtim = 0                                                  'для подсчёта длительности единицы и так-же сторожевой счётчик
Dthnomer = 0                                                'указывает в какую переменную принимает (0=влажность(16бит), 1=температура(16бит), 2=бит проверки(8бит), 3=выход)
Dthbyte = 16
Dthvlaga = 0                                                'переменная влажности
Dthtemp = 0                                                 'переменная температуры

Do
   If Dthin1 = 1 Then                                       'ждём единицы с датчика и приступаем к анализу её продолжительности (длительность единицы 25-28us означает принятый ноль, большая длительность означает принятую единицу)
      Do
      Waitus 1                                              'задержка в подсчёте
      Incr Dthtim                                           'подсчитываем длину единицы и так-же сторожим от зависания
         If Dthtim = Dthporog Then                          'если долго ждали, выходим с ошибкой
            H = 0
            T = 0
            Return
         End If
      Loop Until Dthin1 = 0                                 'после исчезновения единицы мы уже знаем её длину
   If Dthtim > 24 Then                                      'если единица была больше 24us+такты куска кода, то ставим этот бит в единицу, если нет, то ноль уже стоит
      Select Case Dthnomer                                  'выбираем нужную переменную для внесения принятых данных
      Case 0:
         Dthvlaga.dthbyte = 1
      Case 1:
         Dthtemp.dthbyte = 1
      End Select
   End If
   Decr Dthbyte                                             'убавляем номер бита в переменной, почему-то датчик шлёт всё наоборот.

   If Dthbyte = 255 Then                                    'номер бита если меньше нуля, то:
    Incr Dthnomer                                            'переходим на следующую переменную приёма (0=влажность(16бит), 1=температура(16бит), 2=бит проверки(8бит), 3=выход)
      If Dthnomer = 2 Then                                  'если принимаем контрольный бит, то нам нужно 8 бит, а не 16ть
         Dthbyte = 7
         Else
         Dthbyte = 15                                       'в переменной влажности и температуры 16 бит
      End If
   End If
   Dthtim = 0                                               'сбрасываем подсчёты длительности принятой единицы и сторожевого таймера.

  End If

Loop Until Dthnomer = 3                                     'выход по завершению приёма
Set Dthout1                                                 'подаём единицу на выход
Set Dthddr1                                                 'включаем порт на выход, датчику это нравится
H = Dthvlaga / 10                                           'расчёт принятых данных влажности
T = Dthtemp / 10                                            'расчёт принятых данных температуры

Return

+1

25

Waitus 1

Не, так лучше не делать, иначе где-то и что-то будет отваливаться постепенно в коде при использовании его в комплексе. :huh:

0

26

Кому интересно, то вот запись с 5ти датчиков DTH22, один на улице, запись с 3х часов ночи, продолжительность закиси больше суток (конец время написание поста)
Формат:
Номер минуты, влажность д1, температура д1, влажность д2, температура д2, влажность д3, температура д3, влажность д4, температура д4, влажность д5, температура д5, АЦП6, АЦП7
Расчёт для температуры и влажности простой: значение/10
Вот файл TXT - https://yadi.sk/i/CP9HKRZs3EdM53

Вроде ничего так, процент погрешности между датчиками не большой.
Три датчика стояли вместе и находились ближе к полу, а пятый был выше на столе - разница в 2 градуса. Это у меня в комнате такая погода и за окном, чего-то не очень климат то.

Отредактировано Ev3658 (2017-02-26 13:32:57)

+1


Вы здесь » Программирование ATMEL в BASCOM. » Исходники » Библиотека для DHT22