Добавить в избранное

DHT11 и DHT22 с Arduino: температура и влажность за пять минут

Чтение ≈ 4 мин

Подключение датчиков температуры и влажности DHT11/DHT22 к Arduino: схема с подтяжкой, библиотека DHT, чтение значений, ограничение опроса, различия моделей и реальный проект термометра.

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 с лучшей точностью.
Поделиться
Понравился материал?

Комментарии

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