Умный дом на Arduino: честный разбор трёх уровней — от датчика движения до Home Assistant

Умный дом на Arduino: честный разбор трёх уровней — от датчика движения до Home Assistant

Миф о «сложности» умного дома

Первое, что слышит новичок, заинтересовавшийся умным домом: «Это дорого, сложно и требует специалиста». Второе, что он слышит, уже от других людей: «Купи готовую экосистему, Arduino — это игрушка». Оба утверждения одинаково далеки от правды, и оба мешают приступить к делу.

Правда в том, что умный дом — это не единая технология и не одна коробка из магазина. Это набор задач, каждая из которых решается на своём уровне сложности. И Arduino здесь занимает совершенно конкретную нишу: локальная автоматизация на стороне устройства, без облаков, подписок и чужого сервера. Именно эта ниша интересна радиолюбителю, потому что она даёт полный контроль над железом и логикой.

Мы разберём три честных уровня. Первый — автономные сценарии на одной плате, без интернета вообще. Второй — локальная сеть устройств с обменом данными. Третий — интеграция с системой управления умным домом, где Arduino становится одним из многих устройств, а не единственным мозгом.

Но сначала — граница, которую надо понимать до того, как паяльник нагреется.

Граница, которую надо провести сразу

Arduino — это микроконтроллер, а не компьютер. У него нет операционной системы, нет файловой системы в привычном смысле, и он не умеет сам по себе «понимать» команды с телефона. Всё, что он делает, описано в скетче: последовательность операций, которая выполняется в бесконечном цикле.

Из этого следует несколько практических ограничений, которые определяют, что можно построить на Arduino, а что нет.

Arduino не подходит для роли центрального сервера умного дома. Он не может одновременно обслуживать веб-интерфейс, хранить историю показаний, управлять десятками устройств и обеспечивать удалённый доступ. Для этого нужен полноценный компьютер или одноплатный компьютер вроде Raspberry Pi. Arduino отлично справляется с ролью оконечного устройства: читать датчик, щёлкать реле, отправлять данные наверх.

Arduino не умеет работать с видео и звуком в реальном времени. Камера и микрофон на Arduino — это отдельная история с ESP32-CAM и потоковой передачей, и это не тема данной статьи.

Arduino не заменяет промышленные контроллеры и системы безопасности. Если речь идёт о газовом котле или о системе, от которой зависит жизнь, — здесь нужны сертифицированные решения, а не самоделка на макетной плате. Мы будем говорить о бытовых сценариях: свет, розетки, климат, мониторинг.

С этим пониманием можно двигаться дальше, и первый уровень — самый доступный и самый надёжный.

Уровень первый: автономные сценарии на одной плате

Этот уровень не требует ни Wi-Fi, ни интернета, ни телефона. Плата Arduino с датчиками и реле выполняет заданную логику автономно: обнаружила движение в темноте — включила свет, температура поднялась выше порога — включила вентилятор, открылась дверца шкафа — зажгла подсветку. Всё.

Именно этот уровень стоит освоить первым, потому что он даёт немедленный результат и учит главному: связке «датчик — решение — исполнительное устройство». А ещё он полностью рабочий: многие реальные задачи умного дома не требуют интернета вообще.

Сценарий первый: свет по движению и освещённости

Классическая связка, которую используют в прихожих, коридорах, кладовках и санузлах: PIR-датчик движения плюс фоторезистор. Логика простая: свет включается только тогда, когда в помещении темно и обнаружено движение. Если светло — даже при движении свет не включается, потому что естественного освещения достаточно.

Такая логика экономит электроэнергию и продлевает ресурс лампы. В проектах, где студенты собирали подобную систему, именно комбинация PIR и фоторезистора позволяла включать свет только при реальной необходимости, избегая лишнего расхода[reference:0].

Вот карта подключения и логика в виде текстовой схемы.

Компоненты:
  Arduino Uno или Nano
  PIR-датчик движения (например, HC-SR501) -> цифровой пин 2
  Фоторезистор с резистором 10 кОм (делитель напряжения) -> аналоговый пин A0
  Модуль реле (1 канал) -> цифровой пин 7
  Светодиод индикации -> цифровой пин 13 (опционально)

