Термометр-гигрометр на Arduino: DHT22 + дисплей
Термометр-гигрометр — самый полезный прибор, который можно спаять за вечер: в квартире он отвечает на вечный спор «открывать ли окно», в погребе следит за сыростью, в теплице управляет проветриванием. Я делаю их десятками, и формула не меняется: датчик DHT, дисплей, при желании — реле с вентилятором. Всего три детали и час времени.
На этой странице — выбор между DHT11 и DHT22, схема с LCD 1602 и реле вытяжки, и рабочий скетч: он показывает температуру и влажность, включает вентилятор по порогу с гистерезисом. Код исполняется в симуляторе прямо со страницы, а после сборки работает на железе без правок. Для тех, кто хочет углубиться, полный курс датчика лежит в разделе DHT — от первого чтения до порогов в EEPROM.
DHT11 против DHT22: таблица, которая закрывает спор
| Параметр | DHT11 | DHT22 (AM2302) |
|---|---|---|
| Цена | 90-150 ₽ | 300-450 ₽ |
| Диапазон температур | 0…50 °C, шаг 1 °C | -40…+80 °C, шаг 0,1 °C |
| Точность | ±2 °C и ±5 % по влажности | ±0,5 °C и ±2-3 % по влажности |
| Скорость опроса | раз в секунду | раз в 2 секунды |
| Питание и проводка | 3,3-5 В, подтяжка 10 кОм | 3,3-5 В, подтяжка 10 кОм |
| Кому | Комната, учебный стенд, подарок | Улица, теплица, погреб, инкубатор |
Практическое правило: там, где вы решаете «надеть свитер или нет», хватает DHT11 — погрешность 2 °C глаз не различит. Там, где показания превращаются в действия (реле вентилятора, форточка, отчёт по теплице), разница уже критична: DHT11 скажет «25 °C», когда DHT22 честно покажет 27, и вентилятор либо будет молчать, либо наматывает часы впустую. Разницу двух сенсоров на живом графике я показывал в уроке про отличия DHT11 и DHT22.
Три сценария: комната, улица, теплица
- Комната — прибор на полке: DHT22 + LCD, питание от USB-зарядки; вопрос «норм ли дома» закрывается навсегда
- Улица — датчик под козырьком с южной стороны, кабель 2-5 м, корпус из киндера или распаячной коробки; минус и роса требуют DHT22, DHT11 на морозе просто лжёт
- Теплица — уже система: порог влажности включает вытяжку через реле, при жаре приоткрывается форточка на серво; обе автоматики разобраны в уроках про вытяжку и про форточку
Мой совет по размещению: датчик не любит прямое солнце и сквозняк от самой вытяжки — повесьте его в полутора метрах от вентилятора, иначе система будет включать сама себя от собственного воздуха. Распиновку с расцветкой проводов и нюансами монтажа я свёл в обзоре подключения DHT22.
Схема: DHT22, LCD 1602 I2C и реле вентилятора
- DHT22: ножка 1 — 5 В, ножка 2 — DATA на D2, ножка 4 — GND; резистор 10 кОм между 1 и 2 (часто уже на модуле)
- LCD 1602 с модулем I2C (адрес обычно 0x27): SDA — A4, SCL — A5, питание 5 В
- Реле-модуль 1 канал (80-150 ₽): IN — на D8, VCC — 5 В, GND — общий; вентилятор коммутируем контактами COM/NO
- Вентилятор 12 В питается от своего блока, реле лишь замыкает цепь; земли блока вентилятора и Arduino соединять не обязательно
Скетч: показания на экране и реле с гистерезисом
Скетч ниже — цельный прибор: температура и влажность на LCD, дубль в Serial, включение вентилятора по жаре 27 °C и выключение ниже 25 °C. Запустите его в симуляторе и покрутите ползунок температуры датчика на стенде — реле щёлкает по порогам, а на LCD всё живое. На реальном железе код работает без изменений:
// Термогигрометр с реле вытяжки: DHT22 на D2, LCD по I2C, реле на D8.#include <DHT.h>#include <LiquidCrystal_I2C.h> DHT dht(2, DHT22); // DATA на D2LiquidCrystal_I2C lcd(0x27, 16, 2); const int RELE = 8; // IN модуля релеconst float TEMP_ON = 27.0; // включаем вентилятор от 27 °Cconst float TEMP_OFF = 25.0; // выключаем ниже 25 °C (гистерезис 2 °C)bool fanOn = false; unsigned long lastRead = 0; void setup() { Serial.begin(9600); dht.begin(); lcd.init(); lcd.backlight(); pinMode(RELE, OUTPUT); digitalWrite(RELE, LOW); lcd.setCursor(0, 0); lcd.print("Termo-gigrometr");} void loop() { if (millis() - lastRead < 2000) return; // DHT22: раз в 2 секунды lastRead = millis(); float t = dht.readTemperature(); float h = dht.readHumidity(); if (isnan(t) || isnan(h)) { // сорванное чтение — не рисуем мусор Serial.println("DHT не отвечает: DATA, питание или подтяжка 10 кОм"); return; } lcd.setCursor(0, 0); lcd.print("T="); lcd.print(t, 1); lcd.write(223); // глиф градуса HD44780 lcd.print("C "); lcd.setCursor(0, 1); lcd.print("Vlazhnost "); lcd.print(h, 0); lcd.print("%"); Serial.print("t="); Serial.print(t, 1); Serial.print(" h="); Serial.println(h, 0); if (!fanOn && t >= TEMP_ON) { fanOn = true; digitalWrite(RELE, HIGH); Serial.println("вентилятор: ВКЛ"); } if (fanOn && t <= TEMP_OFF) { fanOn = false; digitalWrite(RELE, LOW); Serial.println("вентилятор: ВЫКЛ"); }}Строку «Termo-gigrometr» я пишу латиницей не из вредности: знакогенератор HD44780 не содержит кириллицы, и русские буквы без библиотечных глифов превращаются в мусор. Тему экрана я добиваю в уроке про термогигрометр на LCD, а там же — про хвост из пробелов после чисел, без которого старые цифры торчат на экране при смене знака.
Почему реле включают по гистерезису, а не по порогу
Вариант «вентилятор включается при 26 °C и всё» глючит на границе: показания плавают на десятые градуса, реле начинает стрекотать — включилось, выключилось, и так сотни раз за вечер. Контактная пара при таком режиме живёт недели. Гистерезис разделяет пороги: включение при 27, выключение при 25 — между ними система спокойна, как бы температура ни колебалась. Чем шире окно, тем реже щёлкает реле; для бытовой вытяжки окно в 2 °C — мой рабочий стандарт.
Той же логикой настраиваются пороги влажности для погреба и уставки инкубатора, а чтобы их можно было менять без перепрошивки, значения сохраняют в EEPROM — готовый приём разобран в уроке про пороги в EEPROM.
Грабли, на которые я налетал
- NaN в мониторе — 90% случаев: перепутаны DATA и VCC, обрыв провода или датчик дальше 5-10 м без нормальной подтяжки
- Показания врут на 3-5 °C — датчик стоит вплотную к самому вентилятору или над блоком питания: сдвиньте его от тепла
- DHT11 на улице зимой молчит — его диапазон начинается с 0 °C; минус читает только DHT22
- Реле щёлкает, а вентилятор не крутит — перепутаны COM и NO на клеммах, либо вентилятор питается от того же 5 В Arduino и просаживает плату
- Экран показывает иероглифы — адрес I2C не 0x27, а 0x3F: запустите сканер шины и подставьте честный адрес