Товары из Китая

Обучаемый IR-контроллер для управления двумя группами светильников


Обучаемый IR-контроллер для управления двумя группами светильников

Эта конструкция выходного карантинного дня своими корнями уходит в мои публикации 4-х летней давности. Ну а поводом к написанию стало появившееся, благодаря карантину, время и желание все-же поделиться с народом архиполезной (как показало время) штукой.

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

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

Обучаемый IR-контроллер для управления двумя группами светильников

За снятой клавишей, ровно под ее красным окошком, виден IR-приемник моего контроллера, построенного на Arduino. А сам контроллер с реле и блоком питания находится в выдолбленной в стене нише под выключателем.

За все время использования я несколько раз знакомил выключатель с новыми пультами, поскольку обзавелся проектором и ТВ-боксами. И для этого мне не пришлось даже вставать с дивана. Мое ноу-хау позволяет это делать, не напрягаясь. Об этом ниже.

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

Схема невероятно простая, повторить ее сможет любой, умеющий держать паяльник, а вот результат будет радовать долгие-долгие годы. Детали также стоят копейки на том-же Али. Собрать-же можно, как и я, просто на макетке. Весь функционал контроллера в программе, но я ее выкладываю здесь в исходных кодах в свободное использование. Требование только одно — упоминание авторства при ее использовании на других ресурсах.

Схема:

Обучаемый IR-контроллер для управления двумя группами светильников

Скетч:


// Klop 2020
#include <IRremote.h>
#include <EEPROM2.h>
#define led 13 // светодиод
#define speaker 9 // плюс пищалки
#define RECV_PIN 5 // нога на IRDA приемник
#define DP1 6 // нога на реле 1
#define DP2 7 // нога на реле 2
#define VIK1 2 // нога на выключатель 1
#define VIK2 3 // нога на выключатель 2
#define maxstack 8 // размер стека-1
#define maxbut 40 // максимум запомненных кнопок
byte maxpults;
IRrecv irrecv(RECV_PIN);
decode_results results;
unsigned long butt[maxbut];
unsigned long buttstack[maxstack+1];
bool VikState[]={false, false};
bool sost[]={true,true};
bool flaglearn = false;
byte DP[]={DP1, DP2};
byte VIK[]={VIK1, VIK2};
//------------------------------------------------------------
void setup()
{
irrecv.enableIRIn(); // Старт ресивера IRDA
pinMode(DP1, OUTPUT); // выход на реле 1
pinMode(DP2, OUTPUT); // выход на реле 2
pinMode(VIK1, INPUT); // вход выключателя 1
pinMode(VIK2, INPUT); // вход выключателя 1
VikState[0]=digitalRead(VIK1);
VikState[1]=digitalRead(VIK2);
digitalWrite(DP1, HIGH); // зависит от реле!!! При необходимости заменить на LOW
digitalWrite(DP2, HIGH); // зависит от реле!!! При необходимости заменить на LOW
pinMode(speaker, OUTPUT);
pinMode(led, OUTPUT);
digitalWrite(led, LOW); // гасим светодиод
for (maxpults=0;maxpults<maxbut;maxpults++)
{EEPROM_read(maxpults*4, butt[maxpults]); // читаем значения пультов
if (butt[maxpults]==0) break;
}
}
//------------------------------------------------------------
void ChangeRelay(byte n)
{
sost[n]=!sost[n];
digitalWrite(DP[n],sost[n]);
}
//------------------------------------------------------------
void mybeep(byte n) // звук, n - число пиков
{
for (byte i=0;i<n;i++)
{analogWrite(speaker,150);
delay(100);
analogWrite(speaker,0);
delay(50);
}
}
//------------------------------------------------------------
void IFVIKSTATE()
{
for (byte i=0;i<2;i++)
{
if (VikState[i] != digitalRead(VIK[i])) // если изменилось состояние кнопки выключателя
{ ChangeRelay(i);
VikState[i]=!VikState[i];
delay(800);
}
}
}
//------------------------------------------------------------
void iflearn(unsigned long code) // проверка на включение режима обучения
{
for (byte i=0;i<maxstack;i++) // суем в стек LIFO код клавиши
buttstack[maxstack-i]=buttstack[maxstack-i-1];
buttstack[0]=code;
//если в стеке последовательность 3-х разных кнопок 3 раза, то переход в режим программирования
if ((buttstack[0]==buttstack[3]) && (buttstack[0]==buttstack[6])
&& (buttstack[1]==buttstack[4]) && (buttstack[1]==buttstack[7])
&& (buttstack[2]==buttstack[5]) && (buttstack[2]==buttstack[8]) && (buttstack[0]!=buttstack[1])
&& (buttstack[0]!=buttstack[2]) && (buttstack[1]!=buttstack[2]))
{ // переход в режим программирования
digitalWrite(led, HIGH);
mybeep(1);
flaglearn=true;
for (byte i=0;i<maxstack+1;i++) // чистим стек
buttstack[i]=0;
maxpults=0;
}
}
//------------------------------------------------------------
void IFPULTS()
{
if (irrecv.decode(&results))
{ if (flaglearn) { // если флаг обучения взведен, входим в режим обучения пульта
if ((maxpults>0) && (results.value==butt[maxpults-1]) || (maxpults==maxbut))
{ // режим обучения отключаем при дублировании последней кнопки
flaglearn=false;
digitalWrite(led, LOW);
mybeep(5);
butt[maxpults]=0;
for (byte i=0;i<=maxpults;i++) // записываем коды в EEPROM
EEPROM_write(i*4, butt[i]);
} else
{ for (byte i=0;i<maxpults-1;i++) // был ли такой код ранее?
if (butt[i]==results.value) goto m1;
butt[maxpults]=results.value; // такого кода ранее не было
maxpults++;
mybeep(maxpults%2+1);
}
} else
{ // обычный режим ловли кода кнопки пульта
iflearn(results.value);
for (byte i=0;i<maxpults;i++) // сравним полученный код с каждым из пультов
{ if (results.value==butt[i])
{ ChangeRelay(i%2); // если код совпал, переключаем соответствующее реле
break; // и выходим из цикла
}
}
}
m1:
delay(400); // убираем дребезг
irrecv.resume();
}
}
//------------------------------------------------------------
void loop()
{
IFVIKSTATE(); // проверяем выключатели
IFPULTS(); // проверяем пульты
}