Логика:
  Если PIR обнаружил движение И освещённость ниже порога:
      включить реле
      запомнить время последнего движения
  Если движения нет дольше заданного таймаута (например, 10 секунд):
      выключить реле

Скетч для такой логики несложен, но в нём есть важная деталь: таймаут. Свет не должен гаснуть мгновенно, как только человек остановился, — иначе получится раздражающее мигание. Таймаут в десять секунд после последнего движения решает эту проблему.

// Автономный сценарий: свет по движению и освещённости.
// Arduino Uno/Nano, PIR на пине 2, фоторезистор на A0, реле на пине 7.

const int PIR_PIN = 2;
const int LDR_PIN = A0;
const int RELAY_PIN = 7;

// Порог освещённости: значение с фоторезистора, ниже которого считаем,
// что в помещении темно. Подбирается экспериментально под конкретный делитель.
const int DARKNESS_THRESHOLD = 500;

// Таймаут выключения после последнего движения, миллисекунды.
const unsigned long MOTION_TIMEOUT = 10000;

unsigned long lastMotionTime = 0;
bool relayOn = false;

void setup() {
  pinMode(PIR_PIN, INPUT);
  pinMode(RELAY_PIN, OUTPUT);
  digitalWrite(RELAY_PIN, LOW);  // реле выключено при старте
  Serial.begin(9600);
}

void loop() {
  int lightLevel = analogRead(LDR_PIN);
  bool motionDetected = digitalRead(PIR_PIN) == HIGH;
  bool isDark = lightLevel < DARKNESS_THRESHOLD;

  if (motionDetected && isDark) {
    lastMotionTime = millis();
    if (!relayOn) {
      digitalWrite(RELAY_PIN, HIGH);
      relayOn = true;
      Serial.println("Свет включён: движение в темноте");
    }
  }

  if (relayOn && (millis() - lastMotionTime > MOTION_TIMEOUT)) {
    digitalWrite(RELAY_PIN, LOW);
    relayOn = false;
    Serial.println("Свет выключен: таймаут истёк");
  }

  delay(50);  // небольшой шаг, чтобы не крутить цикл слишком быстро
}

Обратите внимание на порог DARKNESS_THRESHOLD. Он не универсален: значение зависит от номинала резистора в делителе и от конкретного фоторезистора. Его подбирают экспериментально, глядя на показания в мониторе порта при разном освещении. Это не «магия», а обычная калибровка.

Сценарий второй: климат — температура и вентиляция

Второй классический сценарий: контроль температуры. DHT11 или DHT22 читает температуру и влажность, Arduino сравнивает показания с порогом и управляет вентилятором или обогревателем через реле. В проектах автоматизации теплиц и помещений именно такая связка используется: датчик температуры-влажности и вентилятор для регулировки микроклимата[reference:1].

Логика проста: температура выше порога — вентилятор включён, температура ниже порога с гистерезисом — вентилятор выключен. Гистерезис нужен, чтобы вентилятор не дёргался каждые несколько секунд при температуре, колеблющейся около порога. Например, включаем при 28 градусах, выключаем при 26.

Компоненты:
  Arduino Uno или Nano
  DHT11 или DHT22 (датчик температуры и влажности) -> цифровой пин 4
  Модуль реле (1 канал) -> цифровой пин 7
  Вентилятор 12 В с драйвером или 220 В через реле

Логика с гистерезисом:
  Если температура >= 28°C:
      включить вентилятор
  Если температура <= 26°C:
      выключить вентилятор

Разница между порогами включения и выключения — это и есть гистерезис. Он делает поведение системы стабильным и предсказуемым, а не хаотичным.

Сценарий третий: безопасность без интернета

Третий сценарий, который стоит освоить на первом уровне, — автономная сигнализация. Датчик дыма, датчик газа, геркон на двери или окне — Arduino читает состояние датчиков и при срабатывании включает сирену и мигает светодиодом. Без SMS, без уведомлений в телефоне, без облака. Просто громкий звук и свет. В ряде случаев этого достаточно: если вы дома, вы услышите сигнал, даже если телефон разряжен, а интернет пропал.

