Умный дом на Arduino: макет дома, датчики, код и приложение
Собери умный дом на Arduino шаг за шагом: план макета, свет по PIR-датчику, сигнализация газа и пожара, дверь с RFID, лампа на реле, управление с телефона через ESP32 и полный код.
Проект умного дома на Arduino превращает свет, дверь, окно и сигнализацию в макете дома в систему, которая работает сама по показаниям датчиков, а при желании всем этим можно управлять ещё и с телефона. Это один из самых популярных школьных проектов, и не зря. Свет в прихожей, который включается при движении, сигнализация, которая срабатывает при утечке газа, вентилятор, который запускается, когда становится тепло, и дверь, открывающаяся по карте, вместе дают маленькую, но рабочую копию настоящей системы умного дома. С Arduino Uno или ESP32, десятком модулей и одними выходными ты тоже сможешь собрать такой дом.
В этом руководстве мы начнём с плана макета: какой модуль в какую комнату, на что уходит бюджет, как спланировать питание и распределить пины. Затем по очереди соберём и проверим каждый модуль и напишем полный скетч Arduino, который управляет ими всеми одновременно без delay(). В последних разделах ты узнаешь, как управлять домом с телефона через веб-сервер на ESP32 или Blynk, как исправить самые частые ошибки и как впечатлить жюри на школьной презентации.






