Использование данной статьи возможно только после личного разрешения автора.
Программирование Alpha SE на примере демонстрационного стенда.
Приведенная ниже статья предназначена для начинающих интеграторов систем домашней автоматизации и знакомит с основами программирования контроллера Alpha SE.
В качестве объекта автоматизации будем использовать совсем небольшой виртуальный объект - демонстрационный стенд, приведенный ниже.
При автоматизации любого объекта – квартира, дом или наш стенд, прежде всего следует определить круг задач, решаемый контроллером.
Исходя из того, что самой привлекательной областью демонстрации возможностей умного дома является освещение, остановимся именно на нем.
Продемонстрировать возможность управления эл. клапанами воды и газа можно, но висящие железки вряд ли смогут произвести на посетителей хоть какое-то впечатление.
И так, перечислим функции, которые постараемся реализовать на стенде:
- Управление освещением от настенных выключателей,
- Кнопки «Выключить все». Лучше их разместить несколько что бы показать, что выключить весь свет квартиры можно не только из прихожей, но и из спальни, гостиной, детской,
- Кнопка «Я пришел». Ранее ни в одной статье эта функция не описывалась, но оказалась достаточно удобной. Функция «Я пришел» используется в тот момент, когда человек только вошел в дом. Нажатие одной кнопки позволит сразу включить несколько групп освещения и, например, стереосистему,
- Функция «Имитация присутствия» реализуется с использованием того же освещения, о ней уже много раз говорилось в моих предыдущих статьях и поэтому ее описание здесь будет опущено,
- Функция «Паника» используется совместно с охранной сигнализацией и выглядит следующим образом – при срабатывании сигнализации все освещение в квартире начинает мигать с частотой один раз в секунду. В реальной жизни в купе с работающей сиреной «охранки» смотрится очень впечатляюще. Если злоумышленник не ожидает ничего подобного, то есть вероятность, что приехавшим на место преступления сотрудникам милиции на обратном пути придется заехать в аптеку за валидолом для горе преступника. :-),
- Естественно, что упускать возможность демонстрации работы «умного» стенда с сенсорной панели непозволительно. Разместим ее рядом со стендом. Управление чем-либо материальным с экрана монитора всегда впечатляет неготовых к таким фокусам посетителей.
С задачами разобрались, необходимо определить состав оборудования. Нам потребуется:
- Контроллер Alpha SE 1 шт. - именно он будет управлять всем,
- SE8i8or (аналог SECU16) c высоковольтными выходными реле,
- Блок бесперебойного питания: СКАТ 12В 4,5А 1 шт.,
- Автоматический выключатель на 5А 1 шт.,
- Витая пара UTP4 CAT5 10 м,
- ШВВП 10 м,
- Щиток,
- Выключатели, светильники и сам стенд с нанесенным изображением.
Схема коммутации оборудования будет иметь следующий вид:
Сборку оборудования по схеме следует производить только при отключенном питании 220 и 12В. После сборки оборудования и контрольной проверки можно включить питание стенда и приступить к настройке оборудования.
Процесс настройки оборудования автоматизации состоит из 2 этапов - адресация модулей и программирование контроллера. Обе процедуры производятся с помощью программного обеспечения Alpha SE Configurator. О программной адресации модулей написано достаточно много и подробно как в статьях, так и в документации к самому контроллеру. В связи с тем, что исполнительный модуль всего один о нумерации модулей задумываться не придется – присвоим ему адрес 1.
С этого момента начинается, на мой взгляд, самая увлекательная часть – разработка программы для контроллера.
При программировании контроллера доступно 256 переменных. Для того чтобы не запоминать какие из них уже используются рекомендую выписывать все используемые переменные в порядке возрастания в начале программы с указанием места применения.
В нашей программе блок описания переменных будет выглядеть следующим образом:
#var[0] Если 1, значит необходимо выключить все
#var[1] Если 1, значит необходимо отработать макрос "Я пришел"
#var[2] Если 1, значит включен режим ПАНИКА
#var[3] Если 1, значит имитируем присутствие
#var[5] Служебная для имитации присутствия
#var[6] Служебная для имитации присутствия
#var[7] Служебная для имитации присутствия
#var[8] Служебная для имитации присутствия
#var[9] Служебная для режима паника
#Состояния выходных реле
var[10]=Get_Points_State(1,8);
var[11]=Get_Points_State(1,9);
var[12]=Get_Points_State(1,10); # Гостиная 1
var[13]=Get_Points_State(1,11); # Гостиная 2
var[14]=Get_Points_State(1,12); # Спальня
var[15]=Get_Points_State(1,13); # Детская
var[16]=Get_Points_State(1,14); # Ванная
var[17]=Get_Points_State(1,15); # Прихожая
#var[19] Служебная для режима паника
# Состояние выключателей
var[20]=Get_Points_State(1,0); # Выключить все
var[21]=Get_Points_State(1,1); # Я пришел
var[22]=Get_Points_State(1,2); # Гостиная 1
var[23]=Get_Points_State(1,3); # Гостиная 2
var[24]=Get_Points_State(1,4); # Спальня
var[25]=Get_Points_State(1,5); # Детская
var[26]=Get_Points_State(1,6); # Ванная
var[27]=Get_Points_State(1,7); # Прихожая
Написание программы начнем с алгоритма «Выключить все».
В связи с тем, что выключение всего освещения следует производить только после нажатия кнопки выключателя, необходимо отследить это событие. Состояние первого выключателя хранится в переменной 20. Пока кнопка не нажата в переменной 20 будет храниться значение 0, при нажатии – 1.
Самый простой способ отработать алгоритм «Выключить все» - дождаться 1 в переменной 20.
if (var[20]$==1)
{
#Выключить весь свет.
}
Отметим отдельно, что сравнение переменной с 1 мы производим, используя оператор '$==', а не '=='. В чем же отличия между ними? Условие 'if (var[20] ==1)' будет истинно всегда, пока нажата кнопка «Выключить все». Т.е. Если мы нажмем кнопку и будем ее удерживать, на каждом программном цикле контроллер будет выполнять описанные нами действия. Что излишне, в связи с тем, что все освещение будет отключено уже на первом программном цикле. Условие 'if (var[20] $==1)' будет истинно только на первом цикле программы после нажатия.
Разомкнуть все выходы на блоке SE 8i8or за один раз позволит команда Set_Relays_State(1,2,0), которая имеет 2 параметра: номер модуля получателя, битовая маска, определяющая состояние выходов. Сама функция возвращает 0 в случае успешного выполнения или любое другое число в случае провала.
Остановимся подробнее на битовой маске. Самой маленькой единицей измерения в компьютере может быть 1 бит. Бит может принимать всего 2 значения: 1 или 0, заметим, что выходное реле модуля SECU так же может иметь всего 2 состояния: замкнуто, разомкнуто. Один байт состоит из 8 бит, блок SE 8i8or имеет 8 выходов. Думаете это просто совпадение? :)
Байт может принимать значения от 0 до 255. Разберемся в представлении байтов в виде битов:
Байт
|
Представление байта в виде битов
|
0
|
00000000
|
1
|
00000001
|
2
|
00000010
|
3
|
00000011
|
...
|
...
|
255
|
11111111
|
Теперь ясно?
Если совместить биты байта и выходы реле, то получим, что каждому реле соответствует свой бит:
0 – все реле разомкнуты,
1 – замкнуто только 1 реле,
2 – замкнуто только 2 реле,
3 – замкнуты только 1 и 2 реле,
...
255 – замкнуты все реле.
Узнать о соответствии битов выходным реле можно используя конвертор, включенный в окно редактора программы.
На этом обзор по битовым маскам будем считать законченным.
Думаю, что с этого момента должно быть понятно, что при передаче в функцию Set_Relays_State битовой маски 0 все реле разомкнуться, а 255 – замкнутся.
И так наша программа, отрабатывающая алгоритм «Выключить все» при нажатии кнопки будет представлена следующим кодом:
if (var[20]$==1)
{
var[254]=Set_Relays_State(1,2,0);
}
В переменную 254 сохранится результат выполнения операции размыкания всех реле.
Но как нам отработать этот же алгоритм с помощью сенсорной панели? Можно конечно на событие нажатия кнопки сенсорной панели назначить отправку команды var[254]=Set_Relays_State(1,2,0), но этот путь далеко не идеален и вот почему – допустим через некоторое время появится еще один блок SE8i8or и тогда Вам придется снова переписывать как программный код контроллера, так и сенсорной панели, т.е. постоянно следить за идентичностью алгоритмов сенсорной панели и контроллера. Во-вторых программа контроллера выполняется в десятки раз быстрее, чем команды поступающие от CPU-XA Server сенсорной панели. Как же тогда поступить? Ответ очень прост. Нам требуется вынести алгоритм «Выключить все» в отдельный программный блок. Допустим, вот так:
if (var[0]==1) # Отрабатываем алгоритм "Выключить все"
{
var[254]=Set_Relays_State(1,2,0); # Отправляем команду модулю SE 8i8or выключить все
var[0]=0;
};
Теперь для отработки алгоритма «Выключить все» любым образом нужно изменить значение переменной 0 на 1. Данную процедуру можно производить и из текста самой программы, и с помощью сенсорной панели. После отработки алгоритма значение переменной снова изменится на 0.
Модернизированный код приведен ниже:
if (var[20] $==1) # Если нажали кнопку "Выключить все"
{
var[0]=1; # Включаем признак того, что необходимо отработать алгоритм "Выключить все"
};
if (var[0]==1) # Отрабатываем алгоритм "Выключить все"
{
var[254]=Set_Relays_State(1,2,0); # Отправляем команду модулю SE 8i8or выключить все
var[0]=0;
};
Кнопка «Я пришел» будет обрабатываться аналогичным способом. По этой причине мы пропустим детальное описание алгоритма.
При изменении состояния входа блока SE 8i8or контроллер определяет новое положение выключателя и если тот замкнулся значит контроллер замыкает реле, если разомкнулся – размыкает реле.
Кнопочный выключатель аналогичен кнопке звонка – пока кнопку держим пальцем контакт замкнут, убираем палец – контакт размыкается.
if (var[22] $==1) # Отработка алгоритма кнопочного выключателя
{
var[255]=!var[12];
var[254]=Set_Relay_State(1,10,var[255]);
};
Приведем код программы для отработки всех выключателей:
# Начало блока отработки алгоритма выключателей
if (var[22] $==1) # Отработка алгоритма кнопочного выключателя
{
var[255]=!var[12];
var[254]=Set_Relay_State(1,10,var[255]);
};
if (var[23] $==1) # Отработка алгоритма кнопочного выключателя
{
var[255]=!var[13];
var[254]=Set_Relay_State(1,11,var[255]);
};
if (var[24] $==1) # Отработка алгоритма кнопочного выключателя
{
var[255]=!var[14];
var[254]=Set_Relay_State(1,12,var[255]);
};
if (var[25] $==1) # Отработка алгоритма кнопочного выключателя
{
var[255]=!var[15];
var[254]=Set_Relay_State(1,13,var[255]);
};
if (var[26] $==1) # Отработка алгоритма кнопочного выключателя
{
var[255]=!var[16];
var[254]=Set_Relay_State(1,14,var[255]);
};
if (var[27] $==1) # Отработка алгоритма кнопочного выключателя
{
var[255]=!var[17];
var[254]=Set_Relay_State(1,15,var[255]);
};
Если Вы поняли приведенный код программы, то можно сделать паузу и немного отдохнуть.
Gереходим к рассмотрению оставшегося программного кода, а точнее двух алгоритмов - «Имитации присутствия» и «Паника».
Начнем, пожалуй, со второго, т.к. он намного проще первого. Идея заключается в том, что при включении режима «Паника» мы запускаем таймер и на каждую четную секунду отправляем команду включить весь свет, а на нечетную – выключить.
if (var[2]==1) # Если флаг режима паники включен
{
if(var[9]==0) # Если таймер не запущен
{
var[255]=StartTimer(9,1); # Запускаем таймер
};
var[19]=var[9]%2; # Определяем четность значения таймера
if(var[19]==0) # Если значение четное
{
var[254]=Set_Relays_State(1,2,255); # Включаем весь свет
}
else
{
var[254]=Set_Relays_State(1,2,0); # Выключаем весь свет
};
}
else # Если флаг режима "Паника" опущен
{
if (var[9]!=0) # Если таймер идет
{
var[255]=StopTimer(9); # Останавливаем таймер
};
};
Из текста программы видно, что включить режим «Паника» можно изменив значение переменной 2, а точнее присвоив ей единицу. Но как только переменной 2 будет присвоено любое другое число таймер будет остановлен. Вычисление четности значения таймера производится вычислением переменной 19, а именно получением остатка от деления значения таймера на 2.
Для реализации режима «Паника» нам потребовались всего 3 переменные. Учитывая, что в первой версии контроллера их доступно 256, можно считать, что эта функция досталась практически даром.
Алгоритм имитации присутствия немного сложнее. Для лучшего понимания кода априорно оговорим весь алгоритм.
За включение режима имитации присутствия будет отвечать всего одна переменная, как и во всех предыдущих алгоритмах.
Для начала потребуется выбрать произвольное реле над которым будем производить процедуру включения или выключения, далее определим его текущее состояние. Если контроллер будет включать уже включенное реле, толку будет не много. Естественно, что следующим шагом будет выполнение операции включения (выключения) реле. Остается реализовать задержку по времени между операциями. Думаю, метод которым мы будем пользоваться вы поймете увидев код.
if (var[3]==1) # Если включили флаг отработки алгоритма имитации присутствия
{
var[255]=var[5]==0; # Если таймер не запущен
var[254]=var[5]>var[6]; # Если значение таймера = времени задержки
if (var[254]||var[255]) # Если оба условия выполняются
{
var[7]=Random(5); # Выбираем реле над которым будет производится действие
var[7]=var[7]+10; # Т.к. первые 2 реле не используются управляем точками с 10 по 15
var[8]=Get_Points_State(1,var[7]); # Получаем информацию о текущем состоянии выбранного реле
var[8]=!var[8]; # Меняем значение на противоположное
var[254]=Set_Relay_State(1,var[7],var[8]); # Передаем команду на изменение состояния выбранного реле
var[6]=Random(5); # Определяем период бездействия
var[6]=var[6]+2;
var[255]=StartTimer(5,1); # Запускаем таймер
};
}
else # Если флаг имитации присутствия выключен
{
if (var[5]!=0) # Если таймер не остановлен
{
var[255]=StopTimer(5); # Останавливаем таймер
};
};
На этом месте мы можем остановиться. Материал получился не из легких и перегружать его описанием процесса написания программы для сенсорной панели не следует. Учитывая тот факт, что разработке ПО для сенсорных панелей уже посвящено несколько статей можно оставить этот немаловажную процедуру на совесть читателя.
Полный текст демонстрационной программы.
Автор: Быков Виктор Сергеевич
E-mail: info@smart-elec.ru
Сайт: https://smart-elec.ru
|