Основа для розумної кімнати, або як Arduino в гуртожитку живе

    
І знову привіт, Хаброжітелі! Щодня читаючи Хабр, я не раз натрапляв на статті про Arduino і DIY проектах на його основі. Варто зауважити, що з електронікою я справ не мав, а весь мій досвід полягав у відвідуванні радіогуртку на базі підліткового клубу «Вогник» (м. Петрозаводськ) Одного разу я зібрався і вирішив зробити на Arduino браслет з сенсорами (температура, тиск, пульс) для смартфона (зв'язок по BT) Але зробивши помилку при замовленні, я отримав лише сам Arduino і датчик тиску. Щоб протестувати плату я відправився в найближчий магазин радіодеталей за світлодіодами, і там на очі мені попався магнітний датчик закриття дверей. Він наштовхнув мене на думку, що можна було б трохи вдосконалити життя в кімнаті (не плутати з квартирою). Не витрачаючи час, я оформив на Ali замовлення з купою сенсорів і Arduino Mega.
  
Після замовлення джентльменського набору сенсорів (температура, вологість, реле, StarterKit, BT, годинник, дальнометр, IR датчик) я вирішив пошукати як інші представляють розумний будинок. Більшість обмежувалося: управлінням люстрами і теплими підлогами, хоча були й реально круті статті . Частина функцій, звичайних для квартир, в кімнаті були просто зайвими: наприклад, датчик витоку газу або протечки. Я вирішив сам скласти функціонал, необхідний в розумній кімнаті:
 
 
     
  • Управління світлом
  •  
  • Контроль температури
  •  
  • Управління безліччю способів
  •  
  • Управління дверима
  •  
  • Моніторинг температури
  •  
  • Моніторинг погоди
  •  
 
Виявилося, що всі необхідні сенсори вже замовлені і залишається тільки чекати. І ось все сенсори прийшли!
  
 

Перший крок

Коли ти вже помігают світлодіодами і вирішив зібрати розумний будинок, логічним кроком було б моргнути світлом у кімнаті, але рання спека змусила зайнятися контролем температури. Для початку я просто спробував підключити dht11 з StarterKita. Що може бути простіше, якщо в інтернеті повно інструкцій? Як виявилося, для підключення dht11 є безліч бібліотек і не всі вони сумісні з останніми версіями IDE, але через пару годин я милувався температурою виведеної в консоль, а ще через пару хвилин світлодіодом, миготливим в залежності від неї. (Відключити датчик, покласти в холодильник, дістати з холодильника, підключити ...)
 
Першою ж проблемою стала низька точність обраного dht11: він брехав на 2-3 градуси в обидві сторони — довелося його замінити (після цього я намагаюся замовляти датчики в кількох варіантах).
 
Потім я вирушив до LeroyMerlin і придбав там найпростіший вентилятор . Після декількох хвилин метушні з проводами і виделкою вентилятор був зібраний. Разом з сусідом зняли кватирку і встановили його (вентилятор, що не сусіда) на звільнене місце. Ми встромили вилку в розетку і… Вентилятор почав обертатися. Повільно. Дуже повільно.
Чи варто говорити, що ми неправильно встановили вилку, а вентилятор обертався від вітру?
 
 
 
Звичайно, доступно ручне відключення струму. Але як же краще управляти вентилятором через реле? Підключити безпосередньо до вентилятора? Я вирішив підключити вентилятор до реле через розетку: це надає гнучкість системі (можна замінити вентилятор на що-небудь інше).
  
 

Тестування вентиляції

І ось код переписаний зі світлодіода на реле. Прошивка завантажена, я моніторю температуру в очікуванні необхідної для старту — і ось він той момент! Реле клацає, а COM-порт пропадає. Мабуть, в момент перемикання навантаження на USB збільшується і йде перешкода даними. Спочатку я думав, що це за перешкод від 220В проводів, але вони знаходяться на достатній відстані від плати. У наслідку це доставило мені чимало проблем: при спроби залити новий скетч, Arduino йде в ребут, перемикає реле і тим самим виносить COM-порт, а, значить, і процес оновлення. Я так і не зміг побороти цю проблему.
  
 

Управління з пульта

Звичайно, постійна робота вентилятора незабаром набридла, а вимикати його через вимикач було не круто! Тому я дістав Starter Kit і пульт ДУ звідти. Власне з цього моменту і почалися проблеми: я поняття не мав, як виглядає приймач. Але кілька хвилин гугленія допомогли мені знайти його, а ще через годину я вже весело керував вентилятором з пульта.
 
Спочатку це був складний алгоритм з кількома прапорами, але в підсумку я прийшов до невеликого алгоритмом з таймером Якщо (прийшов сигнал) {
время_ручного_управленія = 1800;
режім_вентілятора =! режім_вентілятора;
}
Якщо (время_ручного_управленія! = 0) {
время_ручного_управленія -;
} Інакше {
Якщо (температура <26) {
режім_вентілятора = false;
} Інакше {
режім_вентілятора = true;
}
}
Але і тут без проблем не обійшлося: оновлюючи дроти, я подав 5V на DATA і дуже швидко позбувся приймача. Це і підштовхнуло мене до наступного кроку…
  
 

Управління через BT модуль

Незабаром я підключив BT модуль HC-06, перенаправив висновок туди і додав зчитування команд. Думав, що буде набагато складніше, але спасибі статті з robocraft.
 
 Вийшло
 
  
 

Сусід і вентилятор

Я думав, що навчивши сусіда управляти системою із смартфона, я вирішу проблему «Ей, мені холодно», але… Якщо відключення живлення вентилятора через вимикач я міг стерпіти, але закриття кватирки мене просто виводило з себе. Чому? Вентилятор дув у скло на відстані кількох сантиметрів і моторошно гудів. На щастя, у мене завалялися магнітні датчики, які й спонукали мене на створення системи. Замкнуте датчик сигналізує Arduino про те, що вентилятор не можна включати. На жаль, іноді йшли перешкоди, тому довелося зробити найпростішу перевірку: якщо сигнал про закриття приходить кілька разів поспіль — кватирка дійсно закрита.
 
 
  
 

Управління світлом

Тепер можна було взятися за управління світлом. Після вентилятора вже нічого складного: короб, пара клемників — і світ вже управляється через Arduino (звичайно, з можливістю відключення через старий вимикач). Єдине, що хвилює це те, що реле є не кращим способом для управління лампочками .
  
 

Проблеми зі звуком

Ну яке ж управління світлом без хлопків? Мною був замовлений мікрофон. Так я думав… Пам'ятайте про недосвідченість? Насправді я замовив детектор звуку з налаштуванням порога. Начебто годиться для моєї мети? Але з'явилася пара «але»:
 
 
     
  • Маленький радіус дії: хлопки обробляються тільки з десятка сантиметрів
  •  
  • Мала тривалість подачі сигналу: при великому часі виконанні коду сигнал з датчика просто не встигав зафіксуватися Arduino
  •  
  
 

Повернення пульта

Невелике гугленіе, похід в магазин — і замість згорілого VS1838B я придбав більш надійний TSOP1836. Цього разу установка пройшла успішно і все запрацювало відразу.
 
 
  
 

Вихід на вулицю

З вікном розібрався, але що за ним? Озброївшись паяльником, я припаяв до п'ятиметровому VGA кабелю датчик дощу і ще один dht11. Трохи U-образних кріплень, чорної ізоляційної стрічки, моху і система виходить на бойове чергування.
 
 
 
А ще я дізнався, що можна виводити російський текст.
 
 Стало
 
  
 

Трохи зручності

Здається, що смартфон завжди під рукою, але поки знайдеш, поки підключиш… Іноді швидше вимкнути світло або вентилятор через вимикач, але це позбавляє можливість управління через Arduino (імпульсні реле занадто дорогі), тому я додав дві звичайні кнопки.
  
 

Трохи безпеки

Куди без пожежної сигналізації в общаге технарів? За недосвідченість, я придбав датчик вогню, а не диму. Визначення палаючого сірника на відстані до 30 см — це, звичайно, круто, але недостатньо. Тому поки обійшовся без цього.
 
 До слова про пожежної сигналізації в гуртожитку…
 
     
  • Динамік, з якого іноді лунає сирена або хрип мерця
  •  
  • Локальний датчик диму

  •  
  • Мережевий датчик диму (підключений до пульта охорони)
  •  

  
 

Загальний вигляд

 
 
У розміщення на корпусі комп'ютера є величезний недолік: можливість викликати коротке замикання. Тож невдовзі плата переїде на особисту полку, а замість картонки буде саморобний корпус з кейса для HDD.
  
 

Код скетчу

 Поточний стан # include <IRremote.h>
# Include <IRremoteInt.h>
# Include <DS1302.h>
# Include <DHT.h>
# Define DHT_PIN 2 / / пін градусника…
# Define DHT2_PIN 52 / / пін вуличного градусника…
# Define RAIN_PIN 53 / / пін датчика дощу
# Define RECV_PIN 3 / / пін підключення IR приймача
# Define FAN_PIN 4 / / пін підключення реле
# Define LAMP_PIN 5 / / пін підключення реле
# Define SOUND_PIN A0 / / пін підключення мікрофону
# Define WINDOW_PIN A1 / / пін вікна
  
# Define LAMP_BUT_PIN 50 / / пін підключення мікрофону
# Define FAN_BUT_PIN 51 / / пін вікна
  
  
# Define DHTTYPE DHT11
  
# Define TIMER_FAN 0
# Define TIMER_WINDOW 1
  
  
IRrecv irrecv (RECV_PIN);
decode_results results;
int timers [2];
bool FAN_FLAG = false;
bool LAMP_FLAG = true;
int WINDOW_VAL = 0;
  
bool WINDOW_OPEN = false;
bool WINDOW_FLAG = false;
bool RAIN_FLAG = false;
  
char incomingByte;
  
DHT dht (DHT_PIN, DHTTYPE);
DHT dht2 (DHT2_PIN, DHTTYPE);
  
DS1302 rtc (49, 46, 48);
void setup () {
 Serial1.begin (9600);
  
 rtc.halt (false);
 rtc.writeProtect (false);
 / / Rtc.setDOW (SUNDAY); / / Set Day-of-Week to FRIDAY
 / / Rtc.setTime (0, 37, 40); / / Set the time to 0:37:00 (24hr format)
 / / Rtc.setDate (25, 5, 2014); / / Set the date to 25 травня
  
 timers [TIMER_FAN] = 0;
 timers [TIMER_WINDOW] = 0;
  
 pinMode (RAIN_PIN, INPUT);
 pinMode (LAMP_BUT_PIN, INPUT);
 pinMode (FAN_BUT_PIN, INPUT);
  
 pinMode (FAN_PIN, OUTPUT);
 pinMode (LAMP_PIN, OUTPUT);
  
 digitalWrite (FAN_PIN, LOW);
 irrecv.enableIRIn (); / / Включаємо ресівер
  
 dht.begin ();
 dht2.begin ();
}
 int volume;
void loop () {
WINDOW_VAL = analogRead (WINDOW_PIN); / / Магнітний датчик
if (WINDOW_VAL> 950) {
if (WINDOW_FLAG) {
timers [TIMER_WINDOW] + +;
if (timers [TIMER_WINDOW]> 10) {
WINDOW_OPEN = false;
}
} Else {
WINDOW_FLAG = true;
}
} Else {
WINDOW_OPEN = true;
WINDOW_FLAG = false;
timers [TIMER_WINDOW] = 0;
}
  
if (digitalRead (RAIN_PIN) == HIGH) {
 RAIN_FLAG = true;
} Else {
 RAIN_FLAG = false;
}
  
volume = analogRead (SOUND_PIN);
 if (volume <40) {
LAMP_FLAG =! LAMP_FLAG;
 }
  
  
 if (digitalRead (LAMP_BUT_PIN) == HIGH) {
 input_signal (1);
 }
 if (digitalRead (FAN_BUT_PIN) == HIGH) {
input_signal (0);
 }
  
 if (irrecv.decode (& results))
 {
 if (results.value == 16750695) / / Код кнопки
 {
 input_signal (0);
 }
 if (results.value == 16756815) / / Код кнопки
 {
 input_signal (1);
 }
 irrecv.resume (); / / Отримуємо таке значення
 }
/ / Serial.println (rtc.getTime (). Hour);
/ / Serial.println (rtc.getTime (). Min);
Serial1.print (rtc.getDOWStr ());
Serial1.print ("");
Serial1.print (rtc.getDateStr ());
Serial1.print ("-");
Serial1.println (rtc.getTimeStr ());
  
 if (Serial1.available ()> 0) {
 incomingByte = Serial1.read ();
 if (incomingByte == '0 ') {
 Serial1.println («Ручний режим деактивований»);
 input_signal (0);
 } Else if (incomingByte == '1 ') {
 Serial1.println («Ручний режим активований»);
 input_signal (0);
 } Else if (incomingByte == '2 ') {
 input_signal (1);
 }
 }
  
 float h = dht.readHumidity ();
 float t = dht.readTemperature ();
  
 if (isnan (t) | | isnan (h)) {
 Serial1.println («Помилка читання з внутрішнього термометра»);
 } Else {
 if (timers [TIMER_FAN] <= 0) {
 if (t <26) {
 FAN_FLAG = false;
 } Else if (t> 26) {
 FAN_FLAG = true;
 }
 } Else {
 timers [TIMER_FAN] -;
 }
 Serial1.print («Вологість:");
 Serial1.print (h);
 Serial1.println ("% \ t»);
 Serial1.print («Температура:");
 Serial1.print (t);
 Serial1.println ("* C»);
 }
  
  
 if (timers [TIMER_FAN]> 0) {
 Serial1.print («ручному режимі залишилося працювати:");
 Serial1.print (timers [TIMER_FAN]);
 Serial1.println ("сек.»);
 } Else {
 Serial1.println («Ручний режим вимкнений»);
 }
 if (FAN_FLAG && WINDOW_OPEN) {
 digitalWrite (FAN_PIN, HIGH);
 Serial1.println («Вентилятор включений»);
} Else {
 digitalWrite (FAN_PIN, LOW);
 Serial1.println («Вентилятор вимкнений»);
 }
  
 if (WINDOW_OPEN) {
 Serial1.println («Вікно відкрито»);
 } Else {
 Serial1.println («Вікно закрито»);
 }
  
  
 if (LAMP_FLAG) {
 digitalWrite (LAMP_PIN, HIGH);
 } Else {
 digitalWrite (LAMP_PIN, LOW);
 }
  
  
 h = dht2.readHumidity ();
 t = dht2.readTemperature ();
 Serial1.println («За вікном:»);
 if (isnan (t) | | isnan (h)) {
 Serial1.println («Помилка читання з вуличного термометра»);
 } Else {
 Serial1.print («Вологість:");
 Serial1.print (h);
 Serial1.println ("% \ t»);
 Serial1.print («Температура:");
 Serial1.print (t);
 Serial1.println ("* C»);
 }
 if (RAIN_FLAG) {
 Serial1.println («Дощу немає»);
 } Else {
 Serial1.println («Дощ»);
 }
  
 Serial1.println ("*****");
 delay (100);
}
  
void input_signal (int signal) {
 switch (signal) {
 case 0:
 if (rtc.getTime (). hour> 1 && rtc.getTime (). hour <8) {
 timers [TIMER_FAN] = 1800;
 } Else {
 timers [TIMER_FAN] = 18000;
 }
 FAN_FLAG =! FAN_FLAG;
  
 Serial1.println («Вентилятор переключено»);
 break;
 case 1:
 LAMP_FLAG =! LAMP_FLAG;
 Serial1.println («Світло переключено»);
 break;
 }
}
 
 

А що, якщо в коді збій

Я використовую нормальнозамкнутое реле. Тобто за замовчуванням все включено: можна відключити Arduino від мережі і використовувати прості вимикачі.
  
 

Плани з розвитку

Те, що я перерахував, є лише основою для дійсно розумній кімнати. Адже всі її AI — це включення і відключення вентилятора, залежно від температоруи. Я планую наступне, щоб зробити кімнату більш зручною і «автономної».
  
 
Будильник
Після додавання годин в систему наступний на черзі будильник. Як сигнал я припускаю: пьезопіщалку, моргання світла і включення вентилятора. Ну і звичайно, раннє пробудження, якщо на вулиці дощ (-10 до швидкості пересування).
 
Додати систему збереження будильників на SD картку з допомогою такого модуля (на випадок збоїв в харчуванні).
  
 
Додаток на комп'ютер і смартфон + віджети
Який же розумний будинок без управління зі смартфона або комп'ютера?
 
Припускаю приблизно таку схему:
 
 
 
Чому не Wi-Fi? Занадто дорого.
  
 
Вивести Arduino власне живлення
Думаю, що коментарі зайві: небезпека випалити USB і постійні перешкоди для інших пристроїв. Крім того, хочу перенести харчування з плати на спеціальний адаптер.
  
 
Управління роутером через розетку
Старий добрий Asus RT56U дуже любить грітися, особливо влітку. Тому хочу зробити автоматичне відключення на пару годин вночі, щоб давати йому охолонути.
  
 
Додати моніторинг присутності
Зараз у мене є кілька старих добрих піроелектричних інфрачервоних датчиків і пара ультразвукових датчика відстані. Цього може вистачити для найпростішого контролю присутності.
 
У кімнаті проживають дві людини. Кожен має по чотири стани:
 
 
     
  • За комп'ютером
  •  
  • Варто
  •  
  • Лежить на ліжку
  •  
  • Відсутня
  •  
 
Інфрачервоні датчики визначають присутність в кімнаті, а ультразвукові наявність в зонах (ліжко / стіл) і моніторять кількість увійшли / вийшли.
 
Це дозволить реалізувати найпростіші сценарії:
 
 
     
  • Я прийшов увечері і сусід не спить: включити світло
  •  
  • Всі вийшли: вимкнути світло
  •  
  • Всі лягли і не рухаються: вимкнути світло
  •  
  
 
Додати світлочутливий резистор
Класика жанру: автоматичне включення світла, якщо в кімнаті хтось в зонах «За комп'ютером», а в кімнаті темно.
  
 
Додати електромеханічний замок і доводчик
Не знаю, як вам, а мені весь час лінь шукати ключі, тому я дуже хочу встановити електромеханічний замок укупі зі зчитувачем проксіміті карт або <a href="http://ru.aliexpress.com/wholesale?SearchText=arduino+отпечатки+пальцев&catId=&initiative_id=SB_20140528082732">датчиком відбитків пальців . Вхід в гуртожиток здійснюється за допомогою електронних перепусток — частота мені відома, і я можу легко замовити зчитувач для Arduino, але карти дуже легко клонувати (у мене в самого є пристрій для цього), тому, коли прийде час, швидше за все, зупинюся на відбитках пальців.
  
Сусід часто виходить на кухню / туалет / ванну і не закриває двері. Я сиджу навпроти входу і мені не подобається, що кожен, хто проходить повз, бачить мої труси споглядає диспозицію в кімнаті. Керований доводчик став би прекрасним рішенням для таких ситуацій.
  
 
проапгрейдить кватирку
Як я вже писав, якщо температура вище певної межі, включається вентилятор. Але що, якщо в кімнаті нікого немає, а температура вже нижче 20-ти? Хотілося б додати в систему відкриття / закриття кватирки. Можливо, це будуть прості моторчики + волосінь.
 
Відомо, якщо охолодити лампочку і включити її, з великою часткою ймовірності вона вибухне. Таким чином, це також побереже нерви і лампочки.
 
 лампочка, яка не дожила до системи контролю температури
  
 
Замінити DHT11
Як я вже писав, я не розбираюся в сенсорах і т.п. Тому я купив перші-ліпші датчики температури: dht11. Зараз я хочу замінити їх на dht22 для кімнати і dht21 для вулиці. У dht22 менша похибка, а dht21 має підтримку негативних температур і захищений корпус, що актуально для вулиці. Вуличний dht11 вже іноді почав губитися.
 
 
Додати електричний диммер
Дуже хочеться плавно регулювати рівень освітлення в кімнаті. Якби у мене не було розумної кімнати, я б купив і повісив простий диммер, але зараз хочеться диммер, який може існувати в рамках поточної системи. На мій жаль, я не зміг знайти диммер для 220В, регульований 5В. Все, що поки зміг придумати — це простий диммер + приєднаний до нього моторчик.
  
 
Голосове управління
До поточних способам управління хотілося б додати голосове. Благо, існують системи зразок цієї . Звичайно, голосова реакція теж була б в тему, але це прості динаміки.
  
 

Посилання на придбані сенсори

   
 

Післямова

Думаю, що вийде написати нову статтю по завершенні частини планів, а поки я просто мрію про електромеханічному замку і готуюся до сесії.
 
Хороших наступаючих вихідних: проведіть їх з користю!
    
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.