Octopod: Умная IoT-автоматизация для дома и промышленности
Компоненты и материалы
| Название | Количество |
|---|---|
| Arduino UNO | 1 |
| Arduino MKR WiFi 1010 (или NodeMCU ESP8266 / ESP32) | 1 |
| Maxim Integrated MAX32630FTHR (или MAX32620FTHR, Arduino 1010, любой ESP8266 — потребуется внешний WiFi) | 1 |
| Raspberry Pi Zero Wireless (можно Pi 2/3) | 1 |
| DHT11 Температура и влажность (4 пина) | 1 |
| Seeed Grove Gas Sensor MQ2 | 1 |
| SparkFun Soil Moisture Sensor | 1 |
| PIR датчик движения | 1 |
| RFID-ридер (например, MFRC522) | 1 |
| Реле (2-канальное) | 1 |
| RGB светодиод общий катод | 1 |
| Raspberry Pi Camera Module | 1 |
| Сервопривод Tower Pro MG996R | 1 |
| Зуммер | 2 |
| Bluetooth HC-05 (опционально) | 1 |
| Светодиоды | 4 |
| Блок питания / Power Bank | 2 |
| MicroSD карта (>4 Гб, Class 10 для Raspberry Pi OS) | 1 |
Необходимые инструменты
- Клеевой пистолет
- 3D-принтер (опционально)
- Ручной инструмент (плоскогубцы, ножницы, нож)
Приложения и онлайн-сервисы
- Blynk (управление со смартфона)
- OpenCV (распознавание людей на Raspberry Pi)
О проекте
Octopod — комплексная система умного дома на базе NodeMCU (или MAX32620FTHR / Arduino MKR 1010), Arduino Uno и Raspberry Pi 3. Отправляет данные о температуре, влажности, качестве газа, движении, влажности почвы. Уведомляет о движении и необходимости полива. Управление приборами через приложение Blynk. Режим «mood lighting» (RGB). Камера на Raspberry Pi дает живую видеопоток и с помощью OpenCV обнаруживает людей, отправляя их фото на email. RFID-замок на двери открывает при приближении разрешенной карты.



Как всё работает
- NodeMCU подключен к датчикам, реле, RGB-светодиодам. Через WiFi общается с Blynk-приложением — передает данные и принимает команды управления.
- Raspberry Pi в той же WiFi-сети: живой видеопоток с камеры. Установлен OpenCV — детектирует людей в кадре и отправляет фото на email.
- Умный замок на Arduino с RFID: при считывании разрешенного UID сервопривод открывает дверь.
Шаг 1: Код основного Octopod (NodeMCU)
Код с подробными комментариях. Основные моменты:
Библиотеки
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <DHT.h>
#define BLYNK_PRINT Serial
Настройки Blynk и WiFi
char auth[] = "Your Blynk Auth Key";
char ssid[] = "Your WiFi SSID";
char pass[] = "Your WiFi Password";
Пины и переменные
#define DHTPIN 2
#define soilPin 4
#define gasPin A0
#define pirPin 12
int pirValue, soilValue;
int PIRpinValue, SOILpinValue;
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
BlynkTimer timer;
Обработка виртуальных пинов Blynk (V0 — движение, V1 — почва)
BLYNK_WRITE(V0) { PIRpinValue = param.asInt(); }
BLYNK_WRITE(V1) { SOILpinValue = param.asInt(); }
Отправка данных датчиков (каждую секунду)
void sendSensor() {
int h = dht.readHumidity();
int t = dht.readTemperature();
if (isnan(h) || isnan(t)) { Serial.println("Failed to read from DHT sensor!"); return; }
Blynk.virtualWrite(V5, h); // влажность
Blynk.virtualWrite(V6, t); // температура
}
Проверка PIR и почвы (по команде из приложения)
void getPirValue() {
pirValue = digitalRead(pirPin);
if (pirValue) { Serial.println("Motion detected"); Blynk.notify("Motion detected"); }
}
void getSoilValue() {
soilValue = digitalRead(soilPin);
if (soilValue == HIGH) { Serial.println("Water Plants"); Blynk.notify("Water Plants"); }
}
Setup и Loop
void setup() {
Serial.begin(9600);
Blynk.begin(auth, ssid, pass);
dht.begin();
Blynk.tweet("OCTOPOD IS ONLINE!");
pinMode(pirPin, INPUT);
pinMode(soilPin, INPUT);
timer.setInterval(1000L, sendSensor);
}
void loop() {
Blynk.run(); timer.run();
if (PIRpinValue == HIGH) getPirValue();
if (SOILpinValue == HIGH) getSoilValue();
}
Шаг 2: Код RFID-умного замка (Arduino Uno)
Две версии: без Bluetooth (Serial Monitor) и с Bluetooth (HC-05). Библиотека MFRC522.
- Установить библиотеку MFRC522. Запустить пример
dumpInfo, считываем UID карт. - В коде заменить
XX XX XX XXна нужный UID. - Логика: если UID совпадает — сервопривод поворачивается на 180° (открывает), зеленый LED, звук. Иначе — красный LED, другой звук.