В проектах охранных систем на Arduino именно автономный режим с сиреной и светодиодной индикацией рассматривается как базовый уровень, к которому уже опционально добавляются GSM-модули для SMS[reference:2].

Уровень второй: локальная сеть и протокол MQTT

Первый уровень работает без сети, но у него есть очевидный недостаток: чтобы изменить порог или посмотреть текущие показания, нужно подойти к плате с кабелем. Второй уровень решает эту проблему, добавляя беспроводную связь.

Как Arduino попадает в сеть

Классический Arduino Uno не имеет Wi-Fi на борту. Есть несколько способов добавить связь:

Отдельный модуль ESP8266. ESP8266 — это недорогой чип с Wi-Fi, который можно подключить к Arduino Uno по последовательному порту. Arduino отправляет ему AT-команды, модуль их выполняет. Этот способ работает, но требует аккуратности: ESP8266 чувствителен к питанию, а последовательный порт нужно разделять между отладкой и обменом с модулем.

Плата на ESP8266 или ESP32 вместо Arduino. Более чистый путь: использовать ESP8266 или ESP32 как основную плату. Они программируются в среде Arduino IDE, имеют Wi-Fi на борту и достаточную производительность для сетевых задач. ESP32 предпочтительнее, потому что у него больше памяти, больше пинов и два ядра.

Arduino Uno R4 Wi-Fi. Относительно новая плата с Wi-Fi на борту и полной совместимостью с экосистемой Arduino. Если вы начинаете с нуля и хотите остаться в мире Arduino IDE без переходов на ESP, это разумный выбор.

Для второго уровня мы будем считать, что у вас плата с Wi-Fi — ESP32, ESP8266 или Uno R4 Wi-Fi. Принцип один и тот же: плата подключается к вашей домашней сети, и с ней можно общаться по сети.

Протокол MQTT: почему именно он

MQTT — это лёгкий протокол обмена сообщениями, созданный именно для устройств с ограниченными ресурсами и нестабильными каналами связи. Его модель проста: есть брокер, есть издатели и есть подписчики. Устройство публикует сообщение в определённый топик, брокер рассылает это сообщение всем, кто подписан на этот топик.

Arduino с датчиком температуры публикует в топик home/livingroom/temperature значение 24.5. Подписчик — приложение на телефоне или программа на компьютере — получает это значение и отображает. Если подписчик отправляет команду в топик home/livingroom/light/set значение ON, брокер передаёт её Arduino, который управляет реле света.

Такая архитектура называется «публикация-подписка» и выгодно отличается от прямых соединений: устройства не знают друг о друге, они знают только о брокере. Добавить новое устройство — значит просто заставить его публиковать и подписываться на нужные топики.

Для Arduino существует проверенная библиотека PubSubClient, которая реализует клиент MQTT для ESP8266 и ESP32. Она широко используется в проектах умного дома[reference:3].

Пример: датчик температуры публикует данные в MQTT

Рассмотрим минимальный, но рабочий пример. ESP32 с DHT22 читает температуру и публикует её в MQTT-брокер. Этот код можно использовать как основу для любого датчика.

// ESP32 + DHT22: публикация температуры в MQTT.
// Библиотеки: PubSubClient, DHT sensor library.

#include <WiFi.h>
#include <PubSubClient.h>
#include <DHT.h>

// --- Настройки сети и брокера ---
const char* WIFI_SSID = "ваш_ssid";
const char* WIFI_PASSWORD = "ваш_пароль";
const char* MQTT_BROKER = "192.168.1.100";  // адрес вашего брокера
const int   MQTT_PORT = 1883;
const char* MQTT_TOPIC = "home/livingroom/temperature";

// --- Датчик ---
#define DHT_PIN 4
#define DHT_TYPE DHT22
DHT dht(DHT_PIN, DHT_TYPE);

WiFiClient espClient;
PubSubClient mqttClient(espClient);

void setup() {
  Serial.begin(115200);
  dht.begin();

  // Подключение к Wi-Fi
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("\nWi-Fi подключён");

  // Настройка MQTT
  mqttClient.setServer(MQTT_BROKER, MQTT_PORT);
}