Как работает система умного дома?
Любой умный дом работает по одному и тому же циклу из трёх частей. Датчики измеряют окружающую обстановку: есть ли движение, темно ли, насколько тепло, нет ли на кухне газа или пламени, какую карту поднесли к двери? Контроллер, то есть Arduino или ESP32, сравнивает эти данные с правилами: «если темно и есть движение, включи свет», «если температура выше 28 °C, запусти вентилятор». Исполнительные устройства выполняют решение: реле включает лампу и вентилятор, сервопривод поворачивает дверь и окно, зуммер подаёт сигнал, а дисплей показывает состояние. Управление с телефона просто добавляет в этот цикл ещё один вход; только на этот раз решение принимает не правило, а твоё касание экрана.
| Комната / зона | Модуль | Что делает |
|---|---|---|
| Входная дверь | RFID RC522 + сервопривод SG90 | Открывает дверь, когда приложена разрешённая карта, и закрывает её через 5 секунд |
| Прихожая / гостиная | PIR HC-SR501 + фоторезистор (LDR) + реле | Включает лампу при движении в темноте и выключает её, если движения нет 20 секунд |
| Кухня | Датчик газа MQ-2 + датчик пламени + зуммер | Подаёт прерывистый сигнал тревоги, когда обнаруживает газ или пламя |
| Окно | Сервопривод SG90 | Открывает окно для проветривания при обнаружении газа |
| Спальня | DHT11 + реле + вентилятор | Включает вентилятор при 28 °C и выключает при 26 °C |
| Техническое помещение | Arduino, I2C LCD, источник питания | Показывает температуру, влажность, показания датчика газа и сообщения о состоянии |
Планирование макета дома
Проектируй макет под электронику, а не пытайся втиснуть электронику потом. Основания размером примерно 50×40 см хватит на две-три комнаты и вход. Для стен легко режется канцелярским ножом пенокартон толщиной 5 мм или вспененный ПВХ (например, Forex); МДФ 3–4 мм прочнее, но для него нужны пила или лазерный резак. Хорошая отправная точка — масштаб 1:20: потолок высотой 2,6 м превращается в стену 13 см, а дверь шириной 90 см — в 4,5 см. Сделай крышу съёмной или вообще обойдись без неё: жюри захочет заглянуть в комнаты.
- Техническое помещение или двойной пол: размести Arduino, макетную плату, модуль реле и ввод питания в отсеке в задней части дома или под двойным полом высотой 3–4 см. Если накрыть его прозрачным акрилом, схема будет и защищена, и на виду.
- Кабельные каналы: просверли отверстие 6–8 мм под каждым датчиком и проведи провода под основанием в техническое помещение. Вместо того чтобы сращивать короткие провода, сразу бери провода датчиков достаточной длины.
- Дверь: закрепи дверь на стене маленькой петлёй или скотчем и соедини качалку SG90 с дверью проволокой, согнутой из скрепки. Приклей RC522 к внутренней стороне наружной стены; считыватель обычно читает карту и через плиту толщиной 5 мм.
- Кухня: в настоящих домах датчик природного газа (метана) ставят ближе к потолку, потому что метан легче воздуха, а датчик сжиженного газа (пропан-бутана) — ближе к полу, потому что он тяжелее; для макета подойдёт место под потолком. Направь датчик пламени на плиту.
- Остальные датчики: поставь PIR-датчик в угол, откуда путь от входа виден сбоку; фоторезистор — на наружную стену или окно, где на него не попадает свет лампы; а DHT11 — подальше от лампы и тёплого корпуса MQ-2.
Список деталей и стоимость
| Деталь | Кол-во | Назначение | Уровень цены |
|---|---|---|---|
| Arduino Uno R3 (подойдёт и клон) или ESP32 DevKit | 1 | Мозг дома | Средний |
| Макетная плата и набор проводов-перемычек (папа-папа, папа-мама) | 1 набор | Соединения | Низкий |
| PIR-датчик движения HC-SR501 | 1 | Свет в прихожей | Низкий |
| Фоторезистор (LDR) и резистор 10 kΩ | 1 + 1 | Определение темноты | Очень низкий |
| Модуль датчика газа MQ-2 | 1 | Сигнализация газа и дыма | Низкий |
| Модуль датчика пламени (LM393) | 1 | Пожарная сигнализация | Низкий |
| Модуль температуры и влажности DHT11 | 1 | Управление вентилятором | Низкий |
| RFID-модуль RC522 (с картой и брелоком) | 1 | Дверь по карте | Низкий |
| Сервопривод SG90 | 2 | Дверь и окно | Низкий |
| 2-канальный модуль реле на 5 V | 1 | Лампа и вентилятор | Низкий |
| Активный зуммер | 1 | Звук тревоги | Очень низкий |
| I2C LCD-дисплей 16x2 | 1 | Отображение состояния | Низкий – средний |
| Мини-вентилятор на 5 V и светодиодная лампа или светодиодная лента на 5 V | 1 + 1 | Нагрузки для реле | Низкий |
| Блок питания 5 V 2–3 A и разъём DC или клеммник | 1 | Питание сервоприводов, реле и датчиков | Средний |
| Пенокартон или вспененный ПВХ, канцелярский нож, термоклей | – | Корпус дома | Средний |
Цены часто меняются в зависимости от продавца и со временем, поэтому мы не приводим цифр; в таблице показано, какую долю бюджета занимает каждая деталь. Датчики и модули сами по себе дешёвые; большая часть бюджета уходит на плату, LCD, блок питания и материалы для макета. Если у тебя есть стартовый набор Arduino, плата, макетная плата, провода, фоторезистор, зуммер, а часто ещё сервопривод и LCD уже есть. При скромном бюджете можно отказаться от LCD и второго сервопривода: вместо дисплея используй монитор порта, а окно оставь на следующий этап. Более точный DHT22 вместо DHT11 стоит чуть дороже, зато делает твои измерения убедительнее на презентации.
План питания: зачем отдельный блок питания на 5 V?
В макетах умного дома почти любая жалоба вроде «время от времени перезагружается», «сервопривод дёргается» или «на LCD появляются странные символы» сводится к питанию. USB-порт компьютера даёт около 500 mA, и когда плата питается от USB, пин 5V у Uno тоже упирается в этот предел. Сложи значения ниже, и увидишь, что при одновременном движении обоих сервоприводов общий ток легко превышает 1 A.
| Деталь | Примерный ток при 5 V |
|---|---|
| Arduino Uno | 45–50 mA |
| MQ-2 (нагреватель включён всегда) | Около 150 mA |
| Модуль реле (на канал, реле включено) | 70–80 mA |
| Сервопривод SG90 (в движении / под нагрузкой) | 100–250 mA / до 0,5–0,7 A |
| I2C LCD (подсветка включена) | 20–30 mA |
| RC522 (от пина 3,3 V) | 13–26 mA |
| Активный зуммер, DHT11, PIR-датчик и датчик пламени | 30–40 mA в сумме |
| Мини-вентилятор на 5 V и светодиодная лампа | 100–400 mA в зависимости от модели |
План пинов: Arduino Uno и ESP32
Столько модулей почти полностью занимают пины Uno, поэтому их нужно планировать с самого начала. RC522 использует аппаратный SPI, так что его линии MOSI, MISO и SCK привязаны к D11, D12 и D13. LCD по I2C занимает только A4 и A5, поэтому мы выбрали дисплей с I2C-модулем, а не параллельный LCD. Аналоговые пины при необходимости работают и как цифровые, благодаря этому сервопривод окна можно подключить к A2. Оставь D0 и D1 свободными: эта последовательная линия используется при загрузке кода и при чтении номеров карт в мониторе порта. Расположение пинов своей платы можно посмотреть в утилите распиновки.
| Пин модуля | Arduino Uno | ESP32 |
|---|---|---|
| PIR OUT | D2 | GPIO 16 |
| Датчик пламени DO | D3 | GPIO 17 |
| DHT11 DATA | D4 | GPIO 13 |
| Активный зуммер (+) | D5 | GPIO 25 |
| Сервопривод двери (сигнал) | D6 | GPIO 32 |
| Реле IN1 (лампа) | D7 | GPIO 26 |
| Реле IN2 (вентилятор) | D8 | GPIO 27 |
| RC522 RST | D9 | GPIO 4 |
| RC522 SDA (SS) | D10 | GPIO 5 |
| RC522 MOSI / MISO / SCK | D11 / D12 / D13 | GPIO 23 / 19 / 18 |
| MQ-2 AO | A0 | GPIO 34 (через делитель напряжения) |
| Средняя точка делителя с фоторезистором | A1 | GPIO 35 (делитель питается от 3V3) |
| Сервопривод окна (сигнал) | A2 | GPIO 33 |
| I2C LCD SDA / SCL | A4 / A5 | GPIO 21 / 22 |
Сборка шаг за шагом
- Собери корпус макета и подготовь места для модулей и отверстия для проводов; электронику устанавливай в последнюю очередь.
- Подготовь линию питания: подключи блок питания 5 V к шинам питания макетной платы, соедини GND блока питания с GND Arduino и проверь 5 V мультиметром.
- Подключи I2C LCD и выведи на него какой-нибудь текст. Если не удаётся найти адрес дисплея, воспользуйся скетчем-сканером из статьи I2C LCD.
- Добавляй датчики по одному: DHT11, фоторезистор, PIR, MQ-2 и датчик пламени. Проверь каждый коротким тестовым скетчем в мониторе порта и запиши показания на чистом воздухе, в темноте и на свету.
- Добавь исполнительные устройства: сначала проверь реле без нагрузки по щелчку и светодиоду, затем сервоприводы на внешнем питании и в конце подключи RC522. Отсканируй свои карты и запиши их номера.
- Загрузи основной скетч и выстави пороги GAS_LIMIT, DARK_LIMIT и FAN_ON по своим записям.
- Закрепи провода термоклеем и подпиши их, затем оставь систему включённой на полчаса и понаблюдай, нет ли перезагрузок, перегрева или ложных тревог.
Автоматический свет на PIR-датчике и фоторезисторе
PIR-датчик HC-SR501 улавливает изменения инфракрасного излучения человеческого тела и при движении выставляет на выходе HIGH. С одним только PIR-датчиком лампа загоралась бы и днём, поэтому в нашем правиле два условия: включать, если есть движение и темно. Фоторезистор вместе с резистором 10 kΩ включён как делитель напряжения (5V → LDR → A1 → 10 kΩ → GND), и показание на A1 падает по мере того, как темнеет. Код запоминает время последнего движения и выключает лампу через 20 секунд без нового движения; пока кто-то ходит рядом, таймер каждый раз запускается заново. Поставь перемычку датчика в положение H (повторный запуск), а потенциометр Tx — на минимальное время, и пусть время отсчитывает код. Подробнее — в статьях PIR-датчик движения и Фоторезистор (LDR).
Сигнализация газа и пожара
Внутри MQ-2 находится слой диоксида олова, который нагревается встроенным нагревателем; сжиженный газ, метан, бутан, водород, спирт и дым меняют сопротивление этого слоя. Пин AO модуля выдаёт напряжение, которое растёт вместе с концентрацией газа. Датчику нужно прогреваться при каждом включении, поэтому первые 60 секунд код игнорирует газовую тревогу. Датчик пламени улавливает инфракрасный свет в диапазоне 760–1100 нм, который излучает огонь; на большинстве модулей при виде пламени выход DO уходит в LOW и загорается второй светодиод на плате, но всё равно проверь свой модуль зажигалкой на расстоянии. При обнаружении газа звучит тревога и окно открывается для проветривания; при обнаружении пламени окно остаётся закрытым, потому что свежий воздух раздувает огонь. Настройка порога и другие датчики серии MQ описаны в статье Датчик газа MQ-2.
Температура, влажность и автоматический вентилятор
DHT11 измеряет температуру от 0 до 50 °C с точностью ±2 °C и влажность от 20 до 90% с точностью ±5%, а читать его можно не чаще раза в секунду; код читает его каждые две секунды. Вместо одного порога для вентилятора мы используем гистерезис: вентилятор включается при 28 °C, а выключается, только когда температура опустится до 26 °C. С одним порогом реле щёлкало бы без конца, пока температура колеблется между 27 и 28 °C, и изнашивало бы и себя, и вентилятор. Если датчику не удалось провести измерение и он вернул «nan», код пропускает это измерение и сохраняет последнее верное значение. Для более точных измерений DHT22 работает с тем же кодом; просто напиши DHT22 вместо DHT11. Подробнее — в статье Датчик температуры и влажности DHT11.
Дверь с RFID-картой и сервоприводом
RC522 читает карты и брелоки MIFARE на 13,56 MHz с расстояния 3–5 см. У каждой карты свой идентификационный номер (UID), и код сравнивает прочитанный UID со списком разрешённых карт. Если есть совпадение, сервопривод поворачивает дверь на 90 градусов, раздаётся короткий сигнал, а на LCD появляется «Hos geldin!» (по-турецки «Добро пожаловать!»); через 5 секунд дверь закрывается сама. На неизвестную карту звучит длинный сигнал. Чтобы узнать UID своих карт, загрузи код, открой монитор порта на скорости 9600 бод и приложи карту: появится строка вроде «UID: A1 B2 C3 D4». Впиши эти байты в список CARDS в виде 0xA1, добавляя ведущий ноль к байтам, показанным одной цифрой (0x05 вместо 5). Замок, который проверяет только UID, годится для обучения, но настоящей защиты не даёт; почему — объясняем в статье RFID RC522.
Окно и штора
Для окна хватит второго SG90: соедини проволокой маленькое акриловое окно на петле с качалкой сервопривода, где 0 градусов — закрыто, а 90 градусов — открыто. Вызов write(0) до attach() не даёт сервоприводу при включении дёрнуться на 90 градусов и хлопнуть окном. Шторе нужен больший ход: ткань наматывается на тонкий стержень, а стержень вращается. Для этого тихий и точный вариант — шаговый двигатель 28BYJ-48 с драйвером ULN2003, но ему нужны 4 пина; у Uno их уже не осталось, так что штору разумно оставить для версии на ESP32 или Arduino Mega. Если приходится обходиться одним пином, подойдёт и сервопривод постоянного вращения FS90R, но он не знает своего положения, поэтому открывать и закрывать штору придётся по времени. Ещё одно хорошее расширение — датчик дождя, чтобы окно само закрывалось, когда идёт дождь.
Лампа и вентилятор через реле