Шаг 3: Raspberry Pi — ИИ детекция людей (OpenCV)
Подробная инструкция по установке OpenCV 3.3.0 на Raspberry Pi 3 с Raspbian Stretch.
- Подключение камеры: вставить шлейф между Ethernet и HDMI (серебряные контакты к HDMI). Включить камеру через
sudo raspi-config. - Установка OpenCV:
- Расширить файловую систему (
raspi-config→ Expand Filesystem). - Удалить лишнее:
sudo apt-get purge wolfram-engine libreoffice* && sudo apt-get clean && sudo apt-get autoremove(освобождает ~1 Гб). - Установить зависимости: build-essential, cmake, pkg-config, libjpeg-dev, libtiff5-dev, libjasper-dev, libpng12-dev, libavcodec-dev, libavformat-dev, libswscale-dev, libv4l-dev, libxvidcore-dev, libx264-dev, libgtk2.0-dev, libgtk-3-dev, libatlas-base-dev, gfortran, python2.7-dev, python3-dev.
- Скачать OpenCV 3.3.0 и opencv_contrib 3.3.0, распаковать.
- Установить pip, virtualenv, virtualenvwrapper. Создать виртуальное окружение
cv(Python 2 или 3). - Установить NumPy:
pip install numpy. - Собрать OpenCV с CMake (указать
OPENCV_EXTRA_MODULES_PATHна opencv_contrib/modules). Увеличить swap до 1024 Мб (/etc/dphys-swapfile) для компиляции на 4 ядрах (make -j4). sudo make install && sudo ldconfig. Создать симлинкcv2.soв виртуальное окружение.- Вернуть swap к 100 Мб.
- Проверить:
python -c "import cv2; print(cv2.__version__)"→ 3.3.0.
- Расширить файловую систему (
- Python-скрипт умной камеры: Скачать файлы и модели с Google Drive. Настроить
mail.py(Gmail SMTP, разрешить «менее безопасные приложения»). Вmain.pyможно сменить классификатор (fullbody/upperbody/facial). Запуск:python main.py. Живой стрим наIP_пи:5000. Для внешнего доступа — ngrok.







Шаг 4: Настройка интерфейса Blynk
- Скачать Blynk (App Store / Google Play), войти.
- New Project → Device: NodeMCU, Connection: WiFi. Получить Auth Token на email.
- Добавить виджеты:
- 3 Gauge: Temperature (V6, 0-50°C), Humidity (V5, 0-100%), Gas (V7, 0-1023).
- zeRGBa: R→GP15, G→GP3, B→GP1 (RGB-лента).
- 4 Button: управление реле, режимами.
- SuperChart: 3 потока (Temp, Humidity, Gas).
- Вкладка 2: Twitter, Notifications, Email, Eventor (триггеры: движение → email/notify, полив → notify и т.д.).
- Нажать Play. Интерфейс готов.


Шаг 5: Корпус Octopod (картон / 3D-печать)
Форма вдохновлена октагоном — 3D-октагон. Можно пропустить и напечатать готовый корпус (файлы ниже).
- Картон: рисовать прямоугольники 9×9.5 см, 4 шт в ряд, делать фальцы, вырезать. 4 таких полоски.
- Вырезать 16 углов 135°, клеить между сегментами.
- Склеить 2 открытых структуры в закрытый октагон, затем 2 перпендикулярно → 3D-форма.
- Заклеить 4 прямоугольника 9×9.5 см в промежутки.
- Остается 8 треугольников — вырезать из акрил/прозрачной бумаги, вставить (не клеить все — оставить доступ).
- Покраска: 2-3 слоя спрея в проветриваемом месте, маска, перчатки. Высыхание 4-5 часов между слоями.

Шаг 6: Корпус замка двери
Обычная коробка от обуви, 2-3 слоя краски, узор из скотча. Отверстия для LED и сервопривода.

Шаг 7: Сборка Octopod
NodeMCU на большой макетной плате с блоком питания. Подключение датчиков по схеме:
- DHT11 → D4/GP2
- MQ2 → A0/ADC0
- Soil Moisture → D2/GP4
- PIR → D6/GP12
- RGB: R→D8/GP15, G→Rx/GP3, B→Tx/GP1
- Relay: Ln1→D0/GP16, Ln2→D5/GP14

Шаг 8: Сборка замка двери
После прошивки Arduino собрать по схеме (Fritzing). В коробке от обуви: 2 отверстия для LED, сервопривод выступает. RFID-модуль и макетная плата приклеены к стенке. Питание от Power Bank или адаптера. Это эксперимент — не используйте как основной замок!
Заключение
Веселый и полезный проект. Свет хорошо смотрится, можно сделать просто как настольную лампу. Спасибо создателям Blynk и OpenCV — без их библиотек это было бы невозможно. Голосуйте за проект!
— Saksham
Arduino Blog | Full Instructable

Обновление
Работаю над интеграцией с Amazon Alexa. Код выложу через 2-3 дня!
Код
octopod.ino (Arduino — NodeMCU/MKR1010/MAX32620)
/***************************************************************************
OCTOPOD: SMART HOME AUTOMATION BY SAKSHAM
Blynk lib: https://github.com/blynkkk/blynk-library/releases/latest
DHT lib: https://github.com/adafruit/DHT-sensor-library
***************************************************************************/
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <DHT.h>
#define BLYNK_PRINT Serial
char auth[] = "Your Blynk Auth Key";
char ssid[] = "Your WiFi SSID";
char pass[] = "Your WiFi Password";
#define DHTPIN 2
#define soilPin 4
#define gasPin A0
#define pirPin 12
int pirValue, soilValue, PIRpinValue, SOILpinValue;
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
BlynkTimer timer;
BLYNK_WRITE(V0) { PIRpinValue = param.asInt(); }
BLYNK_WRITE(V1) { SOILpinValue = param.asInt(); }
void sendSensor() {
int h = dht.readHumidity();
int t = dht.readTemperature();
if (isnan(h) || isnan(t)) { Serial.println("Failed to read from DHT sensor!"); return; }
Blynk.virtualWrite(V5, h);
Blynk.virtualWrite(V6, t);
}
void getPirValue() {
pirValue = digitalRead(pirPin);
if (pirValue) { Serial.println("Motion detected"); Blynk.notify("Motion detected"); }
}
void getSoilValue() {
soilValue = digitalRead(soilPin);
if (soilValue == HIGH) { Serial.println("Water Plants"); Blynk.notify("Water Plants"); }
}
void setup() {
Serial.begin(9600);
Blynk.begin(auth, ssid, pass);
dht.begin();
Blynk.tweet("OCTOPOD IS ONLINE!");
pinMode(pirPin, INPUT);
pinMode(soilPin, INPUT);
timer.setInterval(1000L, sendSensor);
}
void loop() {
Blynk.run(); timer.run();
if (PIRpinValue == HIGH) getPirValue();
if (SOILpinValue == HIGH) getSoilValue();
}
octopod_door.ino (Arduino Uno — RFID замок, без Bluetooth)
/***********************************************************************************************************
OCTOPOD: RFID DOOR LOCK — NO BLUETOOTH
Library: MFRC522
************************************************************************************************************/
#include <SPI.h>
#include <MFRC522.h>
#include <Servo.h>
#define SS_PIN 10
#define RST_PIN 9
#define LED_G 5
#define LED_R 4
#define BUZZER 2
MFRC522 mfrc522(SS_PIN, RST_PIN);
Servo myServo;
void setup() {
Serial.begin(9600);
SPI.begin();
mfrc522.PCD_Init();
myServo.attach(3);
myServo.write(0);
pinMode(LED_G, OUTPUT);
pinMode(LED_R, OUTPUT);
pinMode(BUZZER, OUTPUT);
noTone(BUZZER);
Serial.println("Put your card to the reader...");
}
void loop() {
if (!mfrc522.PICC_IsNewCardPresent()) return;
if (!mfrc522.PICC_ReadCardSerial()) return;
String content = "";
Serial.print("UID tag :");
for (byte i = 0; i < mfrc522.uid.size; i++) {
Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
Serial.print(mfrc522.uid.uidByte[i], HEX);
content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
content.concat(String(mfrc522.uid.uidByte[i], HEX));
}
Serial.println();
content.toUpperCase();
if (content.substring(1) == "XX XX XX XX") { // замените на ваш UID
Serial.println("Authorized access");
digitalWrite(LED_G, HIGH);
tone(BUZZER, 500); delay(300); noTone(BUZZER);
myServo.write(180); delay(5000); myServo.write(0);
digitalWrite(LED_G, LOW);
} else {
Serial.println(" Access denied");
digitalWrite(LED_R, HIGH);
tone(BUZZER, 300); delay(1000);
digitalWrite(LED_R, LOW); noTone(BUZZER);
}
}
octopod_door_bluetooth.ino (с Bluetooth HC-05)
/***********************************************************************************************************
OCTOPOD: RFID DOOR LOCK — BLUETOOTH VERSION
************************************************************************************************************/
#include <SoftwareSerial.h>
SoftwareSerial BTserial(0, 1); // RX | TX
#include <SPI.h>
#include <MFRC522.h>
#include <Servo.h>
#define SS_PIN 10
#define RST_PIN 9
#define LED_G 5
#define LED_R 4
#define BUZZER 2
MFRC522 mfrc522(SS_PIN, RST_PIN);
Servo myServo;
void setup() {
BTserial.begin(9600);
BTserial.println("Waiting for connections...");
SPI.begin();
mfrc522.PCD_Init();
myServo.attach(3);
myServo.write(0);
pinMode(LED_G, OUTPUT);
pinMode(LED_R, OUTPUT);
pinMode(BUZZER, OUTPUT);
noTone(BUZZER);
BTserial.println("Put your card to the reader...");
}
void loop() {
if (!mfrc522.PICC_IsNewCardPresent()) return;
if (!mfrc522.PICC_ReadCardSerial()) return;
String content = "";
BTserial.print("UID tag :");
for (byte i = 0; i < mfrc522.uid.size; i++) {
BTserial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
BTserial.print(mfrc522.uid.uidByte[i], HEX);
content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
content.concat(String(mfrc522.uid.uidByte[i], HEX));
}
BTserial.println();
content.toUpperCase();
if (content.substring(1) == "33 3E A7 E5" || content.substring(1) == "E5 36 6B 49") {
BTserial.println("Authorized access");
digitalWrite(LED_G, HIGH);
tone(BUZZER, 500); delay(300); noTone(BUZZER);
myServo.write(180); delay(5000); myServo.write(0);
digitalWrite(LED_G, LOW);
} else {
BTserial.println(" Access denied");
digitalWrite(LED_R, HIGH);
tone(BUZZER, 300); delay(1000);
digitalWrite(LED_R, LOW); noTone(BUZZER);
}
}
3D-модели и корпуса
- Базовый дизайн для картона/дерева:
octopod_v2_ukTmIJ0uMl.f3d - Готовый корпус для 3D-печати:
octo_2_v3_sii4tuCF7d.f3d
Схемы
Пиновка может отличаться для Arduino MKR 1010.
Для Bluetooth: Rx(HC-05)→Tx(Arduino), Tx(HC-05)→Rx(Arduino), 5V→5V, GND→GND.
ESP → MAX32620FTHR пины: AO → GPIO2 A1 → GPIO1 Soil Sensor → GPIO3 Gas Sensor (MQ2) → GPIO4 PIR Sensor → GPIO0 Relay 1 → M0 Relay 2 → M1
Производственный процесс
- Как технологии умного дома трансформируют повседневную жизнь
- Малвертайзинг угрожает умному дому IoT: скрытые рекламы могут скомпрометировать ваши устройства
- Создайте систему домашней автоматизации на Raspberry Pi для удаленного управления
- Умные шторы: автоматическое управление светом на Arduino с солнечной энергией
- Умная банка на ESP8266 + Arduino: мониторинг наполненности в реальном времени
- Умный дом и система безопасности на базе 1Sheeld
- Крестики-нолики на Arduino с матрицей MAX7219 и картонным корпусом
- Сборка надежного таймера обратного отсчета на Arduino с 7-сегментным дисплеем SparkFun
- WiFi-умный замок на Arduino и ESP8266 — открывание с телефона
- Промышленная автоматизация 4.0: революционизируем производственную эффективность