Arduino. Датчик влажности и температуры DTH11, общаемся на прямую.

  1. Плата Arduino. x1
    arduino uno
  2. Компьютер(для написания и загрузке кода, а так же мы будем брать с него электричество и общаться с ним). x1
  3. Провод для соединения компьютера и платы. x1
    USBwire
  4. Датчик температуры и влажности DTH11.
    DTH11
  5. Провода. x3
    wire
  6. Есть схемы с внешним источником питания, но можно взять питание и с платы.

Схема:

ArduinoDTH11_1_bbArduinoDTH11_1_схемаDTH11_3

ArduinoDTH11_2_bbArduinoDTH11_2_схема

Рассмотрим скетч, в котором мы будем управлять датчиком DTH11 на прямую, через передачу и приём сигнала(а так же его обработку) используя только стандартные функции.

Сначала зададим глобальные переменные, которые будут использоваться во всё коде:

В переменной dataPin мы будем хранить значение номера штырька. Объявляется dataPin как константа (const) и подразумевается, что значение переменной не будет менятся.

Так же у нас будет использоваться две переменные со значением температуры и влажности (переменные целого типа):

В блоке Setup устанавливаем скорость взаимодействия компьютера и Arduino.

В нашем случае в значение 115200 бод

дальше мы объявляем функцию readDTH11() которая будет отдавать 0 когда удалось получить значение, -1 когда датчик не отвечает, и -2 когда не совпала контрольная сумма. Перед тем как вернуть 0 данная функция назначит глобальным переменным humidity и temperature значения влажности и температуры соответственно.

Рассмотрим её по подробнее:

Задаём переменные которые будут использоваться в фунции:

Задаём массив recvBuffer целых 8 битных без знаковых чисел, с точной шириной. Длинной 5

в которыё мы будем вносить данные со щётчика.

а так же переменные cnt = 7 в ней будет хранится номер текущего передаваемого бита.

и idx = 0 в котором будет хранится номер байта идущего со счётчика( или индекс массива)

Здесь же зануляем массив:

теперь мы готовы начать обмен данными…

устанавливаем значение штырька в режим вывода.

устанавливаем значение LOW

ждём 18 милисекунд

включаем напряжение (устанавливаем режим HIGH)

на 40 микросекунд

тем самым мы послали сигнал на сенсор, который говори, что мы готовы начать принимать данные.

устанавливаем штырёк в режим приёма данных

Пропускаем первый сигнал. (LOW-HIGH);

опередляем переменную timeout в которой будет хранится кол-во итераций циклов, что бы не попасть в бесконечную петлю.

Выставляем максимальное кол-во циклов, ожидания перехода из состояния штырька из  LOW  в HIGH.

Непосредственно само ожидание, пока значение штырька равно LOW выполнять цикл, при этом каждый цикл значение timeout уменьшается на 1:

а если щётчик достиг 0, то прерываем работу функции со значением -1

далее делаем замер времени:

в переменной t — сохранится количество микросекунд пройденное с момента загрузки платы.

далее по принципу предыдущего цикла ждём, пока закончится идти сигнал HIGH

Далее будет идти интересная строчка:

Разберём её по подробнее:

(micros()-t)>40 здесь мы опять смотрим сколько прошло времени с момента запуска платы (micros()) и вычитаем из неё ранее сохранённое значение времени. если это значение больше 40 микросекунд, будем считать, что это 1. На этом шаге есть нюанс, раз в примерно 70 минут это значение сбрасывается. И если мы попали именно в этот промежуток времени то вместо 1 может получится 0.

Вы ражением (1 <<cnt),  мы делаем побитовый сдвиг в лево иденицы на номер текущего бита. Например если cnt=7 (это первоначальное значение которое мы задали), то если у нас было &0000001(двоичная запись числа), то после операции 1<<7 у нас получится &1000000. Соответсвенно: (1<<6) = (&00000001<<6) = 0100000.

recvBuffer[idx] |= (1 <<cnt) можно записать, как  recvBuffer[idx] =recvBuffer[idx]|(1 <<cnt)

Знак | является по битовым или на всякий случай:

a b aVb
1 1 1
1 0 1
0 1 1
0 0 0

побитовое или будет сравнивать двоичные записи данных чисел по битам и выполнять над ними операцию или, так например для 12|10=(&1100 | &1010)=&1110=14

ну и соответственно recvBuffer[idx] будет являться текущим байтом данных.

Соответственно строчка:

делает следующую операцию, если время сигнала больше 40 микросекунд, то текущий бит буфера изменяется на 1 вместо 0. (не забываем, что в начале мы его обнулили).

Далее:

Если мы закончили заполнять байт, переходим к следующему. Если же мы не дошли до конца:

переходим к следующему биту(то есть предыдущему… 🙂

Здесь заканчивается основной цикл, тоесть мы получили 40 бит (for (int i=0; i<40; i++)).

После этого разбираем полученный буфер на значения, так:

В нулевом(первом) бите будет находится влажность мы передаём её в глобальную переменную humidity

Во втором (третьем) бите будет хранится значение температуры и мы её передаём в глобальную переменную temperature.

Далее проверяем контрольную сумму:

Если recvBuffer[4] = recvBuffer[0]+recvBuffer[2] то всё хорошо. А если нет, функция закончится и выведет значение -2.

Если всё хорошо то выводим 0.

Ура! функция закончилась, осталось ей воспользоваться в главном цикле loop:

Здесь мы запускаем функцию readDTH11() и её вывод записываем в переменную ret.

Если мы не дошли до конца функции и вывалились по середине, то выводим код ошибки на компьютер.

а так же выводим текущие значения влажности и температуры

Делаем задержку между замерами.. датчик не может делать замеры чаще чем раз в 2 секунды.

Скетч закончился.

Видео процесса:

Другие статьи по программированию плат Arduino можно посмотреть здесь.

Комментарии:

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

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