20 февраля 2021
Система, которая будет открывать и закрывать жалюзи во время рассвета и заката, а также включать и выключать свет в темное время суток.
Борисов Алексей, Razumdom, 20 февраля 2021
1. Задача.
Требуется создать систему, которая будет открывать и закрывать жалюзи во время рассвета и заката, а также включать и выключать подсветку.Время включения и выключения светильника задано таблицей c годовым графиком, который предоставил заказчик.
№ | Временной период | Отключение | Включение |
1 | 1.01 - 15.01 | 9:02 | 16:58 |
2 | 16.01- 31.01 | 8:53 | 17:18 |
3 | 1.02 - 14.02 | 8:33 | 17:46 |
4 | 15.02 - 28.02 | 8:08 | 18:11 |
5 | 1.03 - 15.03 | 7:39 | 18:46 |
6 | 16.03 - 31.03 | 7:05 | 19:02 |
7 | 1.04 - 15.04 | 6:30 | 19:30 |
8 | 16.04 - 30.04 | 5:56 | 19:54 |
9 | 1.05 - 15.05 | 5:26 | 20:19 |
10 | 16.05 - 31.05 | 5:01 | 20:43 |
11 | 1.06 - 15.06 | 4:43 | 21:04 |
12 | 16.06 - 30.06 | 4:42 | 21:15 |
13 | 1.07 - 15.07 | 4:57 | 21:06 |
14 | 16.07 - 31.07 | 5:19 | 20:45 |
15 | 1.08 - 15.08 | 5:42 | 20:18 |
16 | 16.08 - 31.08 | 6:08 | 19:44 |
17 | 1.09 - 15.09 | 6:31 | 19:09 |
18 | 16.09 - 30.09 | 6:56 | 18:35 |
19 | 1.10 - 15.10 | 7:21 | 18:02 |
20 | 16.10 - 31.10 | 7:48 | 17:30 |
21 | 1.11 - 15.11 | 8:15 | 17:06 |
22 | 16.11 - 30.11 | 8:38 | 16:50 |
23 | 1.12 - 15.12 | 8:55 | 16:47 |
24 | 16.12 - 31.12 | 9:01 | 16:56 |
Время открытия и закрытия жалюзи задано таблицей.
№ | Временной период | Открытие | Закрытие |
1 | 1.01 - 15.01 | 9:02; 15:58 | 10:02; 16:58 |
2 | 16.01- 31.01 | 8:53; 16:18 | 9:53; 17:18 |
3 | 1.02 - 14.02 | 8:33; 16:46 | 9:33; 17:46; |
4 | 15.02 - 28.02 | 8:08; 17:11 | 9:08; 18:11 |
5 | 1.03 - 15.03 | 7:39; 17:46 | 8:39; 18:46 |
6 | 16.03 - 31.03 | 7:05; 18:02 | 8:05; 19:02 |
7 | 1.04 - 15.04 | 6:30; 18:30 | 7:30; 19:30 |
8 | 16.04 - 30.04 | 5:56; 18:54 | 6:56; 19:54 |
9 | 1.05 - 15.05 | 5:26; 19:19 | 6:26; 20:19 |
10 | 16.05 - 31.05 | 5:01; 19:43 | 6:01; 20:43 |
11 | 1.06 - 15.06 | 4:43; 20:04 | 5:43; 21:04 |
12 | 16.06 - 30.06 | 4:42; 20:15 | 5:42;21:15 |
13 | 1.07 - 15.07 | 4:57; 20:06 | 5:57; 21:06 |
14 | 16.07 - 31.07 | 5:19; 19:45 | 6:19; 20:45 |
15 | 1.08 - 15.08 | 5:42; 19:18 | 6:42; 20:18 |
16 | 16.08 - 31.08 | 6:08; 18:44 | 7:08; 19:44 |
17 | 1.09 - 15.09 | 6:31; 18:09 | 7:31; 19:09 |
18 | 16.09 - 30.09 | 6:56; 17:35 | 7:56; 18:35 |
19 | 1.10 - 15.10 | 7:21; 17:02 | 8:21; 18:02 |
20 | 16.10 - 31.10 | 7:48; 16:30 | 8:48; 17:30 |
21 | 1.11 - 15.11 | 8:15; 16:06 | 9:15; 17:06 |
22 | 16.11 - 30.11 | 8:38; 15:50 | 9:38; 16:50 |
23 | 1.12 - 15.12 | 8:55; 15:47 | 9:55; 16:47 |
24 | 16.12 - 31.12 | 9:01;15:56 | 10:01; 16:56 |
Реализовывать алгоритм будем на модуле DRM88ER.
К каналу реле 1 подключена кнопка для открытия жалюзи.
К каналу реле 2 подключена кнопка для закрытия жалюзи.
К каналу реле 8 подключена светодиодная подсветка.
Этот же алгоритм можно реализовать и на других модулях, например, DRM88R, DDL84R и других, т.к. сценарии во всех модулях практически одинаковые.
2. Решение
Если пойти прямым путем, сделать условия IF для каждого времени, даты и каждой строчки, то это займет очень много строк в программе и выделенной для этого памяти может не хватить.Поэтому будем использовать сжатый алгоритм сценария. Вместо чисто условной логики будем использовать арифметическую логику работы.
Вместо проверки условия для каждой строчки сделаем расчет номера этой строчки. Вместо логической проверки времени выполнения команды сделаем расчет этого времени.
В регистрах IR20 - IR999 находятся ячейки ОЗУ, которые используются как переменные для расчетов.
Диапазон данных в этих переменных может быть типа int -32768 +32767 целое со знаком.
Алгоритм работы будет выглядеть следующим образом:
Рассчитываем цикл работы, т.е. номер строчки в нашей таблице
0: IR33 = IR9006 * 30; текущее значение месяца умножаем на 30
1: IR33 = IR33 – 15; вычитаем из полученного значения 15
2: IR34 = IR33 + IR9004; прибавляем к значению текущий день
3: IR35 = IR34 / 15; делим это значение на 15
Получили номер цикла в диапазоне от 1 до 25, записанный в регистр IR35
Преобразуем время в минуты. Далее все расчеты будут производиться в минутах (1-1439), а не в часах и минутах как обычно принято.
5: IR36 = IR9008 * 60; умножаем часы на 60 получаем минуты
6: IR37 = IR36 + IR9009; прибавляем минуты
Получили текущее время в минутах в диапазоне от 0 до 1439, записанный в регистр IR37
Теперь нужно текущее время в минутах сравнить с данными из таблицы. Для этого прописать каждое значение времени условиями IF.
Это займет достаточно много строк в программе.
Но есть вариант получше, это рассчитать время рассвета и заката.
3. Расчет графика восхода и заката
График восхода и заката выглядит так:Формула расчета восхода выглядит так:
Источник Википедия
Но я упростил формулу расчета и оставил только COS() и коэффициенты смещения функции вверх и вправо. Эти коэффициенты зависят от местоположения населенного пункта и смещения часового пояса.
Формула получилась упрощенная, приблизительная, но для нашей задачи этой точности вполне достаточно.
Значение времени в минутах для рассвета рассчитываем по формуле:
Время = 130 * COS(2 * π / 25 * (номер цикла в году + смещение))+420
2 * π / 25 = 0.251 - это круг, деленный на количество наших циклов 25 и умножаем это значение на 1000, т.к. тригонометрия в модуле пишется целыми числами в тысячных долях. Такой же получаем и результат в тысячных долях, который нужно будет потом разделить на 1000. Номер цикла тоже нужно смещать с учетом того, что световой цикл начинается 22 декабря, а не 1 января.
Сравним полученный результат с данными из таблицы.
№ | Отключение | Минуты | Расчетное значение | Включение | Минуты | Расчетное значение |
1 | 9:02 | 542 | 546 | 16:58 | 1018 | 1014 |
2 | 8:53 | 533 | 533 | 17:18 | 1038 | 1027 |
3 | 8:33 | 513 | 512 | 17:46 | 1066 | 1048 |
4 | 8:08 | 488 | 485 | 18:11 | 1091 | 1075 |
5 | 7:39 | 459 | 454 | 18:46 | 1126 | 1106 |
6 | 7:05 | 425 | 420 | 19:02 | 1142 | 1140 |
7 | 6:30 | 390 | 386 | 19:30 | 1170 | 1174 |
8 | 5:56 | 356 | 355 | 19:54 | 1194 | 1205 |
9 | 5:26 | 326 | 328 | 20:19 | 1219 | 1232 |
10 | 5:01 | 301 | 307 | 20:43 | 1243 | 1253 |
11 | 4:43 | 283 | 294 | 21:04 | 1264 | 1266 |
12 | 4:42 | 282 | 290 | 21:15 | 1275 | 1270 |
13 | 4:57 | 297 | 295 | 21:06 | 1266 | 1265 |
14 | 5:19 | 319 | 308 | 20:45 | 1245 | 1252 |
15 | 5:42 | 342 | 328 | 20:18 | 1218 | 1232 |
16 | 6:08 | 368 | 355 | 19:44 | 1184 | 1205 |
17 | 6:31 | 391 | 387 | 19:09 | 1149 | 1173 |
18 | 6:56 | 416 | 420 | 18:35 | 1115 | 1140 |
19 | 7:21 | 441 | 454 | 18:02 | 1082 | 1106 |
20 | 7:48 | 468 | 485 | 17:30 | 1050 | 1075 |
21 | 8:15 | 495 | 512 | 17:06 | 1026 | 1048 |
22 | 8:38 | 518 | 533 | 16:50 | 1010 | 1027 |
23 | 8:55 | 535 | 546 | 16:47 | 1007 | 1014 |
24 | 9:01 | 541 | 550 | 16:56 | 1016 | 1010 |
Значения расходятся, но разница очень незначительная.
Теперь напишем пример сценария расчета этого времени.
7: IR25 = 251 * IR35
8: IR25 = COS (IR25)
9: IR25 = IR25 * 13
10: IR25 = IR25 / 100
11: IR32 = IR25 + 420
Рассчитали время рассвета в минутах и записали в регистр IR32
Теперь рассчитываем время заката по формуле: Время = 1440 - (время рассвета) + 120
1440 это количество минут в сутках, 120 время, зависящее от местоположения города.
12: IR31 = 1560 - IR32
Получили время заката и записали в регистр IR31
Можно узнать точное время рассвета и заката
Значение берем с сайта: api.sunrise-sunset.org
Координата: Широта, Latitude, lat - (North, N - South, S):
Координата: Долгота, Longitude, lng - (West, W - East, E):
По умолчанию указаны координаты для Тулы.
Дата для расчета времени:
Часовой пояс:
Для Москвы эти коэффициенты будут другие:
Время = 159 * COS(2 * π / 365 * (номер дня в году + 9))+381
2 * π / 365 = 0.0172142 - это круг, деленный на количество дней. Прибавление 9 дней - это смещение, т.к. зимнее солнцестояние 21 декабря.
Расчетный график и реальный график восхода солнца для Москвы все равно расходится. Вероятно учитываются дополнительные параметры, например, снежный покров.
4. Управление подсветкой
13: IF(IR37 = IR32) THEN COIL8 = 0; однократноЕсли текущее время равно времени рассвета, тогда отключить подсветку.
14: IF(IR37 = IR31) THEN COIL8 = 1; однократно
Если текущее время равно времени заката, тогда включить подсветку.
Теперь вторая часть задачи - это управление жалюзи. Для управления используется два временных промежутка.
Рассчитываем дополнительное время открывания и закрывания жалюзи.
15: IR30 = IR31 - 60
16: IR29 = IR32 + 60
Посчитали дополнительное время и записали в регистры IR30 и IR29.
Включаем реле открытия и запускаем таймер на 5 секунд. Секунды задаются с точностью 0,1.
17: IF(IR37 = IR32) THEN COIL1 = 1; однократно
18: IF(IR37 = IR32) THEN TIMER1 = 50; однократно
19: IF(IR37 = IR30) THEN COIL1 = 1; однократно
20: IF(IR37 = IR30) THEN TIMER1 = 50; однократно
Включили реле открытия жалюзи.
21: IF(TIMER1 = 1) THEN COIL1 = 0; однократно
Через 5 сек выключили реле.
Включаем реле закрытия и запускаем таймер на 5 секунд. Секунды задаются с точностью 0,1.
22: IF(IR37 = IR29) THEN COIL2 = 1; однократно
23: IF(IR37 = IR29) THEN TIMER1 = 50; однократно
24: IF(IR37 = IR31) THEN COIL2 = 1; однократно
25: IF(IR37 = IR31) THEN TIMER1 = 50; однократно
Включили реле закрытия.
26: IF(TIMER1 = 1) THEN COIL2 = 0; однократно
Через 5 сек выключили реле.
5. Использование таймера
Можно уменьшить количество строк, использовав таймер.1) При наступлении условия устанавливаем таймер на значение 5.1 секунды.
2) При значении таймера = 5.0 секунды включаем реле.
3) При значении таймера = 0.1 секунды выключаем реле.
4) При значении таймера = 0 секунд таймер останавливается и его значение остается нулевым постоянно.
17: IF(IR37 = IR32) THEN TIMER1 = 51; однократно
18: IF(IR37 = IR30) THEN TIMER1 = 51; однократно
19: IF(TIMER1 = 50) THEN COIL1 = 1; однократно
20: IF(TIMER1 = 1) THEN COIL1 = 0; однократно
Через 5 сек выключили реле.
Включаем реле закрытия и запускаем таймер на 5 секунд. Секунды задаются с точностью 0,1.
21: IF(IR37 = IR29) THEN TIMER2 = 51; однократно
22: IF(IR37 = IR31) THEN TIMER2 = 51; однократно
23: IF(TIMER2 = 50) THEN COIL2 = 1; однократно
24: IF(TIMER2 = 1) THEN COIL2 = 0; однократно
Условия можно сделать не только логическими действиями, но и арифметическими. Например, Если IR37 = IR32, то разность между этими значениями будет равна нулю.
17: IR40 = IR37 - IR32
18: IR41 = IR37 - IR30
19: IF(IR40 = 0) OR (IR41 = 0) THEN TIMER2 = 51
20: IF(TIMER1 = 50) THEN COIL1 = 1; однократно
21: IF(TIMER1 = 1) THEN COIL1 = 0; однократно
Правда в этом случае строк получилось больше.
Алгоритм будет выполняться в течении всего года. В следующем году цикл алгоритма начнется заново.
6. Расчет на большее количество циклов в году
Выше был описан пример на 24 цикла, меняющийся два раза в месяц.Теперь сделаем количество циклов 365 и рассчитаем время на каждый день.
Расчет номера дня в году довольно сложный. Поскольку нам не требуется высокой точности, то мы сильно упростим расчет и оставим точность ± 2 дня.
0: IR33 = IR9006 * 30; текущее значение месяца умножаем на 30
1: IR33 = IR33 – 30; вычитаем из полученного значения 30
2: IR34 = IR33 + IR9004; прибавляем к значению текущий день
Простым умножением получили номер цикла в диапазоне от 1 до 361, записанный в регистр IR35. Это не количество дней, а количество циклов, хотя и очень близкое значение.
Преобразуем время в минуты
5: IR36 = IR9008 * 60; умножаем часы на 60 получаем минуты
6: IR37 = IR36 + IR9009; прибавляем минуты
Получили текущее время в минутах в диапазоне от 0 до 1439, записанный в регистр IR37.
Рассчитаем время начала светового дня.
Вычисление будет приблизительным по упрощенной формуле с использованием только COS и для населенного пункта, для которого составлена таблица. Значение времени в минутах для рассвета рассчитываем по формуле:
Время = 130 * COS(2 * π / 361 * (номер цикла в году))+420
2 * π / 361 = 0.0174 - это круг, деленный на количество наших циклов 361 и умножаем это значение на 1000, т.к. тригонометрия в модуле пишется целыми числами в тысячных долях. Значение косинуса задается в радианах. Чем больше число в четвертом знаке после запятой, тем больше погрешность установки времени.
Записать можем только тысячную долю, т.е. 17. Отбрасывая 4 мы теряем очень сильно в точности и погрешность может оказаться до одного часа. Точность будет выше, при числе циклов, в котором результат будет до 3 знаков после запятой. 2 * π / циклы = 0.ххх0. Больше 3 знаков записать в регистр мы не можем. Когда последний день цикла умножается на это число, то должно получиться 2 * π, а результат COS должен быть 1. Тогда точность будет высокая.
7: IR25 = 17 * IR35
8: IR25 = COS (IR25)
9: IR25 = IR25 * 13
10: IR25 = IR25 / 100
11: IR32 = IR25 + 420
Рассчитали время рассвета и записали в регистр IR32
Теперь рассчитываем время заката по формуле: Время = 1440 - (время рассвета) + 120
12: IR31 = 1560 - IR32
Получили время заката и записали в регистр IR31
Далее пишем управление светом и жалюзи как в варианте, описанном выше.
Таким образом, используя минимальное количество строк в программе, мы сделали управление с довольно массивной таблицей данных.
7. Дифференцирующая цепь
Для управления жалюзи используются два канала реле. Они подключены к кнопкам "Открыть" и "Закрыть". Чтобы осталась возможность пользоваться кнопками нужно, чтобы контакты реле не были постоянно замкнуты.
Для этого нужно продифференцировать выходной сигнал. Дифференцировать - значит из постоянного сигнала сделать импульсный. Интегрировать - значит из импульсного сигнала сделать постоянный.
Продифференцировать сигнал можно двумя способами: программным и аппаратным.
Программный способ.
1) запускаем таймер;
2) при значении таймера = 5.0 секунды включаем реле.;
3) при значении таймера = 0.1 секунды выключаем реле.
Таймер доходит до 0 и останавливается.
18: IF(IR37 = IR30) THEN TIMER1 = 51; однократно
19: IF(TIMER1 = 50) THEN COIL1 = 1; однократно
20: IF(TIMER1 = 1) THEN COIL1 = 0; однократно
Через 5 сек после включения реле оно снова выключится.
Секунды задаются с точностью 0,1.
Аппаратный способ.
1) Замыкаем контакты;
2) заряжается конденсатор;
3) после заряда конденсатора цепь разрывается;
4) после размыкания контактов конденсатор разряжается.
Время заряда конденсатора считается по формуле Ꚍ=RC. где Ꚍ это постоянная времени равная 63% от полного заряда конденсатора в секундах, R в Омах, C в Фарадах.
Описанный выше алгоритм позволяет организовать систему управления освещением и жалюзи по условию изменения светлого и темного времени суток. Алгоритм можно реализовать на любых модулях Razumdom, т.к. сценарии во всех модулях практически одинаковые. Но для работы сценария нужны точно работающие часы. Часы реального времени RTC есть во всех модулях, а стабильность и точность их показания во всех модулях отличается.
P.S. Пока занялся этим вопросом решил сразу дописать эти команды в набор сценариев.
В новых версиях программ будут добавлены следующие параметры:
В регистре IR9018 будет выводиться номер дня в году с учетом високосного года. от 0 до 365 или 366, если год високосный.
В сценариях добавил новый сценарий:
R0 - тип = 26; R1 - тип регистра, R2 - выходной регистр, R3 - коэффициент A, R4 - тип регистра, R5 - регистр номера дня, R6 - коэффициент B.
(R1.2) = (R3) * COS(2 * PI / 365 * ((R4.5) +9))+(R6). Например: IR40 = 159 * COS(k * IR9018) + 381
Так время рассвета можно будет получить сразу из сценария.
А время заката для Тулы будет вычисляться командой: Закат = 1493 - Рассвет
IR31 = 1493 - IR40