void reconnectMQTT() {
  while (!mqttClient.connected()) {
    Serial.print("Подключение к MQTT...");
    if (mqttClient.connect("esp32-sensor-livingroom")) {
      Serial.println("успешно");
    } else {
      Serial.print("ошибка, код: ");
      Serial.println(mqttClient.state());
      delay(2000);
    }
  }
}

void loop() {
  if (!mqttClient.connected()) {
    reconnectMQTT();
  }
  mqttClient.loop();

  // Чтение датчика и публикация раз в 10 секунд
  static unsigned long lastPublish = 0;
  if (millis() - lastPublish > 10000) {
    lastPublish = millis();

    float t = dht.readTemperature();
    float h = dht.readHumidity();

    if (!isnan(t) && !isnan(h)) {
      char payload[16];
      snprintf(payload, sizeof(payload), "%.1f", t);
      mqttClient.publish(MQTT_TOPIC, payload);
      Serial.printf("Опубликовано: %s = %s\n", MQTT_TOPIC, payload);
    } else {
      Serial.println("Ошибка чтения DHT");
    }
  }
}

Здесь важно несколько моментов. mqttClient.setServer задаёт адрес брокера — это может быть ваш компьютер с Mosquitto, Raspberry Pi с Home Assistant или публичный тестовый брокер вроде test.mosquitto.org[reference:4]. Подключение к Wi-Fi блокирующее: скетч ждёт подключения, прежде чем идти дальше. Для простого датчика это нормально, но для устройства, которое должно реагировать на кнопки мгновенно, такая блокировка недопустима — там нужен неблокирующий подход.

Публикация выполняется раз в десять секунд. Это разумный компромисс для температуры: чаще нет смысла, реже — данные становятся неактуальными. Для других датчиков интервал подбирается отдельно.

Локальный брокер: Mosquitto на Raspberry Pi или компьютере

MQTT-брокер — это программа, которая принимает сообщения от издателей и рассылает подписчикам. Самый распространённый брокер с открытым исходным кодом — Eclipse Mosquitto. Он устанавливается на Raspberry Pi, на старый ноутбук или даже на роутер с OpenWrt, если тот позволяет.

Локальный брокер — это ключевой элемент для умного дома без зависимости от облаков. Все устройства в квартире общаются через него, и если интернет пропал, устройства продолжают работать: брокер в локальной сети, а не в чужом дата-центре. Это принципиальное преимущество перед готовыми облачными решениями, которые при потере интернета превращают «умный дом» в обычный набор выключателей.

Настройка Mosquitto — отдельная тема, но в минимальном виде она сводится к установке пакета и запуску службы. Дальше нужно решить, будет ли брокер требовать аутентификацию и шифрование. Для домашней сети за NAT базовый уровень без шифрования приемлем, если вы доверяете всем устройствам в сети. Для доступа извне интернета — обязательны и шифрование, и аутентификация, и это уже требует внимания к безопасности.

Управление нагрузкой через MQTT

Помимо публикации данных, второе направление — управление. Arduino подписывается на топик команды и переключает реле, когда приходит сообщение. Это позволяет управлять светом, розетками и вентиляторами из любого места, где есть MQTT-клиент: с телефона, с компьютера, с другого Arduino.

Логика похожа на пример с датчиком, но с двумя отличиями: нужно подписаться на топик команд и обработать входящее сообщение. Библиотека PubSubClient позволяет задать функцию-обработчик, которая вызывается при получении сообщения в подписанный топик. В этой функции вы читаете полезную нагрузку и решаете, что делать с реле.

Уровень третий: интеграция с Home Assistant

Два первых уровня дают работающую систему, но у неё нет удобного интерфейса. Можно смотреть показания через MQTT-клиент на телефоне, но это не «умный дом» в том смысле, к которому привык пользователь: нет единого экрана, нет сценариев, нет истории.

Home Assistant — это открытая платформа управления умным домом, которая работает на локальном сервере: Raspberry Pi, мини-компьютере, старом ноутбуке. Она объединяет устройства разных производителей и протоколов в одном интерфейсе, позволяет строить автоматизации и отображать данные на дашборде.

Arduino в этой схеме — не замена Home Assistant, а источник данных и исполнительное устройство. Home Assistant получает показания и отправляет команды, а Arduino выполняет конкретную работу на месте.

