Цель проекта: смонтировать два контура освещения комнаты на втором этаже дома, при условии управления в ручном и автоматическом режиме, при минимальных затратах.
Планирование
В качестве датчика движения выбор пал на пироэлектрический инфракрасный сенсор HC-SR50, в первую очередь из-за большого угла обнаружения, порядка 120 градусов. Более подробно останавливаться на нем не будем, единственное о чем следует сказать так это то, что перемычка на сенсоре установлена в положение H. В этом режиме при каждом срабатывании сенсора на выходе остается логическая единица. По количеству сенсоров всё зависит от самой комнаты, в моём случае двух вполне достаточно.
Сигнал с сенсоров будет поступать на одно из двух реле в одном модуле, которое будет включать центральный контур освещения, но в ручном режиме будем управлять двумя реле. Одно отвечает за центральный, второе за периферийный контур.
Одним из условий автоматического управления будет проверка уровня освещенности вне помещения. Осуществлять это будем с помощью сенсора на основе микросхемы LM393.
Для управления в ручном режиме соберём маленькую плату с двумя тактовыми кнопками для удобства монтажа.
![](https://habrastorage.org/web/83a/102/1b7/83a1021b7b584e5081ce518511ace1bd.png)
Перемычка JD-Vсс — Vсс убирается, если на катушку реле будет подаваться отдельное питание, как я понял делается это для гальванической развязки. Для переключения реле необходимо входы IN1 или IN2 притягивать к земле.
![](https://habrastorage.org/web/8d1/a32/57b/8d1a3257b9784bd3b4b25df21f27d942.png)
Подготовка к монтажу
По питанию в моем распоряжение было только напряжение 220 переменного и 12 постоянного тока. Поэтому для питания самого контроллера, реле и сенсоров используется простая схема понижения напряжения до пяти вольт.
![](https://habrastorage.org/web/23d/85d/eb7/23d85deb7dea49b1ae60c549b2fd9b43.jpg)
Платы нарисованы в программе Sprint-Layout, довольно простые и по сути плата контроллера нужна для того чтобы удобно подключать сигналы.
Платы произведены всеми любимой технологией ЛУТ.
![](https://habrastorage.org/web/3f4/793/acc/3f4793acc6924dc0b7f6f27ac551dc26.jpg)
Для защиты сенсора освещения от света со стороны комнаты, чтобы предотвратить неправильную работу алгоритма скетча, принято решение спрятать его в отрезок полипропиленовой трубки. Отверстие в торце для возможности регулировки сенсора.
![](https://habrastorage.org/web/a1e/014/700/a1e01470026148fd8fcb2784dde3889d.jpg)
Составление скетча
// Проект автоматики освещения.
// Настройка пинов.
#define Sensor_1 10 // Пин первого сенсора НС-SR501.
#define Sensor_2 11 // Пин второго сенсора НС-SR501.
#define D0 3 // Пин датчика освещенности.
int Relay[2] = {8, 9}; // Пины реле.
int Button[2] = {5, 6}; // Пины кнопок.
// Переменные.
boolean Start_Sensor = false; // Переменная отражающая факт срабатывания датчика.
boolean relayEnabled[2] = {true, true}; // Состояние реле.
boolean buttonWasUp[2] = {true, true}; // Состояние кнопок.
unsigned long previousMillis = 0; /* Переменнтая для хранения
предыдущего времени срабатывания датчика. */
unsigned long activateTime; // Переменная для хранения времени срабатывания реле.
int value = 0; // Временная переменная для таймера.
// Константы.
const int T_hold = 10000; // Время удержания реле при отсутствии движения.
const int T_motion = 200; // Время от начала фиксирования движения до срабатывания реле.
void setup()
{
// Настройка пинов и их начальное состояние.
pinMode(D0, INPUT); // Датчик освещенности - вход.
for (int i = 0; i < 2; ++i)
{
pinMode(Relay[i], OUTPUT); // Реле - выходы.
pinMode(Button[i], INPUT_PULLUP); // Кнопки - входы с подтягивающим резистором.
digitalWrite(Relay[i], relayEnabled[i]); /* Начальное состояние реле высокое,
чтобы реле включилось необходимо подать низкий сигнал или минус. */
}
}
void loop()
{
if(digitalRead(D0)) // Считываем значение с датчика освещенности "Достаточно ли темно для автоматики?"
{
Sensor_Work();
if (relayEnabled[0] == true && Start_Sensor == true)
// Если состояние 1го реле высокое (отключено) и сработал один из датчиков.
{
relayEnabled[0] = false; // Изменить состояние реле на низкое (включено).
digitalWrite(Relay[0], relayEnabled[0]); // Включить первое реле.
activateTime = millis(); // Зафиксировать время включения реле.
while((millis() - activateTime) < T_hold)
{
// Задержка.
}
relayEnabled[0] = true; // Изменить состояние реле на высокое (отключено).
digitalWrite(Relay[0], relayEnabled[0]); // Отключить реле.
}
}
// Для определения клика сначала понимаем, отпущена ли кнопка прямо сейчас.
for (int i = 0; i < 2; ++i)
{
boolean buttonIsUp = digitalRead(Button[i]);
// Если кнопка была отпущена и (&&) нажата сейчас...
if (buttonWasUp[i] && !buttonIsUp)
{
/* может это клик, а может и ложный сигнал (дребезг), возникающий в
момент замыкания размыкания пластин кнопки, поэтому даем кнопке полностью
успокоиться */
delay(10);
// И снова считываем сигнал.
buttonIsUp = digitalRead(Button[i]);
if (!buttonIsUp)
{
// Если она все еще нажата...
relayEnabled[i] = !relayEnabled[i]; // меняем состояние сигнала на противоположный.
digitalWrite(Relay[i], relayEnabled[i]); // Включаем то реле сквитированной кнопки.
}
}
// Запоминаем последнее состояние кнопки для новой итерации.
buttonWasUp[i] = buttonIsUp;
}
}
void Sensor_Work() // Процедура опроса сенсоров.
{
if (digitalRead(Sensor_1) == HIGH || digitalRead(Sensor_2) == HIGH) /* Если один из
датчиков зафиксировал движение. */
{
// Запустить таймер.
if (millis() - previousMillis > T_motion)
{
previousMillis = millis();
value++;
}
}
else
{
Start_Sensor = false; // Возвращение в исходное состояние факта срабатывания.
value = 0;
}
if(value >= 10)
{
Start_Sensor = true; // Факт срабатывания датчика.
value = 0;
}
}
Монтаж
Датчики спрятаны в небольшую пластиковую коробку.
![](https://habrastorage.org/web/395/ba0/20c/395ba020c72d413eb09b40bc41cba2c2.jpg)
Все кабели, за исключением ответвлений к сенсорам, спрятаны в пластиковые короба.
![](https://habrastorage.org/web/389/953/b8a/389953b8af984641ac99ce8cd3ba4281.jpg)
Вид смонтированного центрального щита.
![](https://habrastorage.org/web/baf/717/6a2/baf7176a20b841e2bcc6a6f5b6a0472f.jpg)
![](https://habrastorage.org/web/f1f/690/fa7/f1f690fa74b3424eb35d457966238985.jpg)
Итог
Получившийся проект удовлетворил поставленную цель, как при работе в автоматическом режиме, например при кратковременном нахождении в комнате, так и в ручном режиме при постоянном нахождении в комнате при отсутствии движения.
Во время работы автоматики не было замечено каких-либо отказов, замечаний.
Комплектация
Контроллер Arduino Pro Mini Atmega 328 5 В 16 МГц | 1 |
Пироэлектрический инфракрасный сенсор HC-SR501 | 2 |
Сенсор освещенности на микросхеме LM393 | 1 |
Стабилизатор напряжения L7805CV | 1 |
Конденсатор керамический 0,33 мкФ | 1 |
Конденсатор керамический 0,1 мкФ | 1 |
Гнездо на плату PBS 1?40 2.54 | 1 |
Переключатель SWD1-1 | 2 |
Клеммник винтовой двухконтактный | 9 |
Стеклотекстолит 61?46 мм | 1 |
Стеклотекстолит 40?20 мм | 1 |
Тактовая кнопка | 2 |
Текстолит | 1 |
Люминесцентный светильник Camelion WL-4002, 16 Вт | 12 |
Потолочный светильник с двумя лампами накаливания | 1 |
Распределительная коробка | 8 |
Кабель ПУНП 2?2.5 | |
Кабель телефонный ШТЛП-4 0,12?7 | |
Кабель канал (различных размеров) | |
Расходники (термоклей, клей Момент Кристалл, припой, канифоль, флюс ТАГС, наконечники) | |
Крепежные элементы (болты, гайки, саморезы, дюбеля, хомуты) |
Ссылки:
Автоматическая подсветка лестницы
Комментарии (16)
telobezumnoe
14.07.2017 08:25можно программно реализовать, на пример если темно есть движение и свет был выключен, то вкл свет, если свет включен и есть движение то свет продолжает гореть несмотря на показания фоторезиста, нет движения свет выключать через пару минут. у себя планирую три режима, ручной, автоматический и полуавтомат, когда просто гасится свет, если нет движения в течении на пример десяти минут, включать его надо снова вручную. режимы переключать через mqtt, как и состояние вкл выкл.
Ungla
14.07.2017 10:25+1Приятно смотреть на исполнение. А то большинство проектов на ардуино больше всего напоминает паучков.
AndrewFe
14.07.2017 19:30+1Я не особо сведущ в электронике, но почему не сделать контроль по двум фотоэлементам, расположенным последовательно, со счетчиком входящих/выходящих человеков?
Там, по сути, ширины любого дверного проема (или толщины?) хватит. Достаточно 20-и сантиметров что бы исключить ошибки.R1on
14.07.2017 19:42Да вы абсолютно правы, такая реализация тоже возможна. Правда в этом проекте этому мешает конструкция входа на второй этаж.
CreFroD
14.07.2017 19:30+1Сам тоже собираюсь реализовать что-то подобное. Но зачем использовать Sprint-Layout, когда есть бесплатная версия EAGLE, DipTrace, KiCAD, CircuitMaker?
R1on
14.07.2017 19:33Конечно, можно использовать выше вами перечисленные программы, тут просто платы весьма простые и достаточно средств Sprint-Layout.
romualdinio
14.07.2017 19:32Надо было сразу на этом контроллере и пожарную сигнализацию делать, раз ПУЭ пренебрегаете )))
MisterSmith
14.07.2017 19:33Ардуино и мигание светом — пора уже заканчивать, уже все и так всё поняли, интересно было на первой, десятой, но уже не на сто первой статье…
R1on
14.07.2017 19:37пора уже заканчивать… переселяться в избу и жечь парафиновые свечи… В чем то я с вами соглашусь идей уже много, как в прочем и статей, но реально доведенных до конца проектов маловато встречается.
mitgard
14.07.2017 19:33А зачем так странно конвертировать питание с 12В до 5В?
Alexeyslav
17.07.2017 11:04Очень даже классический вариант. На многих ардуиновских платках именно такой вариант, но у мелких стабилизаторов ограниченная нагрузочная способность. В варианте с 12В на 5В при токе выше 20мА уже надо применять стабилизаторы в TO220 и с радиатором(можно конечно варианты с DPAK но крепить к ним радиатор ещё то удовольствие), если хотите чтобы он работал надёжно и в летнюю жару.
Alexeyslav
17.07.2017 10:02+1И всё-таки алгоритм непонятен.
Зачем регулировать сенсоры освещённости прямо на самих сенсорах? У ардуины есть аналоговые входы, их можно завести прямо туда а «регулировку» порогов производить чисто программно и/или при помощи заведённых тут же на другие аналоговые входы потенциометров или кнопками в цифровом виде или через блютуз-модуль с ноутбука.
Там же программно компенсировать вероятную засветку от тех же ламп освещения(состояние освещения знаем, величину засветки измерить и ввести в виде поправки) заодно осуществить контроль перегорания ламп(освещение включили а засветка меньше обычного).
Ещё из идей — использовать рассеивающую линзу от фонарика на фотодатчик чтобы увеличить площадь обзора и уменьшить влияние локального затенения от пролетающих насекомых или птиц.
Да, код не смотрел но есть ли защита от слишком частого переключения реле? чтобы оно не дёргалось каждую секунду изнашивая лампы в случае помех(электрических или оптических) на датчиках. Гистерезис на пороги срабатывания это одно, а защита от дёргания должна быть независимо.
R1on
17.07.2017 20:53Изначально, контроль освещенности задумывалось осуществлять за счет схемы делителя напряжения с фоторезистором и как вы говорите сигнал из этого делителя заводить на аналоговый вход Arduino и программно, методом сравнения с константой, регулировать порог освещенности. Но от этого отказались из-за того, что пришлось бы делать еще одну небольшую схемку, что не оправдывает затраты и время на изготовление. Готовый же сенсор на микросхеме LM393 стоит каких то 25 р. и то сути только подключить останется.
R1on
17.07.2017 20:56и по поводу реле, да замечание отличное, можно допилить немного код, добавить например счетчик времени, чтобы избежать дребезг самого реле.
MPaul
Нда… а поставить обычный выключатель в параллель к обычному датчику движения не проще?
И кстати зачем проверять освещенность СНАРУЖИ комнаты? Если снаружи сияет солнце, а в комнате глаз выколи — свет включать не нужно?