Подключение DHT11 и DHT22 к Arduino: схема и код
DHT11 это самый дешёвый способ добавить в проект температуру и влажность, а DHT22, он же AM2302, это его точный старший брат. Подключение у них одинаковое: питание, земля и данные на любой цифровой пин с подтяжкой 10 кОм.
Полные уроки с симулятором: подключение и первые данные и термостат с гистерезисом.
Ниже разбираем, как устроен протокол DHT и почему подтяжка обязательна, что означает NAN в показаниях, где датчик надо ставить, чтобы он не врал, какой датчик климата выбрать новичку и как проверить схему по семи шагам.
Схема подключения
| Вывод DHT (слева направо, лицом к решётке) | Куда подключать |
|---|---|
| 1 — VCC | 5 В (DHT22 может от 3.3 В) |
| 2 — DATA | Любой цифровой пин, например D2, и подтяжка 10 кОм к VCC |
| 3 — NC | Никуда |
| 4 — GND | GND |
Корпус датчика смотрит на вас решёткой, а под ней пластиковый держатель с четырьмя выводами. В зависимости от партии встречается и трёхвыводный вариант, где средний вывод это DATA, а NC нет вовсе. Протокол у обоих датчиков один и тот же, собственный, разработанный производителем: Arduino сначала тянет линию данных вниз на 18–30 мс, этим она говорит «дай замер», а датчик в ответ отдаёт 40 бит, где единица это около 70 мкс, а ноль около 26–28 мкс. Провод до датчика при этом работает как открытый коллектор: в покое линию держит подтяжка, и именно поэтому подтяжка обязательна.
Отсюда практический вывод. Без подтяжки линия данных висит в воздухе, Arduino не может отличить ноль от единицы, и вместо замера получает мусор, который библиотека честно превращает в NAN. Подтягивающий резистор нужен от 4,7 до 10 кОм, классическое значение 10 кОм подходит всем. Второй вывод, который стоит помнить, длина провода до датчика. При трёх метрах и более сигнал уже подъезжает искажённым, и надёжнее питать датчик от 5 В, а не от 3,3 В.
Код: чтение температуры и влажности
#include "DHT.h"#define DHTPIN 2#define DHTTYPE DHT11DHT dht(DHTPIN, DHTTYPE); void setup() { Serial.begin(9600); dht.begin();} void loop() { float t = dht.readTemperature(); float h = dht.readHumidity(); Serial.print("T="); Serial.print(t); Serial.print(" H="); Serial.println(h); delay(2000); // DHT не любит частые опросы}В коде есть две детали, которые стоит понимать. Первая: readTemperature() и readHumidity() внутри делают один и тот же полный обмен с датчиком, так что вызывать их подряд это два одинаковых замера, а не два разных. Правильнее один раз вызвать read(), получить оба значения и работать с ними. Вторая: библиотека возвращает NAN, если замер не удался, и молчаливый NAN в Serial Monitor выглядит как «датчик сломан», хотя чаще всего дело в подтяжке или в слишком частом опросе. Строка delay(2000) это не просто вежливость: DHT11 физически не успевает отдать второй замер раньше секунды, а DHT22 держит паузу в две секунды.
Библиотеку выбирают по названию. Самый ходовой вариант это DHT sensor library от Adafruit: она тянет за собой ещё и Adafruit Unified Sensor, поэтому при установке из менеджера подтянется вторая. Есть и более лёгкая DHT11 library, где всё написано в одном файле и ничего тянуть не нужно. Для ESP32 существует отдельная DHTesp: она использует другую реализацию таймера и работает заметно устойчивее, потому что обычная библиотека на ESP32 опаздывает с опросом.
DHT11 vs DHT22: что выбрать
| Параметр | DHT11 | DHT22 (AM2302) |
|---|---|---|
| Точность температуры | ±2 °C | ±0.5 °C |
| Диапазон температуры | 0…+50 °C | −40…+80 °C |
| Влажность | 20–80%, ±5% | 0–100%, ±2% |
| Опрос | раз в 1 с | раз в 2 с |
| Цена | копейки | в 3–4 раза дороже |
| Для чего | комнатный термометр, обучение | теплицы, погодные станции, термостаты |
Разница в цене обычно небольшая, и если датчик выбирают один раз, мы берём DHT22. Дело в диапазоне: DHT11 физически не измеряет температуру ниже нуля, то есть для уличного термометра он не годится вообще, а DHT22 работает и в мороз. Плюс DHT11 выдаёт целые числа и слегка «прыгает» между соседними градусами, а DHT22 отдаёт значения с десятыми долями. Единственный аргумент за DHT11 это цена и то, что он встречается в учебных наборах.
Тупик: датчик молчит, хотя подтяжка на месте
Случай из нашей практики: DHT11 на макетке, подтяжка 10 кОм, питание 5 В, всё по схеме, а в мониторе порта стабильно NAN. Мы перепроверили ноги, переставили датчик, заменили библиотеку на более простую, перечитали протокол и решили, что модуль бракованный.
Модуль был в порядке. Проблема была в том, что мы считали датчик сразу после подачи питания: в этот момент внутренняя схема выходит из режима сна, и первый запрос она не обслуживает. Как только мы добавили паузу перед первым чтением, замер появлялся сразу и дальше шёл стабильно. Второй по важности случай тот же по симптому, но с другой причиной: провод DATA был воткнут в соседнее гнездо макетки, и линия просто не доходила до датчика. С тех пор у нас порядок проверки зафиксирован: питание, подтяжка, ноги, пауза после включения, и только потом замена железа.
Личный опыт: где мы ставили датчик и почему он врал
Замеры в комнате у DHT11 расходились с показаниями обычного термометра, и мы искали ошибку в коде, пока не обратили внимание на место установки. Датчик был закреплён прямо над платой, а Arduino под нагрузкой сама греется. Корпус датчика тоже нагревается: он измеряет температуру воздуха вокруг себя, и если это воздух над греющейся платой, замер будет завышен на градус-полтора.
Как только мы вынесли датчик на отдельную проволоку в сторону от платы, показания почти сравнялись с термометром. Ещё один эффект мы наблюдали при работе в теплице: там влажность меняется медленно, и датчик успевает за ней следовать, но если закрыть его коробкой, он меряет воздух внутри коробки, а не вокруг неё. Общий вывод, который мы записали себе: датчик климата измеряет воздух в том месте, где стоит, и это место надо выбирать так же внимательно, как сам датчик.
Авторская позиция: какой датчик климата взять
Мы советуем начинать с DHT11 только ради экономии: его почти всегда уже лежит в наборе, и он прощает ошибки, потому что недорогой и легко заменяемый. Как только в проекте появляется решение, зависящее от показаний (термостат, вентилятор, запись в лог), мы переходим на DHT22 или вовсе на BME280.
Причина в том, что DHT11 не умеет ничего, кроме температуры и влажности, и выдаёт их целыми числами с погрешностью в пару градусов. BME280 даёт то же самое плюс атмосферное давление, работает по I2C, не занимает отдельный пин с подтяжкой и заметно лучше ведёт себя на длинных проводах. Для учебного термостата внутри комнаты DHT11 достаточно, для погодной станции на улице мы берём BME280 в защищённом корпусе, и гайд по BME280 разбирает его подробно. Отдельно скажем про DS18B20: он меряет только температуру, зато в герметичном корпусе и с точностью около половины градуса, поэтому в воде или в холодильнике он лучше любого DHT.