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

Цель проекта: смонтировать два контура освещения комнаты на втором этаже дома, при условии управления в ручном и автоматическом режиме, при минимальных затратах.

Планирование


В качестве датчика движения выбор пал на пироэлектрический инфракрасный сенсор HC-SR50, в первую очередь из-за большого угла обнаружения, порядка 120 градусов. Более подробно останавливаться на нем не будем, единственное о чем следует сказать так это то, что перемычка на сенсоре установлена в положение H. В этом режиме при каждом срабатывании сенсора на выходе остается логическая единица. По количеству сенсоров всё зависит от самой комнаты, в моём случае двух вполне достаточно.

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

Одним из условий автоматического управления будет проверка уровня освещенности вне помещения. Осуществлять это будем с помощью сенсора на основе микросхемы LM393.

Для управления в ручном режиме соберём маленькую плату с двумя тактовыми кнопками для удобства монтажа.



Перемычка JD-Vсс — Vсс убирается, если на катушку реле будет подаваться отдельное питание, как я понял делается это для гальванической развязки. Для переключения реле необходимо входы IN1 или IN2 притягивать к земле.



Подготовка к монтажу


По питанию в моем распоряжение было только напряжение 220 переменного и 12 постоянного тока. Поэтому для питания самого контроллера, реле и сенсоров используется простая схема понижения напряжения до пяти вольт.



Платы нарисованы в программе Sprint-Layout, довольно простые и по сути плата контроллера нужна для того чтобы удобно подключать сигналы.





Платы произведены всеми любимой технологией ЛУТ.



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



Составление скетча


Скетч
// Проект автоматики освещения.
// Настройка пинов.
#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;
}
}

Монтаж


Датчики спрятаны в небольшую пластиковую коробку.



Все кабели, за исключением ответвлений к сенсорам, спрятаны в пластиковые короба.



Вид смонтированного центрального щита.





Итог


Получившийся проект удовлетворил поставленную цель, как при работе в автоматическом режиме, например при кратковременном нахождении в комнате, так и в ручном режиме при постоянном нахождении в комнате при отсутствии движения.

Во время работы автоматики не было замечено каких-либо отказов, замечаний.


Комплектация


Контроллер 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)


  1. MPaul
    14.07.2017 06:48

    Нда… а поставить обычный выключатель в параллель к обычному датчику движения не проще?
    И кстати зачем проверять освещенность СНАРУЖИ комнаты? Если снаружи сияет солнце, а в комнате глаз выколи — свет включать не нужно?


  1. Dmitry_5
    14.07.2017 07:43

    И наоборот, ночью не всегда надо включать освещение


  1. telobezumnoe
    14.07.2017 08:25

    можно программно реализовать, на пример если темно есть движение и свет был выключен, то вкл свет, если свет включен и есть движение то свет продолжает гореть несмотря на показания фоторезиста, нет движения свет выключать через пару минут. у себя планирую три режима, ручной, автоматический и полуавтомат, когда просто гасится свет, если нет движения в течении на пример десяти минут, включать его надо снова вручную. режимы переключать через mqtt, как и состояние вкл выкл.


  1. Ungla
    14.07.2017 10:25
    +1

    Приятно смотреть на исполнение. А то большинство проектов на ардуино больше всего напоминает паучков.


  1. AndrewFe
    14.07.2017 19:30
    +1

    Я не особо сведущ в электронике, но почему не сделать контроль по двум фотоэлементам, расположенным последовательно, со счетчиком входящих/выходящих человеков?
    Там, по сути, ширины любого дверного проема (или толщины?) хватит. Достаточно 20-и сантиметров что бы исключить ошибки.


    1. R1on
      14.07.2017 19:42

      Да вы абсолютно правы, такая реализация тоже возможна. Правда в этом проекте этому мешает конструкция входа на второй этаж.


  1. CreFroD
    14.07.2017 19:30
    +1

    Сам тоже собираюсь реализовать что-то подобное. Но зачем использовать Sprint-Layout, когда есть бесплатная версия EAGLE, DipTrace, KiCAD, CircuitMaker?


    1. R1on
      14.07.2017 19:33

      Конечно, можно использовать выше вами перечисленные программы, тут просто платы весьма простые и достаточно средств Sprint-Layout.


  1. romualdinio
    14.07.2017 19:32

    Надо было сразу на этом контроллере и пожарную сигнализацию делать, раз ПУЭ пренебрегаете )))


  1. MisterSmith
    14.07.2017 19:33

    Ардуино и мигание светом — пора уже заканчивать, уже все и так всё поняли, интересно было на первой, десятой, но уже не на сто первой статье…


    1. R1on
      14.07.2017 19:37

      пора уже заканчивать… переселяться в избу и жечь парафиновые свечи… В чем то я с вами соглашусь идей уже много, как в прочем и статей, но реально доведенных до конца проектов маловато встречается.


  1. mitgard
    14.07.2017 19:33

    А зачем так странно конвертировать питание с 12В до 5В?


    1. Alexeyslav
      17.07.2017 11:04

      Очень даже классический вариант. На многих ардуиновских платках именно такой вариант, но у мелких стабилизаторов ограниченная нагрузочная способность. В варианте с 12В на 5В при токе выше 20мА уже надо применять стабилизаторы в TO220 и с радиатором(можно конечно варианты с DPAK но крепить к ним радиатор ещё то удовольствие), если хотите чтобы он работал надёжно и в летнюю жару.


  1. Alexeyslav
    17.07.2017 10:02
    +1

    И всё-таки алгоритм непонятен.
    Зачем регулировать сенсоры освещённости прямо на самих сенсорах? У ардуины есть аналоговые входы, их можно завести прямо туда а «регулировку» порогов производить чисто программно и/или при помощи заведённых тут же на другие аналоговые входы потенциометров или кнопками в цифровом виде или через блютуз-модуль с ноутбука.
    Там же программно компенсировать вероятную засветку от тех же ламп освещения(состояние освещения знаем, величину засветки измерить и ввести в виде поправки) заодно осуществить контроль перегорания ламп(освещение включили а засветка меньше обычного).
    Ещё из идей — использовать рассеивающую линзу от фонарика на фотодатчик чтобы увеличить площадь обзора и уменьшить влияние локального затенения от пролетающих насекомых или птиц.
    Да, код не смотрел но есть ли защита от слишком частого переключения реле? чтобы оно не дёргалось каждую секунду изнашивая лампы в случае помех(электрических или оптических) на датчиках. Гистерезис на пороги срабатывания это одно, а защита от дёргания должна быть независимо.


  1. R1on
    17.07.2017 20:53

    Изначально, контроль освещенности задумывалось осуществлять за счет схемы делителя напряжения с фоторезистором и как вы говорите сигнал из этого делителя заводить на аналоговый вход Arduino и программно, методом сравнения с константой, регулировать порог освещенности. Но от этого отказались из-за того, что пришлось бы делать еще одну небольшую схемку, что не оправдывает затраты и время на изготовление. Готовый же сенсор на микросхеме LM393 стоит каких то 25 р. и то сути только подключить останется.


    1. R1on
      17.07.2017 20:56

      и по поводу реле, да замечание отличное, можно допилить немного код, добавить например счетчик времени, чтобы избежать дребезг самого реле.