Пин Arduino может безопасно отдавать только около 20 mA (абсолютный предел — 40 mA), а вентилятору или лампе нужно гораздо больше. Поэтому между ними ставят модуль реле: сигнал на его пине IN подаёт ток на электромагнит, который замыкает контакты в отдельной цепи. Подключай нагрузку к клеммам COM и NO, чтобы лампа оставалась выключенной, пока Arduino выключена или перезагружается. Большинство таких модулей — с активным LOW, то есть реле включается, когда записываешь LOW; для этого в коде и есть константы RELAY_ON и RELAY_OFF. В setup() код записывает HIGH ещё до того, как сделать пин выходом, поэтому при запуске Arduino реле не щёлкает даже на мгновение. Для вентилятора мы используем гистерезис, чтобы он не включался и не выключался слишком часто, а лампа горит, пока не истечёт таймер PIR-датчика.
Полный скетч (Arduino Uno)
Главное правило кода умного дома: ни один модуль не ждёт другого. Если держать дверь открытой 5 секунд через delay(5000), всё это время не работала бы газовая сигнализация и не читался бы PIR-датчик. Поэтому каждый модуль вынесен в отдельную функцию, а loop() вызывает эти функции одну за другой сотни раз в секунду. Всё, что связано со временем, измеряется через millis(), а состояние каждого модуля хранится в переменных вроде lightOn, fanOn, doorOpen и alarmOn. Все настройки собраны в начале кода в виде констант, так что ради изменения порога не придётся копаться в коде. Логику этого подхода ты найдёшь в статье millis() или delay(). Чтобы скомпилировать код, установи через «Менеджер библиотек» (Library Manager) библиотеку MFRC522, DHT sensor library от Adafruit и LiquidCrystal I2C от Frank de Brabander, а когда спросят, установи все зависимости. Servo, SPI и Wire входят в состав Arduino IDE.
1#include <SPI.h>
2#include <MFRC522.h>
3#include <Servo.h>
4#include <DHT.h>
5#include <Wire.h>
6#include <LiquidCrystal_I2C.h>
7
8// Pinler / Pins
9const byte PIR_PIN = 2, FLAME_PIN = 3, DHT_PIN = 4, BUZZER_PIN = 5, DOOR_PIN = 6;
10const byte LAMP_RELAY = 7, FAN_RELAY = 8, RST_PIN = 9, SS_PIN = 10;
11const byte GAS_PIN = A0, LDR_PIN = A1, WINDOW_PIN = A2;
12
13// Ayarlar / Settings
14const byte RELAY_ON = LOW, RELAY_OFF = HIGH; // aktif LOW röle / active-LOW relay
15const byte FLAME_ACTIVE = LOW; // alev görünce DO LOW olur / DO goes LOW on flame
16const int GAS_LIMIT = 400; // temiz havaya göre ayarla / tune in clean air
17const int DARK_LIMIT = 300; // bunun altı karanlık / below this is dark
18const float FAN_ON = 28.0, FAN_OFF = 26.0; // fan histerezisi (°C) / fan hysteresis (°C)
19const unsigned long LIGHT_MS = 20000; // son hareketten sonra ışık / light after last motion
20const unsigned long DOOR_MS = 5000; // kapı açık kalma süresi / door open time
21const unsigned long WARMUP_MS = 60000; // MQ-2 ve PIR ısınması / MQ-2 and PIR warm-up
22
23const byte CARDS[][4] = { // yetkili kart UID'leri / authorised card UIDs
24 {0xA1, 0xB2, 0xC3, 0xD4},
25 {0x12, 0x34, 0x56, 0x78}
26};
27
28MFRC522 rfid(SS_PIN, RST_PIN);
29Servo door, window;
30DHT dht(DHT_PIN, DHT11);
31LiquidCrystal_I2C lcd(0x27, 16, 2);
32
33float tempC = 0, hum = 0;
34int gas = 0;
35bool lightOn = false, fanOn = false, doorOpen = false, alarmOn = false;
36unsigned long lastMotion = 0, doorAt = 0, lastDht = 0, lastLcd = 0, beepUntil = 0;
37
38void setup() {
39 Serial.begin(9600);
40 digitalWrite(LAMP_RELAY, RELAY_OFF); pinMode(LAMP_RELAY, OUTPUT); // açılışta kapalı / off at boot
41 digitalWrite(FAN_RELAY, RELAY_OFF); pinMode(FAN_RELAY, OUTPUT);
42 pinMode(PIR_PIN, INPUT);
43 pinMode(FLAME_PIN, INPUT);
44 pinMode(BUZZER_PIN, OUTPUT);
45 door.write(0); door.attach(DOOR_PIN); // önce açı, sonra attach / angle first, then attach
46 window.write(0); window.attach(WINDOW_PIN);
47 dht.begin();
48 SPI.begin();
49 rfid.PCD_Init();
50 lcd.init();
51 lcd.backlight();
52 lcd.print(F("BlueGrays Ev"));
53}
54
55void loop() {
56 unsigned long now = millis();
57 handleLight(now);
58 handleClimate(now);
59 handleSafety(now);
60 handleDoor(now);
61 bool beep = (long)(beepUntil - now) > 0;
62 digitalWrite(BUZZER_PIN, beep || (alarmOn && (now / 250) % 2)); // alarmda kesik bip / pulsed beep on alarm
63 updateLcd(now);
64}
65
66// 1) Hareketle ışık / motion light
67void handleLight(unsigned long now) {
68 if (now < WARMUP_MS) return; // PIR ısınıyor / PIR warming up
69 if (digitalRead(PIR_PIN) == HIGH) {
70 lastMotion = now;
71 if (analogRead(LDR_PIN) < DARK_LIMIT) lightOn = true; // yalnız karanlıkta yak / only when dark
72 }
73 if (lightOn && now - lastMotion > LIGHT_MS) lightOn = false;
74 digitalWrite(LAMP_RELAY, lightOn ? RELAY_ON : RELAY_OFF);
75}
76
77// 2) Sıcaklık ve fan / temperature and fan
78void handleClimate(unsigned long now) {
79 if (now - lastDht < 2000) return; // DHT11'i sık okuma / don't read DHT11 too often
80 lastDht = now;
81 float t = dht.readTemperature();
82 float h = dht.readHumidity();
83 if (isnan(t) || isnan(h)) return; // okuma hatası / read error
84 tempC = t;
85 hum = h;
86 if (tempC >= FAN_ON) fanOn = true;
87 if (tempC <= FAN_OFF) fanOn = false;
88 digitalWrite(FAN_RELAY, fanOn ? RELAY_ON : RELAY_OFF);
89}
90
91// 3) Gaz ve yangın / gas and fire
92void handleSafety(unsigned long now) {
93 gas = analogRead(GAS_PIN);
94 bool gasAlarm = now > WARMUP_MS && gas > GAS_LIMIT;
95 bool fire = digitalRead(FLAME_PIN) == FLAME_ACTIVE;
96 alarmOn = gasAlarm || fire;
97 window.write(gasAlarm && !fire ? 90 : 0); // gazda aç, yangında kapalı tut / open on gas, shut on fire
98}
99
100// 4) RFID kapı / RFID door
101void handleDoor(unsigned long now) {
102 if (doorOpen && now - doorAt > DOOR_MS) {
103 door.write(0); // süre dolunca kapat / close when time is up
104 doorOpen = false;
105 }
106 if (!rfid.PICC_IsNewCardPresent() || !rfid.PICC_ReadCardSerial()) return;
107 Serial.print(F("UID:")); // yeni kartın UID'sini öğren / learn a new card's UID
108 for (byte i = 0; i < rfid.uid.size; i++) {
109 Serial.print(' ');
110 Serial.print(rfid.uid.uidByte[i], HEX);
111 }
112 Serial.println();
113 if (isAllowed(rfid.uid.uidByte)) {
114 door.write(90);
115 doorOpen = true;
116 doorAt = now;
117 beepUntil = now + 100; // kısa bip: hoş geldin / short beep: welcome
118 } else {
119 beepUntil = now + 800; // uzun bip: yetkisiz kart / long beep: unknown card
120 }
121 rfid.PICC_HaltA();
122}
123
124bool isAllowed(const byte *uid) {
125 for (byte i = 0; i < sizeof(CARDS) / 4; i++) {
126 if (memcmp(uid, CARDS[i], 4) == 0) return true;
127 }
128 return false;
129}
130
131// 5) Ekran / display
132void updateLcd(unsigned long now) {
133 if (now - lastLcd < 1000) return;
134 lastLcd = now;
135 lcd.setCursor(0, 0);
136 lcd.print(F("T:"));
137 lcd.print(tempC, 0);
138 lcd.print(F("C Nem:%"));
139 lcd.print(hum, 0);
140 lcd.print(F(" "));
141 lcd.setCursor(0, 1);
142 if (alarmOn) {
143 lcd.print(F("!! ALARM !! "));
144 } else if (doorOpen) {
145 lcd.print(F("Hos geldin! "));
146 } else {
147 lcd.print(F("Gaz:"));
148 lcd.print(gas);
149 lcd.print(F(" "));
150 }
151}| Функция | Задача | Как часто? |
|---|---|---|
| handleLight() (свет) | Включает реле лампы по PIR-датчику и фоторезистору и выключает после 20 секунд без движения | Каждый проход loop (кроме первых 60 секунд) |
| handleClimate() (климат) | Читает DHT11 и управляет вентилятором с гистерезисом 28/26 °C | Каждые 2 секунды |
| handleSafety() (безопасность) | Читает MQ-2 и датчик пламени, управляет тревогой и окном | Каждый проход loop |
| handleDoor() (дверь) | Читает карту, выводит UID в монитор порта, открывает и закрывает дверь | Каждый проход loop |
| updateLcd() (дисплей) | Показывает температуру, влажность, показания датчика газа или сообщение о состоянии | Раз в секунду |
| Строка зуммера внутри loop() | Выдаёт сигнал при считывании карты и прерывистый звук тревоги | Каждый проход loop |
После компиляции этот код занимает около 38% памяти программ Uno и 28% её ОЗУ, так что запас памяти ещё есть, но из пинов свободным остаётся только A3. К A3 можно подключить кнопку или датчик дождя; для чего-то большего придётся перейти на Arduino Mega или ESP32. Заключать постоянный текст в F() — самый простой способ снизить расход ОЗУ.
Управление с телефона: веб-сервер на ESP32