Библиотеки IRremote.h и EEPROM2.h легко гуглятся на github.com. Разумеется, еще понадобится элементарный навык работы с Ардуино, но таких руководств на youtube сегодня пруд пруди.

Опишу работу.

Для знакомства контроллера с новыми пультами я применяю придуманный мной способ, который я назвал «виртуальный цифровой замок» и использовал еще 4 года назад. Для этого я, к примеру, беру любой пульт и последовательно нажимаю на нем три любые клавиши с интервалом не менее полсекунды. Затем повторяю эту операцию еще два раза. Это и есть код входа в режим обучения, в реальной жизни случайно так сделать практически невозможно (шифр можно изменить, изменив код программы).

В данной реализации зажжется светодиод на плате Ардуино и пищалка пискнет один раз. Один раз — это значит, что контроллер ждет нажатия кнопки на пульте, которая будет управлять первой группой светильников. После нажатия кнопки, контроллер запомнит этот код и пикнет два раза. Это, понятно, означает, что следует нажать другую кнопку, которая будет управлять второй группой светильников. После этого контроллер пискнет снова один раз. Значит можно программировать аналогичным образом и второй пульт. И так до 20 пультов. Но если этот пульт последний, то после 1 пика следует еще раз нажать последнюю нажатую клавишу. Тогда контроллер пискнет 5 раз, запишет все введенные коды во внутреннюю постоянную память, погасит светодиод и выйдет из режима обучения.

Процесс работы наглядно показан в видео:

Что понадобится купить:

Обучаемый IR-контроллер для управления двумя группами светильников

Еще, для питания контроллера, конечно потребуется БП на 5V и возможность его запитать в месте расположения. Как раз с этим может возникнуть проблема, если проводка уже разведена и в месте расположения контроллера нет фазы или ноля. Конечно, для таких гуру электроники как Ksiman это не проблема, он и в прошлый раз показал как это сделать, но я в этом откровенно слаб и не рискую делать то, чего не понимаю.

Я использую такие БП:

Обучаемый IR-контроллер для управления двумя группами светильников

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

Следует упомянуть такой момент. Если вдруг в наше отсутствие отключили свет, а потом включили. Как поведет себя эта конструкция? В этом случае реле встанут в положение «Выключено» и свет будет выключен.

На этом я заканчиваю, надеюсь, что ничего не упустил. А если упустил — спрашивайте, постараюсь ответить на все вопросы и дополнить статью.

Всем здоровья и с пользой провести свалившееся на нас карантинное время!


СМОТРИ ТАКЖЕ

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *