Просмотр полной версии : реализация годового графика включения/выключения
KRUPSKIY
29.03.2016, 20:27
Как лучше реализовать годовой график вкдючения/выключения освещения? Нужный график не привязан к времени восходами захода солнца, а только к местному времени. например, сегодня свет включить в 22-00, в 7-00 выключить, завтра в 22-03 вкл. т. д.? Хватит ли памяти ПЛК (например, ПЛК110, для хранения программы без какой-либо формулы для вычисления времени на каждый день, если каждый день прописать отдельными командами?
можно сделать таблицу и вычислять смещение по ней. Должно меньше памяти съесть.
А вообще были реализации календарей даже на ПР
И не лень вам будет 740 раз прописывать времена ?
lara197a
30.03.2016, 06:55
Памяти хватит, но вот писать такую таблицу- титаническая работа.
Я бы накатал какой-нибудь алгоритм, периодически к примеру прибавлять- вычитать.
KRUPSKIY
30.03.2016, 08:45
В том-то и дело, что алгоритма нет. График утвежждается на год местным руководством. В следующем году может поменяться, а может нет. На год я готов помучиться, вручную прописать. Лишь бы хватило память ПЛК. Как это реализовать практически? Есть ли какой-то пример?
ну так и переложите составление графика на руководство, пусть они его пишут в ексель, а Вы потом его в плк пропарсите
KRUPSKIY
30.03.2016, 08:56
С графиком то вопрос решаем. А как ваму программу написать с привязкой к реальному времени, никогда не делал.
lara197a
30.03.2016, 09:06
С графиком то вопрос решаем. А как ваму программу написать с привязкой к реальному времени, никогда не делал.
пиши в личку сброшу.
приборист
30.03.2016, 09:09
+ сразу для ПЛК110 делайте программу синхронизации времени по внешнему серверу.
С графиком то вопрос решаем. А как ваму программу написать с привязкой к реальному времени, никогда не делал.
Есть готовый проект на ПР114, если интересно, пишите в личку.
KRUPSKIY
06.04.2016, 12:15
SA104: Спасибо, за деньги не надо!
Насколько я понимаю, в таблице для каждого дня первым должно быть событие ВЫКЛ, а вторым ВКЛ?
Ведь в конструкции "сегодня свет включить в 22-00, в 7-00 выключить" 7-00 относится уже не к сегодня, а к завтра?
SA104: Спасибо, за деньги не надо!
Действительно. На чужом горбу приятней
А вопрос еще актуальный?
Хотя, посмотрел, что ТС больше не появлялся
Наверно обиделся :confused:
ЗЫ. Может еще вернется?
PROGRAM PLC_PRG
VAR RETAIN PERSISTENT
Schedule: ARRAY [1..366, 1..2] OF TOD; (* Расписание: Время Откл, Время Вкл. в формате Time Of Date*)
END_VAR
VAR CONSTANT
dpm: ARRAY [1..12] OF INT := 31, 28, 31,30, 31, 30, 31, 31, 30, 31, 30, 31; (*Чисол дней в месяце*)
nulldt: SystemTimeDate; (*нужна для обнуления параметров*)
END_VAR
VAR
CurTimeExInst: CurTimeEx;
CurSystemTimeDate: SystemTimeDate;
CurSysTime64: SysTime64;
year: INT;
second: INT;
day: INT;
hour: INT;
minute: INT;
month: INT;
LEAP_YEAR: BOOL; (*Флаг високосного года*)
Curr_DAY: INT; (*Номер дня в году*)
i: INT;
Now: TOD; (*Текущее время*)
Stop: TOD; (*Время выключения*)
Start: TOD; (*Время включения*)
Light: BOOL; (*Освещение вкл.*)
END_VAR
CurSystemTimeDate:=nulldt;
CurTimeExInst(TimeDate := CurSystemTimeDate, SystemTime := CurSysTime64);
year :=CurSystemTimeDate.Year;
month :=CurSystemTimeDate.Month;
day :=CurSystemTimeDate.Day;
hour :=CurSystemTimeDate.Hour;
minute :=CurSystemTimeDate.Minute;
second :=CurSystemTimeDate.Second;
(*------------------------------------------------------------------------*)
LEAP_YEAR := SHL(year,14) = 0; (*Проверить високосный год*)
(*номер дня в году*)
Curr_DAY:=day + BOOL_TO_INT(month > 2 AND LEAP_YEAR);
FOR i:=1 TO 12 DO
IF i < month THEN Curr_DAY:=Curr_DAY + dpm[i] ; END_IF
END_FOR
(*------------------------------------------------------------------------*)
Now := DWORD_TO_TOD( INT_TO_DWORD(SECOND)*1000+ INT_TO_DWORD(MINUTE) * 60000 + INT_TO_DWORD(HOUR) * 3600000);
(*Вкл/Выкл здесь*)
Stop:=Schedule[Curr_DAY, 1];
Start:=Schedule[Curr_DAY, 2];
IF stop < start THEN
Light := start <= Now OR Now < stop;
ELSE
Light := start <= Now AND Now < stop;
END_IF;
Бесплатно!
Вот как вбивать это расписание? Здесь гораздо интересней задачка.
Автор темы хочет бесплатно, а вы ПЛК предлагаете вместо ПР-ки - для всего одной задачи. :)
Вот как вбивать это расписание? Здесь гораздо интересней задачка.
Чего там интересного.
Покласть на ретайн чтоб не стать очередным плакальщиком на форуме.
При старте прочитать из файла и выложить в модбас-слейв.
Периодически проверять слейв на изменения, при их наличии (или специальной просьбе от клиента) - сбрасывать в файл.
Внешним модбас-клиентом менять что-угодно в слейве говоря или нет (все равно обнаружит) об этом
Или просто тупо перенести файл данных в плк и сказать ему об этом чтоб прочитал.
Ну и время ему скидывать для синхронизации
В общем - строк 20..40
А первоначальные данные - тупо программно заполнить.
to petera
А зачем считать дни ?
.. schedule : array[1..12,1..31,1..2] of tod;
Первые два индекса правильно возвратит syslibtime )), и дальше без промежуточных переменных
..
stop := schedule[CurSystemTimeDate.Month, CurSystemTimeDate.Day, ..];
..
//какие, блин, длинные имена. Может просто икс ?
to petera
А зачем считать дни ?
.. schedule : array[1..12,1..31,1..2] of tod;
Первые два индекса правильно возвратит syslibtime )), и дальше без промежуточных переменных
Красиво,
но 31 февраля, апреля, июня...?
http://www.owen.ru/forum/attachment.php?attachmentid=16915&d=1425224217уже где-то было...? Почти как 30 Термидора или Брюмера.
23754
Год республиканского календаря состоял из 365 или 366 дней, поделённых на 12 месяцев продолжительностью ровно 30 дней, после которых шло подряд 5 или, соответственно, 6 дополнительных дней, которые назывались «санкюлотиды». Название «санкюлотиды» происходит от слова «санкюлоты» — революционно настроенные массы, — и дословно означает «без коротких бархатных брюк» (такую одежду носили буржуазия и дворяне, а городская беднота, разумеется, не могла себе их позволить). Каждый месяц делился на 3 декады по 10 дней. Гражданам предлагалось самим определить, сколько и какие из этих дней будут для них выходными, но для госслужащих устанавливался лишь один выходной день — последний день каждой декады.
Валенок, Вы наш новый Шарль-Жильбер Ромм! http://www.owen.ru/forum/attachment.php?attachmentid=19860&d=1441788809
Дни считать предлагаю потому, что
График утвежждается на год местным руководством. В следующем году может поменяться, а может нет. На год я готов помучиться, вручную прописать.
Хотелось, чтобы "помучился" поменьше и не ошибся в днях года, когда будет "вручную прописывать".
А с Термидорам или Брюмероми классно бы вышло, только как объяснить начальству, что кроме законных, традиционных каникул в январе, тьфу... в Вандемьере, или вся таки в Нивозе?, еще будут пять санкюлотидов в конце года. Хотя работяги обрадовались бы. :rolleyes:
Владимир Ситников
09.04.2016, 09:16
Дни считать предлагаю потому, что
Хотелось, чтобы "помучился" поменьше и не ошибся в днях года, когда будет "вручную прописывать"
Вы о чём?
Одно дело перечислять расписание для каждого дня в году (это норм), а другое -- вычислять номер текущего дня в году (это не норм). [1..12, 1..31] -- выглядит вполне разумно.
но 31 февраля, апреля, июня...?
А чем мешает 31 февраля?
Вы бы лучше не о Брюмерах, а о Медведеве подумали: вот снова сделает он летнее время и будет "превед медвед" два раза в год с переводом часов.
Вы о чём?
Одно дело перечислять расписание для каждого дня в году (это норм), а другое -- вычислять номер текущего дня в году (это не норм). [1..12, 1..31] -- выглядит вполне разумно.
А чем мешает 31 февраля?
Вы бы лучше не о Брюмерах, а о Медведеве подумали: вот снова сделает он летнее время и будет "превед медвед" два раза в год с переводом часов.
Летнее время? А что это?
http://www.owen.ru/forum/attachment.php?attachmentid=16915&d=1425224217
И чего мне о Медведеве думать? Кто он мне? Никто!
Мне уж если думать, то о Кобякове Андрее Владимировиче.:rolleyes:
http://www.owen.ru/forum/attachment.php?attachmentid=23761&d=1460184287
Хотелось, чтобы "помучился" поменьше и не ошибся в днях года, когда будет "вручную прописывать".:
Ну если модбас-клиент пишет, то просто не предлагать ненужные поля
Да и какая цена ошибки с учетом ручного заполнения а не по восходам-закатам ?
А для плк 31 февраля просто не наступит - см. сислибтайм
lara197a
09.04.2016, 22:23
пора закрывать.
я ему заготовку 30.03 сбросил.
спасибо не сказал.
а вы все рекомендации пишете...:(
KRUPSKIY
13.04.2016, 11:27
Всем откликнувшимся-огромное спасибо, отдельно-lara197a !
Извиняюсь за молчание-не было возможности.
Тема еще актуальна, просто жду ПЛК, чтобы проверить. В симуляторе ведь не работает.
Всем откликнувшимся-огромное спасибо, отдельно-lara197a !
Извиняюсь за молчание-не было возможности.
Тема еще актуальна, просто жду ПЛК, чтобы проверить. В симуляторе ведь не работает.
Зато работает в PLCWinNT. Так, что проверить можно.
Что-то никто не предложил набивать таблицу прямо в КДС, в визуализации.
https://www.youtube.com/watch?v=ochqaMC5pdw
Для упрощения ввода данных пришлось расписание в таблице с Time Of Day заменить на пользовательский тип данных
TYPE Schedule :
STRUCT
HourOff: INT;
MinuteOff: INT;
HourOn: INT;
MinuteOn: INT;
END_STRUCT
END_TYPE
PROGRAM PLC_PRG
VAR RETAIN PERSISTENT
Table:ARRAY [1..366] OF Schedule; (* Расписание: *)
END_VAR
VAR CONSTANT
dpm: ARRAY [1..12] OF INT := 31, 28, 31,30, 31, 30, 31, 31, 30, 31, 30, 31; (*Чисол дней в месяце*)
nulldt: SystemTimeDate; (*нужна для обнуления параметров*)
END_VAR
VAR
CurTimeExInst: CurTimeEx;
CurSystemTimeDate: SystemTimeDate;
CurSysTime64: SysTime64;
year: INT;
second: INT;
day: INT;
hour: INT;
minute: INT;
month: INT;
LEAP_YEAR: BOOL; (*Флаг високосного года*)
Curr_DAY: INT; (*Номер дня в году*)
i: INT;
Now: TOD; (*Текущее время*)
Stop: TOD; (*Время выключения*)
Start: TOD; (*Время включения*)
Light: BOOL; (*Освещение вкл.*)
selX:INT :=1; (*Используется в визуализации (в таблице)*)
selY:INT :=1; (*Используется в визуализации (в таблице)*)
END_VAR
CurSystemTimeDate:=nulldt;
CurTimeExInst(TimeDate := CurSystemTimeDate, SystemTime := CurSysTime64);
year :=CurSystemTimeDate.Year;
month :=CurSystemTimeDate.Month;
day :=CurSystemTimeDate.Day;
hour :=CurSystemTimeDate.Hour;
minute :=CurSystemTimeDate.Minute;
second :=CurSystemTimeDate.Second;
(*------------------------------------------------------------------------*)
LEAP_YEAR := SHL(year,14) = 0; (*Проверить високосный год*)
(*номер дня в году*)
Curr_DAY:=day + BOOL_TO_INT(month > 2 AND LEAP_YEAR);
FOR i:=1 TO 12 DO
IF i < month THEN Curr_DAY:=Curr_DAY + dpm[i] ; END_IF
END_FOR
(*------------------------------------------------------------------------*)
Now := DWORD_TO_TOD( INT_TO_DWORD(SECOND)*1000+ INT_TO_DWORD(MINUTE) * 60000 + INT_TO_DWORD(HOUR) * 3600000);
Stop:= DWORD_TO_TOD(INT_TO_DWORD(Table[Curr_DAY].HourOff) * 3600000 + INT_TO_DWORD(Table[Curr_DAY].MinuteOff) * 60000);
Start:=DWORD_TO_TOD(INT_TO_DWORD(Table[Curr_DAY].HourOn) * 3600000 + INT_TO_DWORD(Table[Curr_DAY].MinuteOn) * 60000);
IF stop < start THEN
Light := start <= Now OR Now < stop;
ELSE
Light := start <= Now AND Now < stop;
END_IF;
KRUPSKIY
13.04.2016, 15:24
То, что надо, petera! Спасибо!
KRUPSKIY
09.06.2016, 07:19
petera! Все отлично работает, но возникла другая проблема. Мне необходимо вводить не два, а четыре значения времени на каждый день. В этом случае уже не хватает памяти в ПЛК, чтобы объявить переменные как RETAIN PERSISTENT. Что-либо можно придумать?
petera! Все отлично работает, но возникла другая проблема. Мне необходимо вводить не два, а четыре значения времени на каждый день. В этом случае уже не хватает памяти в ПЛК, чтобы объявить переменные как RETAIN PERSISTENT. Что-либо можно придумать?
Тогда хранить таблицу расписания в файле.
Редактирование файла в визуализации можно сделать по аналогии с тем, как я делал для рецептов (доп кнопки Сохранить и Отменить) http://www.owen.ru/forum/showthread.php?t=22665&p=186999&viewfull=1#post186999
https://www.youtube.com/watch?v=q9sjdc6UYY0
Если сами не справитесь, то буду помогать.
KRUPSKIY
09.06.2016, 12:16
ОК! petera всегда помогает! Буду пробовать, спасибо!
dkapotov
15.06.2016, 17:16
А как сделать, чтобы в таблице было переменное число строк? Сейчас оно равно количеству дней, то есть 365, а нужно чтобы на СПК была такая же таблица, но были кнопки Добавить/Удалить запись. Пользователь сам сможет добавлять/удалять нужную запись с временем включения/выключения
lara197a
15.06.2016, 17:45
А как сделать, чтобы в таблице было переменное число строк? Сейчас оно равно количеству дней, то есть 365, а нужно чтобы на СПК была такая же таблица, но были кнопки Добавить/Удалить запись. Пользователь сам сможет добавлять/удалять нужную запись с временем включения/выключения
нужно прописывать всю таблицу и через "видимость" открывать-закрывать строки.
(с СПК не работал, как конкретно там не знаю)
Что-то никто не предложил набивать таблицу прямо в КДС, в визуализации.
[/CODE]
кстати у меня пример тоже был с визуализацией.
час, минуты, секунды
и того 6 значений на событие.
т.е. если даже использовать по событию в день, то нужно отрисовать почти 2000 ячеек, присвоить переменные
и свойства заполнить....
Powered by vBulletin® Version 4.2.3 Copyright © 2025 vBulletin Solutions, Inc. All rights reserved. Перевод: zCarot