У Uno нет Wi-Fi; проще всего управлять умным домом с телефона, если заменить «мозг» на ESP32. Код ниже подключает ESP32 к домашней сети и запускает небольшой веб-сервер. Когда телефон подключён к той же сети Wi-Fi, открой в браузере IP-адрес из монитора порта, и ты увидишь четыре большие кнопки для лампы, вентилятора, двери и окна, а также текущие температуру, влажность и показания датчика газа; страница обновляется сама каждые 10 секунд. Каждая кнопка отправляет ESP32 короткий запрос с указанием, какое устройство переключить; ESP32 меняет состояние и возвращает тебя на главную страницу. Для сервоприводов установи через «Менеджер библиотек» библиотеку ESP32Servo, потому что стандартная библиотека Servo на ESP32 не работает.
1#include <WiFi.h>
2#include <WebServer.h>
3#include <ESP32Servo.h>
4#include <DHT.h>
5
6const char* ssid = "AgAdi"; // Wi-Fi adın / your Wi-Fi name
7const char* password = "Sifre123"; // Wi-Fi şifren / your Wi-Fi password
8
9const int LAMP_RELAY = 26, FAN_RELAY = 27;
10const int DOOR_PIN = 32, WINDOW_PIN = 33;
11const int DHT_PIN = 13, GAS_PIN = 34; // GPIO 34: ADC1, bölücüyle / ADC1, through a divider
12const int RELAY_ON = LOW, RELAY_OFF = HIGH; // aktif LOW röle / active-LOW relay
13
14WebServer server(80);
15Servo door, window;
16DHT dht(DHT_PIN, DHT11);
17
18bool lamp = false, fan = false, doorOpen = false, windowOpen = false;
19float tempC = NAN, hum = NAN;
20unsigned long lastDht = 0;
21
22void apply() { // durumu donanıma uygula / push the state to the hardware
23 digitalWrite(LAMP_RELAY, lamp ? RELAY_ON : RELAY_OFF);
24 digitalWrite(FAN_RELAY, fan ? RELAY_ON : RELAY_OFF);
25 door.write(doorOpen ? 90 : 0);
26 window.write(windowOpen ? 90 : 0);
27}
28
29String button(const char* id, const char* label, bool on) {
30 return String("<a class='b ") + (on ? "on" : "off") + "' href='/set?d=" + id +
31 "&v=" + (on ? "0" : "1") + "'>" + label + (on ? ": ON" : ": OFF") + "</a>";
32}
33
34void handleRoot() {
35 String html = "<!DOCTYPE html><html><head><meta charset='utf-8'>"
36 "<meta name='viewport' content='width=device-width,initial-scale=1'>"
37 "<meta http-equiv='refresh' content='10'><title>BlueGrays Ev</title>"
38 "<style>body{font-family:sans-serif;text-align:center}"
39 ".b{display:block;margin:12px auto;padding:18px;max-width:320px;border-radius:10px;"
40 "color:#fff;text-decoration:none;font-size:20px}"
41 ".on{background:#2e7d32}.off{background:#607d8b}</style></head><body>"
42 "<h2>BlueGrays Akıllı Ev</h2>";
43 html += "<p>" + String(tempC, 1) + " °C | %" + String(hum, 0) +
44 " | Gaz/Gas: " + String(analogRead(GAS_PIN)) + "</p>";
45 html += button("lamp", "Lamba / Lamp", lamp);
46 html += button("fan", "Fan", fan);
47 html += button("door", "Kapı / Door", doorOpen);
48 html += button("window", "Pencere / Window", windowOpen);
49 html += "</body></html>";
50 server.send(200, "text/html", html);
51}
52
53void handleSet() { // /set?d=lamp&v=1
54 String d = server.arg("d");
55 bool v = server.arg("v") == "1";
56 if (d == "lamp") lamp = v;
57 else if (d == "fan") fan = v;
58 else if (d == "door") doorOpen = v;
59 else if (d == "window") windowOpen = v;
60 apply();
61 server.sendHeader("Location", "/"); // ana sayfaya dön / back to the main page
62 server.send(303);
63}
64
65void setup() {
66 Serial.begin(115200);
67 door.attach(DOOR_PIN, 500, 2400);
68 window.attach(WINDOW_PIN, 500, 2400);
69 pinMode(LAMP_RELAY, OUTPUT);
70 pinMode(FAN_RELAY, OUTPUT);
71 apply(); // her şey kapalı başlar / everything starts off
72 dht.begin();
73 WiFi.begin(ssid, password);
74 while (WiFi.status() != WL_CONNECTED) {
75 delay(500);
76 Serial.print('.');
77 }
78 Serial.println();
79 Serial.println(WiFi.localIP()); // bu adresi telefonda aç / open this address on your phone
80 server.on("/", handleRoot);
81 server.on("/set", handleSet);
82 server.begin();
83}
84
85void loop() {
86 server.handleClient();
87 if (millis() - lastDht > 2000) { // 2 sn'de bir ölç / measure every 2 s
88 lastDht = millis();
89 float t = dht.readTemperature();
90 float h = dht.readHumidity();
91 if (!isnan(t) && !isnan(h)) {
92 tempC = t;
93 hum = h;
94 }
95 }
96}В этот код входят только те части, которыми ты управляешь удалённо. Сюда можно перенести и функции handleLight(), handleSafety() и handleDoor() из скетча для Uno: поменяй номера пинов по столбцу ESP32 в таблице, используй ESP32Servo вместо Servo и заново измерь пороги GAS_LIMIT и DARK_LIMIT, потому что АЦП ESP32 возвращает значения от 0 до 4095. У страницы нет пароля, так что открыть дверь сможет любой в твоей домашней сети; добавить простой пароль функцией authenticate() библиотеки WebServer — хорошая привычка. Для панели, которая обновляется в реальном времени, смотри статью ESP32 и WebSocket.
Управление откуда угодно через Blynk
До веб-сервера на ESP32 можно достучаться только из той же сети. Если хочется управлять домом и снаружи, через мобильный интернет, всё упрощает облачная платформа вроде Blynk IoT: интерфейс собирается перетаскиванием в приложении на телефоне, а ESP32 подключается к серверу Blynk. Создай шаблон в Blynk.Cloud, добавь три потока данных (datastreams) — V0 (integer, 0–1, лампа), V1 (double, температура) и V2 (double, влажность), — добавь устройство и вставь выданные Template ID, Template Name и Auth Token в начало кода. В приложении достаточно привязать виджет Switch к V0 и по виджету Gauge к V1 и V2. Бесплатный тариф ограничивает число устройств, потоков данных и сообщений в месяц, поэтому мы отправляем данные датчиков каждые пять секунд, а не каждую секунду. Полная настройка описана в руководстве Blynk IoT и ESP32.
1#define BLYNK_TEMPLATE_ID "TMPLxxxxxxx" // Blynk konsolundan kopyala / copy from the Blynk console
2#define BLYNK_TEMPLATE_NAME "Akilli Ev"
3#define BLYNK_AUTH_TOKEN "TokenBuraya"
4
5#include <WiFi.h>
6#include <BlynkSimpleEsp32.h>
7#include <DHT.h>
8
9const int LAMP_RELAY = 26; // aktif LOW röle / active-LOW relay
10DHT dht(13, DHT11);
11BlynkTimer timer;
12
13BLYNK_WRITE(V0) { // uygulamadaki anahtar / switch widget in the app
14 digitalWrite(LAMP_RELAY, param.asInt() ? LOW : HIGH);
15}
16
17BLYNK_CONNECTED() {
18 Blynk.syncVirtual(V0); // bağlanınca son durumu al / restore the last state
19}
20
21void sendSensors() {
22 float t = dht.readTemperature();
23 float h = dht.readHumidity();
24 if (isnan(t) || isnan(h)) return;
25 Blynk.virtualWrite(V1, t); // sıcaklık / temperature
26 Blynk.virtualWrite(V2, h); // nem / humidity
27}
28
29void setup() {
30 pinMode(LAMP_RELAY, OUTPUT);
31 digitalWrite(LAMP_RELAY, HIGH); // açılışta kapalı / off at boot
32 dht.begin();
33 Blynk.begin(BLYNK_AUTH_TOKEN, "AgAdi", "Sifre123");
34 timer.setInterval(5000L, sendSensors); // 5 sn'de bir: mesaj kotasını korur / every 5 s saves quota
35}
36
37void loop() {
38 Blynk.run();
39 timer.run();
40}Какой способ управления выбрать?
| Способ | Что нужно | Снаружи дома | Сложность | Лучше всего для |
|---|---|---|---|---|
| Веб-сервер на ESP32 | ESP32 и домашний Wi-Fi | Нет, только в той же сети | Средняя | Школьные презентации, демонстрации без интернета, полностью свой код |
| Blynk IoT | ESP32, интернет и аккаунт Blynk | Да | Лёгкая | Готовый интерфейс, графики и уведомления |
| Bluetooth (HC-05) | Uno, HC-05 и приложение для Android | Нет, около 10 м | Лёгкая | Если хочется остаться на Uno (не работает с iPhone) |
| Telegram-бот | ESP32 и интернет | Да | Средняя | Уведомления о тревоге и короткие команды |
| MQTT + Home Assistant | ESP32 и локальный сервер (например, Raspberry Pi) | Да, нужна настройка | Высокая | Настоящая домашняя автоматизация |
Для школьной презентации самый надёжный выбор — веб-сервер на ESP32: он не зависит от интернета и облака и работает в собственной сети, даже если в зале нет Wi-Fi. Если хочется остаться на Uno и просто добавить Bluetooth, можно сделать своё приложение для Android в App Inventor; но у Uno не осталось свободных пинов, так что ради HC-05 придётся пожертвовать LCD или сервоприводом окна. Получать сообщение на телефон при срабатывании тревоги можно с помощью Telegram-бота на ESP32, а подключить дом к настоящим устройствам — через MQTT и Home Assistant.
Умный дом на Raspberry Pi Pico
Ту же систему можно собрать и на MicroPython с Raspberry Pi Pico, а Pico W с Wi-Fi можно управлять с телефона так же, как ESP32 (смотри веб-сервер на Pico W). Pico работает от 3,3 V, поэтому и здесь действуют правила для ESP32: питай делитель с фоторезистором от 3V3, понижай аналоговые выходы на 5 V делителем и выбирай модуль реле, который срабатывает от 3,3 V. Аналоговых входов всего три: GP26, GP27 и GP28. Код ниже — версия модуля света по движению на MicroPython:
1from machine import Pin, ADC
2import time
3
4pir = Pin(15, Pin.IN) # PIR OUT (3,3 V çıkış / 3.3 V output)
5ldr = ADC(26) # GP26: bölücü 3V3'ten / divider fed from 3V3
6relay = Pin(14, Pin.OUT, value=1) # aktif LOW röle, kapalı başla / active-LOW relay, start off
7
8LIGHT_MS = 20000 # son hareketten sonra ışık / light after last motion
9DARK = 20000 # bunun altı karanlık / below this is dark
10last = time.ticks_ms()
11on = False
12
13while True:
14 now = time.ticks_ms()
15 if pir.value():
16 last = now
17 if ldr.read_u16() < DARK: # yalnız karanlıkta yak / only when dark
18 on = True
19 if on and time.ticks_diff(now, last) > LIGHT_MS:
20 on = False
21 relay.value(0 if on else 1)
22 time.sleep_ms(50)Советы для школьной презентации
- Начни с проблемы: опиши реальную ситуацию одной фразой, например «свет, забытый в пустом доме, утечка газа, которую никто не замечает, пожилые люди, теряющие ключи», а затем покажи, как твой макет её решает.
- Подготовь структурную схему: датчики слева, Arduino в центре, исполнительные устройства справа; подпиши стрелки правилами («темно + движение → лампа»). Жюри не будет читать твой код, но эту схему запомнит.
- Распиши живую демонстрацию: приложи карту и покажи, как открывается дверь, помаши рукой перед PIR-датчиком, поднеси к MQ-2 ватный диск, смоченный медицинским спиртом (спирт тоже вызывает срабатывание датчика), и погрей DHT11 пальцами. Каждая демонстрация — 10–20 секунд.
- Никакого открытого огня: не зажигай зажигалку или свечу внутри картонного макета. Большинство датчиков пламени реагируют и на инфракрасный свет пульта от телевизора, поднесённого близко; проверь это заранее и используй в демонстрации.
- Подстрой пороги под помещение: если в день презентации в зале 22 °C, ожидание 28 °C сорвёт демонстрацию вентилятора; выставь FAN_ON на 2–3 градуса выше комнатной температуры, чтобы вентилятор включался, когда греешь датчик пальцами.
- Измеряй и приводи цифры: например, запиши, сколько минут в день горит лампа с PIR-датчиком и без него, и укажи экономию в процентах. Результат в цифрах гораздо убедительнее, чем «оно работает».
- Держи запасной план: запиши видео работающей системы, возьми запасные провода, сервопривод и блок питания, а номера карт и настройки Wi-Fi запиши на листке.
- Подготовься к вопросам жюри: на вопрос «Как это работало бы в настоящем доме?» держи наготове короткие ответы о безопасности при сетевом напряжении, сертифицированных датчиках, защищённости RFID и о том, что происходит с дверью при отключении электричества.
Частые ошибки и как их исправить
| Признак | Вероятная причина | Решение |
|---|---|---|
| Arduino перезагружается или LCD сходит с ума, когда двигается сервопривод | Сервоприводы и реле питаются от пина 5V Arduino | Отдельный блок питания 5 V 2–3 A, общий GND, конденсатор 470–1000 µF на питании сервоприводов |
| Реле работает наоборот и включено при подаче питания | Модуль с активным LOW | Поменяй местами значения RELAY_ON и RELAY_OFF |
| Тревога срабатывает при каждом включении | MQ-2 прогревается, а PIR-датчик привыкает к обстановке | Оставь задержку WARMUP_MS; перед первым использованием дай MQ-2 долго поработать |
| Лампа загорается днём или гаснет и тут же снова включается | Неверный DARK_LIMIT или фоторезистор видит свет лампы | Выставь порог по показаниям в мониторе порта и перенеси фоторезистор на наружную стену |
| Карты не читаются | Ошибка в подключении RC522 или модуль подключён к 5 V | Проверь пины SPI и протестируй модуль примером DumpInfo |
| DHT11 возвращает nan | Провод DATA на неправильном пине или у голого датчика нет подтягивающего резистора | Проверь пин, используй модуль или добавь 10 kΩ между DATA и VCC |
| Сервопривод время от времени дёргается | Слабое питание; при чтении DHT11 прерывания ненадолго приостанавливаются | Улучши питание; при необходимости вызывай detach() для сервопривода, когда он закончит движение |
| На ESP32 показания газа всегда 0 или 4095 | Пин ADC2 конфликтует с Wi-Fi или нет делителя | Используй пин ADC1, например GPIO 34 или 35, и делитель напряжения |
| Телефон не открывает страницу ESP32 | Телефон в гостевой сети или на мобильном интернете либо сеть на 5 GHz | Подключись к той же сети 2,4 GHz и возьми IP-адрес из монитора порта |
Проект умного дома на Arduino объединяет в одной сборке чтение датчиков, принятие решений, управление моторами и реле, планирование питания и беспроводное управление, поэтому это отличная тема и для учёбы, и для презентации. Начни с одного модуля, проверяй каждый шаг и наращивай систему понемногу. В приложении BlueGrays есть пошаговые проекты умной подсветки лестницы, умного освещения с PIR-датчиком и фоторезистором, сигнализации пламени и газа, RFID-замка двери и веб-сервера на ESP32 — со схемами подключения и кодом.
Частые вопросы
Что нужно для проекта умного дома на Arduino?
Для базового макета хватит Arduino Uno или ESP32, PIR-датчика движения, фоторезистора, датчика газа MQ-2, датчика пламени, DHT11, RFID-модуля RC522, двух сервоприводов SG90, 2-канального модуля реле, зуммера и I2C LCD. Добавь макетную плату, провода-перемычки, блок питания 5 V 2–3 A и материалы для макета. Большинство модулей стоят недорого; основная часть бюджета уходит на плату, дисплей, блок питания и сам макет.
Что лучше для умного дома: Arduino или ESP32?
Если управление с телефона не нужно, проще Arduino Uno: она напрямую работает с модулями на 5 V, и большинство примеров написано именно для неё. Выбирай ESP32, если нужны управление с телефона по Wi-Fi, уведомления или больше пинов, но её пины работают от 3,3 V, поэтому с модулями реле и аналоговыми датчиками на 5 V придётся быть внимательнее.
Как управлять умным домом на Arduino с телефона?
Проще всего взять ESP32 и поднять веб-сервер; тогда лампой, вентилятором и дверью можно управлять кнопками в браузере телефона, подключённого к той же сети Wi-Fi. Для доступа снаружи дома подойдёт облачное приложение вроде Blynk IoT, а если хочется остаться на Arduino Uno — Bluetooth-модуль HC-05 и приложение для Android.
Из какого материала лучше делать макет умного дома?
Самый практичный материал — пенокартон или вспененный ПВХ толщиной 5 мм: он режется канцелярским ножом и клеится термоклеем. Для более прочного корпуса подойдёт МДФ 3–4 мм. Основание примерно 50×40 см, съёмная крыша и отдельный технический отсек для электроники сильно упрощают работу.
Может ли Arduino включать и выключать сетевую лампу?
Да, через модуль реле на 5 V, который электрически отделяет сетевую цепь от Arduino. Но сетевое напряжение может убить: выполняй подключения только при вынутой из розетки вилке, размещай схему в закрытом изолированном корпусе и никогда не работай с ней в ученическом проекте без присмотра взрослых. Для макета вполне достаточно ламп на 5 V или 12 V.
Подходит ли умный дом на Arduino для научной выставки?
Умный дом — очень распространённая тема, поэтому одного работающего макета часто недостаточно. Если связать проект с измеримым исследовательским вопросом, например сколько энергии экономит освещение по движению или как быстро срабатывает газовая сигнализация, он станет гораздо сильнее в глазах жюри.
Что собрать после прочтения
Все проекты
Температура и влажность с DHT11
Насколько тепло в твоей комнате и влажный ли воздух или сухой? Датчик DHT11 измеряет температуру и влажность, а Arduino выводит значения на двухстрочный LCD-экран и обновляет их каждые пару секунд. Ес

