Одна метеостанция в коридоре нашей квартиры полгода рисовала «в доме всё хорошо», пока зимой я не занёс в детскую второй термометр с балкона. Он показывал на три с половиной градуса меньше коридорного: тёплый воздух из кухни гулял по коридору, датчик стоял в самой тёплой точке квартиры и честно врал про весь дом. Средняя температура по одной точке — это средняя температура по больнице: комната дальняя, комната с окном на север и кухня живут в разных климатах, и один сенсор этого не видит.
Хорошая новость: вторая точка измерения стоит копейки. База подключения не меняется ни на букву — та же схема из урока про подключение DHT11, только повторённая дважды. В этом уроке посадим два датчика на одну плату, разнесём их опрос по времени, введём главный показатель многозонного дома — дельту между комнатами — и соберём скользящее среднее, которое превращает прыгающие единицы в спокойную линию.
Каждому датчику — свой пин и свой объект
Архитектура предельно прямая: у каждого DHT своя линия данных и свой объект библиотеки. DHT dhtA(2, DHT22) и DHT dhtB(3, DHT22) — два конструктора, два вызова begin, два набора вызовов чтения. Подтяжка 10 кОм ставится у каждой линии данных отдельно — это две независимые схемы, а не общая шина. В этом принципиальное отличие от I2C-устройств, которые висят парами на двух проводах и различаются адресом: там разводка на всех одна, механика разобрана в уроке про два провода I2C. У DHT дешевле наоборот — лишний провод, зато ноль возни с адресами.
Опрос важно разнести по времени. DHT22 отвечает не чаще раза в две секунды — правило из урока про интервал опроса действует на каждый объект отдельно. Наивный цикл «прочитал первого, прочитал второго, спим две секунды» работает, но оба чтения блокируют скетч на 4–5 миллисекунд каждое и приезжают пачкой в одну секунду. Мне спокойнее держать расписание: комната А опрашивается на чётном такте, комната Б — на нечётном, между ними ровно две секунды тишины. Линии дальше друг от друга во времени — меньше взаимных наводок, и монитор читается ровнее.
Провода по комнатам я тяну витой парой и ставлю внешнюю подтяжку у сенсора, а не у платы — правила те же, что для одиночного датчика, но длина линии в два-три метра превращает мелкие огрехи в систематические пропуски. Если второй датчик начинает отвечать через раз, а первый работает идеально — не ищите мистику в коде, смотрите длину и качество линии.
| Комната | Датчик | Пин | Зона нормы | Реакция |
|---|---|---|---|---|
| Детская | DHT22 | 2 | 20–24 °C | ниже 20 — обогреватель, выше — проветрить |
| Спальня | DHT22 | 3 | 18–22 °C | спать холоднее, чем кажется: следить ночью |
| Кухня | DHT11 | 4 | любая | контроль влажности после плиты |
Дельта между комнатами — главный показатель
Два датчика дают не просто два числа, а новую величину: разность. delta = t1 − t2 в нормальной квартире гуляет в пределах полуградуса-градуса. Дельта подскочила до трёх — что-то случилось: закрыта дверь в тёплую комнату, распахнуто окно, застряла штора на батарее. Для DHT22 с шагом 0,1 °C и погрешностью ±0,5 порог заметности дельты я держу на единице: всё, что меньше одного градуса разницы, — шум двух сенсоров, а не событие. Событие — это когда дельта перевалила за единицу и держится несколько опросов подряд.
Разность живёт и в другую сторону: детская холоднее коридора — классика сквозняка из начала урока. Чтобы дельта не дёргалась от каждого сквозняка, показания сглаживают скользящим средним: последние восемь чтений складываются и делятся на восемь. Одиночный выброс — кто-то дунул на датчик, открылась дверь — тонет в среднем, а устойчивый тренд проходит. Точка росы для каждой комнаты считается по тем же данным — формула Магнуса и готовый скетч лежат в уроке про точку росы, и для двух комнат она часто показательнее температуры: холодная комната с влажным воздухом опаснее тёплой с сухим.
#include "DHT.h" DHT dhtA(2, DHT22); // детскаяDHT dhtB(3, DHT22); // спальня float tA = 0;float tB = 0;int tick = 0; void setup() { Serial.begin(9600); dhtA.begin(); dhtB.begin();} void loop() { if (tick % 2 == 0) { tA = dhtA.readTemperature(); // чётный такт — детская } else { tB = dhtB.readTemperature(); // нечётный — спальня } tick++; float delta = tA - tB; Serial.print("tA="); Serial.print(tA, 1); Serial.print(" tB="); Serial.print(tB, 1); Serial.print(" delta="); Serial.println(delta, 1); delay(2000); // каждому датчику — свои две секунды тишины}Считаем по одной комнате: буфер и среднее
Скользящее среднее удобно отработать на одном датчике — вся механика буфера потом копируется в каждую комнату как есть. Идея: держим массив на восемь показаний, пишем по кругу, поверх считаем среднее и отклонение текущего значения от него. Отклонение — это датчик событий внутри одной комнаты: кто-то открыл форточку, занёс холодный пакет, датчик попал под поток батарей. Пока отклонение меньше единицы — комната живёт обычной жизнью; перевалило — светодиод начинает строчить, и вы смотрите, что случилось.
Глубина буфера — вопрос вкуса с границей. Восемь показаний при опросе раз в полторы секунды — окно в двенадцать секунд: сглаживает дрожь сенсора, но ещё реагирует на дверь. Буфер на тридцать ячеек спокоен как удав, но вы пропустите короткое событие целиком. Я остановился на восьми и ни разу не пожалел; для медленных процессов вроде погреба берите больше, для сигнализации — меньше.
Вместе со средним из того же буфера считаются минимум и максимум — размах окна. Он отвечает на вопрос, который среднее прячет: насколько комната вообще беспокойна. В статичной спальне восемь последних показаний лягут в десятую долю градуса, на кухне у плиты то же окно развернётся на полтора. Размах — это паспорт комнаты: сравнивая окна между собой, вы увидите, какая зона дома требует внимания, ещё до того, как упрётесь в пороги.
- Соберите код двух датчиков из блока выше на живой плате и подуйте сначала на один сенсор, потом на второй: дельта качнётся в разные стороны — почувствуйте инструмент.
- В симуляторе уменьшите порог срабатывания с единицы до 0,3: сторож начнёт реагировать на шум сенсора. Это наглядная граница «событие против дрожи» — верните единицу обратно.
- Добавьте в скетч печать mn= и mx= из буфера: размах окна за секунду покажет, насколько комната вообще спокойна, — статичный коридор и кухня у плиты будут выглядеть по-разному.
- 1. Как подключить второй DHT к той же плате?
- 2. Зачем разносить опрос двух DHT22 по времени?
- 3. Дельта между комнатами 0,4 °C. Что это значит?
- 4. Что даёт скользящее среднее по восьми показаниям?
- 5. Почему в симуляторе не видно двух датчиков из урока?
- Каждому DHT — свой цифровой пин, своя подтяжка 10 кОм и свой объект библиотеки; адресов у DHT нет.
- Опрос разносите по времени: чётный такт — комната А, нечётный — комната Б, по две секунды тишины каждому.
- Дельта между комнатами — главный показатель: меньше единицы шум, за единицу и держится — событие.
- Скользящее среднее на восьми показаниях гасит выбросы; глубину окна подбирайте под темп вашей комнаты.
- В симуляторе второй DHT не оживить — расчёты отрабатывайте на одном сенсоре, схему двух проверяйте на плате.
Куда двигаться дальше — подскажет ваш дом. Показать обе комнаты на живом графике проще простого: пары tA= и tB= в формате из урока про Serial Plotter рисуют два именованных ряда, и сквозняк станет виден как расхождение линий. Экранное решение — термогигрометр на LCD из соответствующего урока: страницы кнопкой, по комнате на страницу, а на третьей — дельта.
И маленькое напутствие напоследок: датчики в разных комнатах начинают жить своей жизнью, и один из них обязательно покажется «врущим». Прежде чем менять железо, повесьте оба рядом на десять минут: расхождение в полградуса — паспортная погрешность, в полтора — повод заменить экземпляр. Мой «врун» из детской за три года так и не потребовал замены — потребовал перенести его со сквозняка на нейтральную стену.
Частые вопросы по теме урока
- Как подключить второй DHT к той же плате?
- У DHT нет адресов: каждому датчику — свой цифровой пин и свой конструктор объекта. Подтяжка 10 кОм ставится у каждой линии своя. На свою линию данных и создать второй объект с этим пином
- Зачем разносить опрос двух DHT22 по времени?
- Каждый DHT22 требует двух секунд тишины между своими опросами. Расписание «чётный/нечётный такт» держит честные интервалы и даёт более ровный поток данных. Чтобы строки в мониторе шли ровнее и линии меньше мешали друг другу
- Дельта между комнатами 0,4 °C. Что это значит?
- Погрешность DHT22 ±0,5 °C, поэтому разность меньше градуса — шум. Событием я считаю дельту за единицу, продержавшуюся несколько опросов подряд. В пределах шума двух сенсоров, события нет
- Что даёт скользящее среднее по восьми показаниям?
- Одиночный выброс — дуновение, дверь — тонет в среднем из восьми точек. Медленный тренд, например остывание комнаты, проходит через окно без потерь. Гасит одиночные выбросы, но пропускает устойчивый тренд
- Почему в симуляторе не видно двух датчиков из урока?
- У эмулятора один климатический сенсор на всю плату. Сим строится вокруг расчётов по одному датчику, а два датчика проверяются на живой плате. Движок держит один объект DHT на всю плату, второй эмулировать нечем