Как Arduino попадает в Home Assistant

Самый естественный путь для Arduino-устройства — через MQTT. Home Assistant имеет встроенную интеграцию с MQTT: вы описываете устройство через конфигурацию, и оно появляется в интерфейсе как любой другой датчик или переключатель.

Концепция MQTT Discovery позволяет устройству автоматически сообщать Home Assistant о своих возможностях. Если Arduino публикует сообщение в специальный топик конфигурации, Home Assistant создаёт сущность автоматически, без ручного редактирования файлов конфигурации. Существует библиотека HomeAssistantMQTT для Arduino, которая управляет структурой MQTT для публикации сенсоров, бинарных сенсоров, кнопок, переключателей и чисел в Home Assistant[reference:5].

Для ESP32 и ESP8266, запрограммированных через ESPHome, интеграция с Home Assistant ещё проще: ESPHome генерирует прошивку на основе YAML-конфигурации и автоматически создаёт все сущности. Но это уже не совсем «Arduino-скетч» в чистом виде, а отдельный фреймворк со своей логикой. Для тех, кто хочет остаться на классических скетчах, путь через MQTT Discovery — самый прямой.

Что даёт интеграция

Появление Arduino-устройства в Home Assistant меняет масштаб. Датчик температуры, который раньше был изолированной железкой, становится частью системы: его показания можно использовать в автоматизациях, сравнивать с другими датчиками, строить графики, получать уведомления на телефон.

Реле, управляемое через MQTT, становится переключателем в интерфейсе Home Assistant. Его можно включить голосом через интеграцию с голосовым ассистентом, по расписанию, по геолокации или по сценарию, который объединяет несколько устройств. Самодельное устройство на Arduino перестаёт быть «поделкой» и начинает работать наравне с заводскими.

Но здесь важно не потерять понимание границ. Home Assistant — это сервер, и он требует питания, обновлений и обслуживания. Если он падает, автоматизации, построенные только на нём, перестают работать. Поэтому первый уровень — автономные сценарии на самой плате — стоит сохранять даже при наличии Home Assistant. Локальная логика на Arduino продолжает работать, даже если сервер недоступен, и это делает систему устойчивее.

Практический проект, связывающий все три уровня

Соберём всё вместе на примере одной комнаты. Пусть это будет спальня.

На первом уровне — автономная подсветка шкафа: геркон на дверце и RGB-светодиод. Дверь открылась — светодиод зажёгся мягким белым светом, дверь закрылась — погас. Эта логика работает всегда, даже без сети и сервера. Подобные системы с магнитным датчиком двери и RGB-подсветкой описаны в проектах автоматизации спальни[reference:6].

На втором уровне — ESP32 с DHT22 публикует температуру и влажность в MQTT, а также подписывается на топик управления реле, которое включает увлажнитель. Логика публикации и подписки живёт на плате, но данные уходят в локальный брокер.

На третьем уровне — Home Assistant получает эти данные через MQTT Discovery, отображает температуру на дашборде и позволяет управлять увлажнителем через интерфейс. Дополнительно можно настроить автоматизацию: если влажность ниже 40% и время ночное, включать увлажнитель на минимальной мощности.

Получается система, где каждый уровень решает свою задачу и не зависит от других полностью. Если Home Assistant недоступен, подсветка шкафа и публикация данных продолжают работать. Если MQTT-брокер недоступен, подсветка шкафа всё ещё работает. Автономность на нижнем уровне — это не роскошь, а принцип проектирования, который отличает надёжную систему от хрупкой.

Безопасность: честный разговор про 220 В

Нельзя написать статью про умный дом на Arduino и не сказать про безопасность. Управление реле, которое коммутирует 220 вольт, — это не то же самое, что мигание светодиодом на макетной плате.

Макетная плата и 220 В несовместимы. Макетные платы рассчитаны на слаботочные цепи. Коммутировать через них сетевые нагрузки нельзя: контакты не рассчитаны на ток, изоляция не рассчитана на напряжение, случайное касание может быть смертельным. Для работы с 220 В нужен модуль реле с оптоизоляцией, закреплённый в корпусе, с соблюдением зазоров и изоляции. Модуль реле подключается к Arduino низковольтной стороной, а силовая сторона изолирована.