Умное освещение лестницы и коридора
Ступи на лестницу или в коридор, и свет загорается ступенька за ступенькой в ту сторону, куда ты идёшь. На каждом конце стоит датчик расстояния; мимо какого ни пройдёшь, восемь светодиодов загораются

Умное освещение на ESP32 (PIR + LDR + реле + OLED)
Сделай умное освещение для коридора, ванной или кладовки на ESP32! С PIR-датчиком движения, датчиком освещённости LDR и модулем реле собирается классический сценарий «свет включается при движении в темноте»: если вокруг уже светло, движение свет НЕ включает, и днём энергия экономится. Свет горит 30 секунд; если движение продолжается, таймер сбрасывается, и свет горит дольше. OLED SSD1306 крупно показывает состояние (ON / DAYTIME / WAITING) и обратный отсчёт.

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

Сигнализация пламени и газа
Маленький страж, который сразу предупреждает, когда где-то утекает газ или появляется пламя. Датчик газа следит за газом в воздухе, а датчик пламени — за светом огня; пока всё в порядке, горит зелёный

Дверной замок с RFID на ESP32 (RC522 + сервопривод + OLED + зуммер + светодиод)
Собираем умный дверной замок на ESP32, модуле RFID RC522, сервоприводе SG90, OLED-дисплее SSD1306, активном зуммере и 2 светодиодах. При поднесении карты её UID сравнивается со списком разрешённых карт в коде: если доступ разрешён, сервопривод поворачивается и открывает дверь (зелёный светодиод + 2 коротких сигнала), а через 5 секунд дверь снова запирается сама. При чужой карте загорается красный светодиод, звучат 3 быстрых сигнала, а прочитанный UID показывается на экране.

Включение лампы 220V пультом
Включай и выключай настоящую лампу у себя дома пультом от телевизора, не вставая с дивана. Arduino читает невидимый световой сигнал пульта; кнопка питания щёлкает реле и включает лампу, а кнопка отклю

Асинхронный веб-сервер на ESP32 (с выводом IP на LCD)
В этом проекте ESP32 превращается в асинхронный веб-сервер, которым можно управлять с телефона или компьютера в той же сети Wi-Fi. Благодаря библиотеке ESPAsyncWebServer сервер может обрабатывать несколько запросов одновременно (в отличие от классического WebServer.h, который блокируется на одном запросе). Открыв IP-адрес ESP32 в браузере, ты нажимаешь кнопки ON/OFF (маршруты /on и /off) и включаешь и выключаешь светодиод на GPIO 5.
Другие статьи
Приложение BlueGrays
Собери эту схему шаг за шагом в телефоне
Схема подключения, код и список деталей на одном экране. 200+ проектов на Arduino, ESP32 и Pico готовы к сборке.
Наведи камеру телефона
Наведи камеру на код — откроется магазин приложений на телефоне.
или открыть магазин

