У меня в кладовке-сушилке год висел датчик с одним светодиодом и одним порогом: выше 24 °C — горит, ниже — нет. Логика казалась железной, пока я не посмотрел на это летом: температура в комнате живёт вблизи порога, дышит туда-сюда, и диод строчил как стробоскоп. Домашние решили, что сигнализация сломалась. Я три вечера изучал скетч и схему, прежде чем признал: виноват не датчик и не провода, а сама идея одного порога.
Комнатная температура не стоит на месте. Она плавает в десятых долях градуса от сквозняка и чайника, а DHT11 к этому добавляет свои ±2 °C погрешности и отдаёт показания с шагом в целый градус — между 23 и 24 у него нет ничего. Для такого сенсора граница 24,0 — лотерея: показания прыгают через неё без всякой реальной причины. Индикация «норма или нет» одним диодом с одним порогом либо мигает, либо врёт, третьего не дано.
Выход, к которому я пришёл, — зоны вместо порога. В этом уроке нарисуем три зоны для жилой комнаты, подберём числа-границы, которые не дрожат, зажжём три светодиода, а заодно придумаем, как выразить те же три состояния одним диодом — ритмом вспышек. Схема и привычки из урока про светодиод на макетке пригодятся напрямую.
У зон есть и человеческая сторона. Три состояния читаются как светофор: зелёный — не трогай ничего, красный — иди разбирайся, синий — закрой форточку. Один порог такого словаря не даёт: он умеет говорить только «да или нет», а у любой комнаты словарь побогаче. Чем меньше у прибора состояний, тем чаще он врёт не по-настоящему, а по формулировке — и именно это я увидел в кладовке в тот вечер.
Зоны вместо порога: откуда берутся числа
Норму не надо выдумывать. Санитарные правила для жилых комнат в отопительный сезон дают 18–24 °C и влажность 30–45 %, летом верхняя планка влажности доходит до 60 %. Я от себя сдвинул верхнюю границу температуры на два градуса вверх: в комнате с работающим компьютером и двумя людьми 24 °C уже ощущаются как духота, проверено. Моя рабочая зона — 20–26 °C, и она пережила три зимы без правок.
Ширина зоны — не вопрос вкуса, а арифметика. Зона должна быть хотя бы вдвое шире погрешности сенсора, иначе индикация будет щёлкать сама. У DHT11 погрешность ±2 °C, значит зона уже 4 °C — плохая идея: любые 20–26 (шесть градусов) для него на грани, а вот для DHT22 с его ±0,5 °C — с трёхкратным запасом. Отсюда правило: сначала смотрим в паспорт датчика, потом рисуем границы.
С влажностью та же история. Я держу пороги 30 и 60 %: ниже 30 % зимой в квартире с батареями воздух сушит кожу и рассаду, выше 60 % — приглашение плесени на стену. Если ваш прибор едет в теплицу, инкубатор или погреб, числа будут другими — но метод не изменится: зона шире погрешности, границы из задачи, а не с потолка.
Оговорка по железу. У DHT11 паспорт влажности — 20–80 % с точностью ±5 %, и на краях диапазона он врёт заметно сильнее, чем в середине. Моя нижняя граница 30 % лежит внутри, но уже близко к неуютной зоне: в сушилке я видел от DHT11 и 18 %, когда по всему остальному миру воздух был сухой, но не настолько. Для задач, где влажность — главный герой, это аргумент за DHT22 с его ±2–5 % и полным диапазоном от нуля до ста.
| Зона | Температура | Влажность | Индикация | Что делаю я |
|---|---|---|---|---|
| Холодно | ниже 20 °C | любая | синий горит | закрыть окно, включить обогрев |
| Норма | 20–26 °C | 30–60 % | зелёный горит | ничего — это цель |
| Жарко | выше 26 °C | любая | красный горит | проветрить |
Три светодиода и три резистора
Схема честная и скучная, как и должно быть: каждый диод — анодом через резистор 220 Ом к своему пину, катодом на общую землю. Пины 12, 11 и 10: красный — жара, зелёный — норма, синий — холод. Резистор 220 Ом при питании 5 В и падении на диоде около 2 В даёт ток примерно (5 − 2) / 220 ≈ 14 мА — для индикации достаточно, порт Arduino не перенапрягаем. Мой потолок для ярких прозрачных диодов — 330 Ом: они слепят и на 14 мА.
Пины выбраны не навсегда, но не случайно: 12, 11 и 10 стоят на колодке рядом, три провода идут по макетке одной дорожкой и не переплетаются с линией данных датчика. Резисторов три — по одному на диод, общих здесь не бывает. Пин 13 я нарочно оставил свободным — на Uno к нему подключён бортовой светодиод L, который мигает при каждой загрузке и путает картину, если вести индикацию через него. Если пинов мало, диоды уезжают куда угодно — в скетче это три строки define, ничего больше.
Скетч читает пару t и h, считает зону двумя сравнениями и зажигает ровно один диод из трёх. Три горящих одновременно не несут информации: прибор должен отвечать на вопрос «что делать», а не рисовать всё, что измерил. Пары t=, h=, zone= в мониторе — не украшение: с такой печатью строки без правок понимает и Serial Plotter, к которому мы придём в уроке про график показаний.
#include "DHT.h" #define DHTPIN 2#define DHTTYPE DHT11 #define LED_HOT 12 // красный: жарко#define LED_OK 11 // зелёный: норма#define LED_COLD 10 // синий: холодно DHT dht(DHTPIN, DHTTYPE); void setup() { Serial.begin(9600); pinMode(LED_HOT, OUTPUT); pinMode(LED_OK, OUTPUT); pinMode(LED_COLD, OUTPUT); dht.begin();} void loop() { float t = dht.readTemperature(); float h = dht.readHumidity(); int zone = 1; // по умолчанию — норма if (t < 20.0) zone = 0; // холодно if (t > 26.0) zone = 2; // жарко digitalWrite(LED_COLD, zone == 0 ? HIGH : LOW); digitalWrite(LED_OK, zone == 1 ? HIGH : LOW); digitalWrite(LED_HOT, zone == 2 ? HIGH : LOW); Serial.print("t="); Serial.print(t); Serial.print(" h="); Serial.print(h); Serial.print(" zone="); Serial.println(zone); delay(2000);}Одна лампа, три ритма
В макетке симулятора под ногами один светодиод, и это не помеха: три состояния кодируются ритмом вспышек, как на промышленных панелях. Ровно горит — норма. Стробит с периодом около четверти секунды — жара, дела плохо. Редко вспыхивает раз в секунду с лишним — холодно. Такой язык читается и из соседней комнаты, а ночью постоянная лампа не слепит — редкие вспышки видны и в темноте.
Ритм ведёт отдельная функция showZone: она две секунды мигает по своей таблице и за это время к датчику не лезет — опрос остаётся честным, раз в две секунды. Разделение «чтение, решение, показ» — каркас любого прибора: дальше меняется только показ, чтение и решение переезжают из скетча в скетч без правок. А если захочется убрать delay совсем — это делается через millis, мы это разбирали в уроке про millis вместо delay.
Язык ритмов стоит документировать. Я клею на корпус бумажку с расшифровкой — ровно горит: норма; стробит: жарко; мигает редко: холодно, — потому что через полгода никто в доме, включая меня, уже не помнит, что значил этот строб. И держу словарь коротким: больше трёх ритмов на один индикатор — и расшифровка понадобится самому прибору.
- Сузьте границы до T_COLD 23.0 и T_HOT 24.0 и выставьте температуру около 23,5. Зона в один градус уже погрешности DHT11 — вы увидите живой дребезг зон из note выше, теперь своими глазами.
- Поменяйте ритмы местами: пусть холод стробит, а жара вспыхивает редко. Правится одна функция showZone — чтение и решение не трогаются вообще. Если после правки что-то сломалось, вы знаете, где искать.
- Добавьте влажность в индикацию: при нормальной температуре и h ниже 30 % пусть диод делает двойную вспышку — два коротких зажигания с delay(100) между ними. Двойная вспышка и редкая одиночная различаются с первого взгляда.
- 1. Почему диод с одним порогом мигает на границе, хотя в комнате ничего не меняется?
- 2. Какой минимальной ширины стоит делать зону для DHT11?
- 3. Какой ток пойдёт через светодиод с резистором 220 Ом при 5 В и падении на диоде 2 В?
- 4. Зачем функция showZone держит ритм две секунды, а не читает датчик каждый проход?
- 5. Что печатать в Serial, чтобы строку понимали и человек, и плоттер?
- Зона вместо порога: для жилой комнаты я работаю с 20–26 °C и влажностью 30–60 %; ширина зоны — минимум двойная погрешность сенсора.
- Три светодиода на пинах 12, 11, 10, каждый через 220 Ом; горит ровно один — тот, что подсказывает действие.
- Дребезг на границе лечится гистерезисом: включение и выключение на разных величинах.
- Один индикатор кодирует три состояния ритмом: ровно — норма, строб — жара, редкие вспышки — холод.
- Печать парами t=24.00 h=45.00 zone=1 годится и человеку, и Serial Plotter без правок.
Индикация — первый шаг от датчика к прибору. Следующий — не показывать, а действовать: в термостате с гистерезисом к этим же зонам добавляется реле, и комната сама держит тепло. Если ещё выбираете сенсор под свою задачу, сравнение DHT11 и DHT22 разложит разницу по полочкам, а базы про мигание светодиодом и светодиод на макетке пригодятся, когда захотите четвёртый диод — например, жёлтый, между нормой и жарой.
И последнее — про привычку. Пороги, которые я назвал, не истина, а стартовая разметка: измерьте свою комнату неделю через монитор или плоттер и подвиньте границы под неё. У моей кухни зона сместилась на градус вниз — духовка греет, и 26 там наступает раньше. Прибор, который врёт про комфорт в вашем доме по чужой таблице, хуже прибора без индикации вообще.
Частые вопросы по теме урока
- Почему диод с одним порогом мигает на границе, хотя в комнате ничего не меняется?
- Показания плавают в пределах погрешности и шага измерения. Узкий порог превращает это плавание в мигание — лечится широкой зоной или гистерезисом. Проверьте сами: зона в один градус щёлкает даже в симуляторе с его шумом в десятые доли. Температура дышет вокруг порога, а погрешность сенсора шире этого дыхания
- Какой минимальной ширины стоит делать зону для DHT11?
- Зона уже двойной погрешности будет щёлкать от шума. Для DHT11 я держу шесть градусов 20–26, для DHT22 хватает и трёх. Хотя бы вдвое шире его погрешности ±2 °C — от четырёх градусов
- Какой ток пойдёт через светодиод с резистором 220 Ом при 5 В и падении на диоде 2 В?
- Закон Ома: (5 − 2) / 220 ≈ 0,014 А. Именно поэтому 220 Ом — стандартный выбор для индикации от пина Arduino: ток в полтора-два раза меньше предельных 40 мА на пин, яркости хватает с запасом. Около 14 мА
- Зачем функция showZone держит ритм две секунды, а не читает датчик каждый проход?
- DHT11 пересчитывает показания не чаще раза в секунду. Частый опрос даёт nan и устаревшие числа, а ритм между чтениями — это задача showZone. Так скетч живёт часами без единого nan. Чтобы опрос DHT оставался не чаще разрешённого, а индикация жила своей жизнью
- Что печатать в Serial, чтобы строку понимали и человек, и плоттер?
- Пары t=24.00 читает человек, а плоттер из них собирает именованные ряды. Одна печать обслуживает обоих, и для человека это выглядит как обычная строка лога. Пары имя=значение: t=24.00 h=45.00 zone=1