Готовые модули реле — не панацея. Многие дешёвые модули реле имеют недостаточную изоляцию между управляющей и силовой частями, а контакты рассчитаны на ток, который заявлен с запасом только в идеальных условиях. Для управления лампами и вентиляторами обычно достаточно, но для мощных нагрузок — нагревателей, кондиционеров, бойлеров — нужны реле с запасом по току и, желательно, с принудительным охлаждением.

Solid-state реле вместо электромеханических. Для частого переключения светодиодных ламп и других нагрузок, которые не любят частые коммутации, стоит рассмотреть твердотельные реле. Они дороже, но не имеют движущихся частей, не щёлкают и служат дольше.

Автономность как элемент безопасности. Если система управляет светом в подъезде или вентиляцией, она не должна зависеть от Wi-Fi и сервера для выполнения базовых функций. Локальная логика на Arduino — это не «урезанная» версия, а более надёжный вариант. Сеть — для удобства мониторинга и управления, а не для критичных сценариев.

Чек-лист перед сборкой

  • Определили, на каком уровне будет работать система: автономно, в локальной сети или с интеграцией в Home Assistant. Не усложняйте сверх необходимого.
  • Для автономного уровня проверили, что логика на плате не зависит от сети и сервера.
  • Для сетевого уровня выбрали плату: ESP32, ESP8266 или Uno R4 Wi-Fi. Убедились, что питания хватает и Wi-Fi ловит в месте установки.
  • Для MQTT-брокера решили, где он будет жить: на Raspberry Pi, на компьютере или на роутере. Проверили, что брокер запускается автоматически после перезагрузки.
  • Для 220 В выбрали модуль реле с оптоизоляцией, закрепили его в корпусе, проверили зазоры и изоляцию. Не коммутировали сетевое напряжение через макетную плату.
  • Для датчиков температуры учли, что DHT11 менее точен и более медленный, чем DHT22. Для точных задач выбрали DHT22 или другой датчик.
  • Для питания учли, что ESP32 и ESP8266 чувствительны к просадкам. Если реле щёлкает и плата перезагружается, добавьте конденсатор по питанию или используйте отдельный источник для реле.
  • Для отладки оставили доступ к монитору порта. Это проще, чем гадать, почему устройство не выходит на связь.
  • Для обновления прошивки продумали, как будете прошивать плату, если она уже установлена в стене или в корпусе. OTA-обновления на ESP32 и ESP8266 решают эту проблему, но требуют поддержки в скетче.

Итог

Умный дом на Arduino — это не одна система, а три разных подхода, и каждый из них имеет смысл.

Первый уровень — автономные сценарии на одной плате — самый надёжный и самый быстрый в реализации. Он не требует интернета, не зависит от серверов и работает всегда. С него стоит начинать.

Второй уровень — локальная сеть и MQTT — добавляет удобство мониторинга и управления без потери автономности. Устройства общаются через локальный брокер, а не через чужое облако.

Третий уровень — интеграция с Home Assistant — превращает набор самодельных устройств в систему, где они работают вместе с заводскими датчиками и переключателями. Home Assistant не заменяет Arduino, а дополняет его.

Ошибка новичка — пытаться сразу строить третий уровень. Это приводит к сложной системе, которую трудно отлаживать, и к разочарованию. Начните с первого, убедитесь, что он работает стабильно, потом добавьте сеть, и только потом — сервер.

Эта статья продолжает цепочку блога: выбор платформы и чтение документации разбирались в Как читать даташит, сравнение микроконтроллеров — в ESP32-S3 и Новинках процессоров, практическая поделка с датчиком и дисплеем — в Термогигрометре с OLED на Arduino, вопросы питания, которые критичны и для умного дома, — в Питании ESP32 и ESP32-S3, а маркировка резисторов в обвязке датчиков — в Маркировке SMD-резисторов.

Официальные ориентиры по всем библиотекам и инструментам, упомянутым в статье, — в их собственной документации: PubSubClient, HomeAssistantMQTT, DHT sensor library, Eclipse Mosquitto и Home Assistant. Там же точные сигнатуры функций, форматы топиков и примеры конфигурации, которые я намеренно не воспроизводил по памяти.