DHT11 и DHT22: чем отличаются
Оба датчика измеряют температуру и влажность и отдают данные по однопроводному цифровому интерфейсу — идеальны для начинающих. Различия в точности:
- DHT11 (синий): 0–50 °C, ±2 °C; влажность 20–80 %, ±5 %. Опрос раз в секунду. Дешевле.
- DHT22 / AM2302 (белый): −40…+80 °C, ±0.5 °C; влажность 0–100 %, ±2–5 %. Опрос раз в 2 секунды. Точнее и дороже.
Для домашнего термометра DHT11 хватит, для серьёзного проекта — DHT22.
Подключение
У датчика 4 вывода (у модулей — 3, плюс встроенная подтяжка): VCC, DATA, NC (не подключён), GND. На голом датчике DATA нужна подтяжка 4.7–10 кОм к VCC:
Arduino 5V ── VCC (пин 1)
Arduino 5V ──[10кОм]── DATA (пин 2) ── Arduino D2
пин 3 — не подключён
Arduino GND ── GND (пин 4)
Если у вас модуль с платой (3 пина) — резистор уже есть, просто: VCC→5V, DATA→D2, GND→GND.
Код: библиотека DHT
Ставим библиотеку «DHT sensor library» от Adafruit через менеджер библиотек (потянет и Adafruit Unified Sensor):
#include <DHT.h>
#define DHTPIN 2
#define DHTTYPE DHT22 // или DHT11
DHT dht(DHTPIN, DHTTYPE);
void setup() {
Serial.begin(9600);
dht.begin();
}
void loop() {
float h = dht.readHumidity();
float t = dht.readTemperature(); // °C; для °F — true вторым аргументом
if (isnan(h) || isnan(t)) {
Serial.println("ошибка чтения DHT");
return;
}
Serial.print("T: "); Serial.print(t);
Serial.print(" °C, H: "); Serial.print(h); Serial.println(" %");
delay(2000); // не чаще раза в 2 с для DHT22!
}
readTemperature/readHumidity возвращают NaN при ошибке — проверка isnan обязательна: при битой посылке или плохом контакте увидите NaN вместо мусора.
Ограничение опроса — критично
DHT22 можно опрашивать раз в 2 секунды, DHT11 — раз в секунду. Чаще — датчик возвращает ошибки или NaN. В реальном проекте опрос делают по millis(), а не по delay, чтобы не блокировать остальное:
DHT dht(2, DHT22);
uint32_t lastRead = 0;
float lastT = 0, lastH = 0;
void loop() {
if (millis() - lastRead >= 2000) {
lastRead = millis();
float t = dht.readTemperature();
float h = dht.readHumidity();
if (!isnan(t) && !isnan(h)) {
lastT = t; lastH = h;
}
}
// остальной код — lastT/lastH всегда свежие
}
Точность и стабильность
DHT-датчики просты и стабильны, но данные скачут — усредняйте:
float avgTemp() {
float sum = 0; int n = 0;
for (int i = 0; i < 5; ++i) {
float t = dht.readTemperature();
if (!isnan(t)) { sum += t; ++n; }
delay(2000);
}
return n ? sum / n : NAN;
}
Для быстрой фильтрации удобно экспоненциальное скользящее среднее — без хранения массива:
lastT = lastT * 0.8 + newT * 0.2; // 20% новое, 80% старое
Вывод на LCD
Связка DHT22 + LCD1602 — классический первый прибор:
#include <DHT.h>
#include <LiquidCrystal_I2C.h>
DHT dht(2, DHT22);
LiquidCrystal_I2C lcd(0x27, 16, 2); // адрес 0x27 или 0x3F
void setup() {
dht.begin();
lcd.init();
lcd.backlight();
}
void loop() {
float t = dht.readTemperature();
float h = dht.readHumidity();
if (!isnan(t) && !isnan(h)) {
lcd.setCursor(0, 0);
lcd.print("T: " + String(t, 1) + " C ");
lcd.setCursor(0, 1);
lcd.print("H: " + String(h, 0) + " % ");
}
delay(2000);
}
Типичные проблемы
- NaN постоянно: проверьте DATA-пин, подтяжку, правильный DHTTYPE и питание.
- NaN периодически: опрос слишком частый (меньше 2 с), длинный провод, помехи — экранируйте или сокращайте.
- Первое чтение всегда NaN: нормально — игнорируйте первое после старта.
- Числа скачут: усреднение или скользящее среднее.
- Низкая влажность <20 % или странные значения: датчик умер или DHT11 на пределе диапазона.
Итог
DHT22 + Arduino — пять проводов и десять строк кода до работающего термогигрометра. Правила: подтяжка DATA для голого датчика, опрос раз в 2 с, проверка isnan, усреднение для стабильности. Дальше этот код превращается в умный дом, логгер на SD-карту или метеостанцию с дисплеем.
Полный скетч: температурный монитор
#include <DHT.h>
const int DHT_PIN = 2;
DHT dht(DHT_PIN, DHT22);
void setup() {
Serial.begin(9600);
dht.begin();
}
void loop() {
float t = dht.readTemperature();
float h = dht.readHumidity();
if (isnan(t) || isnan(h)) {
Serial.println("ошибка чтения DHT");
} else {
Serial.printf("T=%.1f°C H=%.0f%% HI=%.1f°C\n",
t, h, dht.computeHeatIndex(t, h, false));
}
delay(2000); // DHT22 — не чаще раза в 2 секунды
}
computeHeatIndex даёт ощущаемую температуру — учитывает влажность.
Фильтрация показаний
DHT скачет на ±0.5°C — простая скользящая средняя сглаживает:
float avg = NAN;
float t = dht.readTemperature();
if (!isnan(t)) {
avg = isnan(avg) ? t : avg * 0.8 + t * 0.2; // EMA
}
DHT11 против DHT22: выбор
| | DHT11 | DHT22 | |---|---|---| | Точность T | ±2°C | ±0.5°C | | Точность H | ±5% | ±2% | | Диапазон T | 0–50°C | −40…+80°C | | Опрос | раз в 1 с | раз в 2 с | | Цена | дешевле | дороже в 2–3 раза |
Для погодной станции и улицы — только DHT22. DHT11 — для игр и «проверить как работает».
Усреднение нескольких датчиков
Два-три DHT по комнате дают более стабильное показание, чем один — ставьте их на разные пины и усредняйте.
Альтернативы с точностью выше
DHT — начальный уровень. Когда нужна точность: BME280 (темп+влаж+давление, I2C), SHT31 (точнее по влажности), DS18B20 (только температура, но −55..+125 и водонепроницаемый корпус). Для улицы DHT вообще не подходит — берите герметичный DS18B20.
Применение в проектах
- Метеостанция с логированием на SD.
- Термостат (DHT + реле на обогреватель).
- Вентиляция по влажности в ванной/теплице.
- IoT-узел: показания → ESP32 → MQTT → Home Assistant.
Полный пример с выводом на LCD
#include <DHT.h>
#include <LiquidCrystal_I2C.h>
DHT dht(2, DHT22);
LiquidCrystal_I2C lcd(0x27, 16, 2);
void setup() {
dht.begin();
lcd.init();
lcd.backlight();
}
void loop() {
float t = dht.readTemperature();
float h = dht.readHumidity();
lcd.setCursor(0, 0);
lcd.print("T=");
lcd.print(t, 1);
lcd.print((char)223);
lcd.print("C");
lcd.setCursor(0, 1);
lcd.print("H=");
lcd.print(h, 0);
lcd.print("% ");
delay(2000);
}
Альтернативы с точностью выше
- BME280 — темп+влаж+давление, I2C, ±0.5°C.
- SHT31 — точнее по влажности, I2C.
- DS18B20 — только температура, −55..+125, водонепроницаемый.
- AHT20 — дешёвая замена DHT11 с лучшей точностью.