Какой элемент в КДС может заменить "DC32" из ОЛ?
Вид для печати
Какой элемент в КДС может заменить "DC32" из ОЛ?
Добрый день.
Нахожусь в некотором замешательстве. В основной программе вызывается блок для подсчёта максимального количества работавших за час насосов:
И эти данные, соответственно, раз в час сохраняются в файл.Код:(* фронты включения насосов *)
rtrPumpOn1(CLK:= inNA1, Q=> );
rtrPumpOn2(CLK:= inNA2, Q=> );
rtrPumpOn3(CLK:= inNA3, Q=> );
rtrPumpOn4(CLK:= inNA4, Q=> );
rtrPumpOn5(CLK:= inNA5, Q=> );
rtrPumpOn6(CLK:= inNA6, Q=> );
(* фронты выключения насосов *)
ftrPumpOn1(CLK:= inNA1, Q=> );
ftrPumpOn2(CLK:= inNA2, Q=> );
ftrPumpOn3(CLK:= inNA3, Q=> );
ftrPumpOn4(CLK:= inNA4, Q=> );
ftrPumpOn5(CLK:= inNA5, Q=> );
ftrPumpOn6(CLK:= inNA6, Q=> );
(* считаем количество работающих насосов *)
pumpsCount := pumpsCount + BOOL_TO_INT(rtrPumpOn1.Q) + BOOL_TO_INT(rtrPumpOn2.Q) + BOOL_TO_INT(rtrPumpOn3.Q) + BOOL_TO_INT(rtrPumpOn4.Q) + BOOL_TO_INT(rtrPumpOn5.Q) + BOOL_TO_INT(rtrPumpOn6.Q) -
BOOL_TO_INT(ftrPumpOn1.Q) - BOOL_TO_INT(ftrPumpOn2.Q) - BOOL_TO_INT(ftrPumpOn3.Q) - BOOL_TO_INT(ftrPumpOn4.Q) - BOOL_TO_INT(ftrPumpOn5.Q) - BOOL_TO_INT(ftrPumpOn6.Q);
(* запоминаем максимальное количество работающих насосов *)
IF maxPumpsCount < pumpsCount THEN
maxPumpsCount := pumpsCount;
END_IF;
IF rtrHour.Q THEN
dataFlow.maxPumpsOn[tmTimeNow.Hour] := INT_TO_STRING(maxPumpsCount); (* сохраняем значение в структуру *)
maxPumpsCount := 0; (* обнуляем значение *)
oldHour := tmTimeNow.Hour; (* обнуляем разницу времени *)
END_IF;
Что непонятно, так это то, что в некоторые часы я получаю нулевые значения, хотя на 100% уверен, что в эти часы не было такого, что ни один насос не работал. После этого блока уже вызывается программа записи в файл, которая пишет значения структуры "dataFlow", также раз в час по фронту "rtrHour.Q". Как то можно это объяснить?
Ну мне нужно знать сколько максимум насосов работало в этом часу, а не сколько работает в текущий момент сохранения.
После обнуления:
maxPumpsCount все равно становится равным количеству работающих насосов в этот момент, согласноКод:IF rtrHour.Q THEN
maxPumpsCount := 0; (* обнуляем значение *)
END_IF;
И всё работает как задумано, но в некоторые часы (процентов 5% случаев может, не считал точно) maxPumpsCount оказывается равным 0, хотя это не так. вот и пытаюсь понять в чем косякКод:(* запоминаем максимальное количество работающих насосов *)
IF maxPumpsCount < pumpsCount THEN
maxPumpsCount := pumpsCount;
END_IF;
Чтобы знать сколько максимум насосов работало в этом часу, а не сколько работает в текущий момент сохранения совсем не обязательно подсчитывать фронты включения и фронты выключения.
Для этого есть стандартный оператор MAX() и как было верно сказано, нужно просто посчитать количество включенных насосов
Никаких промежуточных счетчиков не нужно!!
Как в прочем и r_trigg, f_trigg
Обратите внимание, что я не обнуляю maxPumpsCount после записи в структуру, а присваиваю ей количество работающих насосов в данный момент времени.Код:maxPumpsCount := MAX (maxPumpsCount , (BOOL_TO_INT(inNA1) +BOOL_TO_INT( inNA2) + BOOL_TO_INT(inNA3) +
BOOL_TO_INT(inNA4) +BOOL_TO_INT( inNA5) +BOOL_TO_INT( inNA6) ) );
IF rtrHour.Q THEN
dataFlow.maxPumpsOn[tmTimeNow.Hour] := INT_TO_STRING(maxPumpsCount); (* сохраняем значение в структуру *)
oldHour := tmTimeNow.Hour;
(* А теперь, подсчитать количество ВКЛЮЧЕННЫХ. насосов на начало следующего часа *)
maxPumpsCount := BOOL_TO_INT(inNA1) +BOOL_TO_INT( inNA2) + BOOL_TO_INT(inNA3) +
BOOL_TO_INT(inNA4) +BOOL_TO_INT( inNA5) +BOOL_TO_INT( inNA6);
END_IF;
И для следующего часа это и будет начальным значением максимального количества включенных насосов.
Имеется ПЛК110, являющийся в системе устройством ввода вывода. Передача по modbus. Сам ПЛК является slave устройством. Необходимо выставлять регистры состояния входов, записывать значения выходов и получать из сети промежуточные переменные. Все бы ничего, но мастер при опросе ищет устройство, регистры которого начинаются с адреса 0ХА400. В конфигураторе ПЛК для слэйва задание адреса не подразумевается, они поочередно идут, начиная с нулевого. Каким образом можно обозвать переменную и присвоить ей конкретный адрес регистра? И еще: можно ли знать, что переменная прочитана (пришел запрос на чтение данного регистра соответсвующей функцией)? Хотел через modbus.lib но он работает только с мастером.
Да, действительно,что то я забыл про МАХ(). Думаю ваш вариант будет правильнее работать. Спасибо.
Здравствуйте, нужна помощь. Некорректно работает тайм аут мастера: Панель СПК110 (мастер), подключение по modbus через 485; 2 слейва из 3 отключены; Тайм аут мастера стоит 200 мс; Время между фреймами 20 мс; Реальное время, которое уходит на эти 2 отключенных слейва 20 с! Как исправить? Спасибо за помощь
Добрый день! ПЛК пока не приобретен. Ориентируясь на ПЛК73, дописываю программу управления системой отопления и горячей водой под 2 существующих источника тепла (твердотопливный и электро) + в перспективе третий (газ) на CFC. Много чего удалось победить: управление одной кнопкой двумя-тремя разными *родственными* режимами, управление одной кнопкой взаимоисключающими режимами, управление задвижкой двустороннего действия. Много времени ушло на проработку *защиты от дурака*, когда например начинают нажимать лихорадочно на все подряд кнопки, нажимают и удерживают, и так далее. Но споткнулся о задачу реализации режима работы электронагревом в ночное время суток - с 23час5мин до 5час55мин. Интуитивно понимаю, что решение крутится вокруг таймера RTC. Но у него какой -то странный (обрезанный) функционал. Не понятно, зачем этот таймер вообще есть в стандарт.либ. Вопрос у меня разветвленный. Как сделать автоматическое считывание времени из ЦП персонального компьютера (для режима эмуляции) или ПЛК, и записи на вход блока PDT? Второй вариант вопроса. Как написать суточный (не недельный) таймер вручную с нуля? И в догонку еще вопрос. Извините, я еще только учусь, но есть ли в ПЛК функция автостарта программы на случай отключения электричества?
Спасибо. С автостартом понял. Как быть с суточным таймером? Кто поможет?
Все значительно проще, чем Вы думали. Никаких таймеров RTC ненужно :rolleyes:
Вложение 31675
А что такое "блок PDT"? И зачем он Вам нужен?
Спасибо за решение! Попробую разобраться. Про PDT я не верно выразился. Вход PDT блока RTC))
И все таки вопрос про считывание программой времени из памяти ПК остался. Как-то это можно реализовать?
Все. Понял)) Объявляем переменную реального времени в плк. И она в программе показывает реальное время) Предыдущий вопрос снимается. Спасибо.
Кто знает, как прописать ТРМ1 датчик температуры NTC 10kOm?
уважаемые разработчики OBEN!
зделайте 3-ёх контактные кнопки,
с помощью которых можно будет собирать кнопочные матрицы, такие как на Фото.
Для ПР110 получается
16-36 кнопочная станция.
Здравствуйте. использую библиотечный блок Пид регулятор,для управления нагревателем 3 кВт (очень инертное изменение температуры) с выводом данных на панель СП-270. Недавно выдал глюк, которого в реальности быть не может. Сделал сброс ПЛК, глюк исчез, но Пид регулирование теперь отличается от того, что было раньше в худшую сторону. Температура прыгает вокруг уставки, хотя никаких значений я не изменял. Подскажите - где копать?
Сам отвечу - замкнул тэн, и ТТР с управлением 4-20 мА сгорела и залипла в 100% открытом состоянии, все грелось на полную, а сигнал управления был на 0, так как реальная температура превышала уставку. А эти иглы в графике - замыкания тена на землю. Всем спасибо
Добрый день!
Начинаю вникать в процесс программирования owen. Как просто "программист" состоялся ))
Возможно, странный вопрос, но все же.
А можно в операторах непосредственно использовать ВХОДЫ (глобальные переменные, связанные с входами) ?
Вот такой фрагмент, скажем, допустим ?
В теле функции -
...
If diP then
... do something
end_if
diP - дискретный вход, если он в состоянии "1" - чего то сделать.
Какие особенности и/или подвохи ?
Или надо сначала в локальную переменную считать вход fsysP := diP, а затем уже использовать fsysP в операторах ?
Видимо неправильно вопрос задал ) по области видимости как бы вопросов нет.
Сам способ использования в конструкции IF (while, и аналогичных) переменной-входа - допустим ? Тонкостей и нюансов никаких нет ?
упрощенно, сперва в глобальные переменные записываются сигналы с физ.входов, далее выполняется пользовательский код, далее из соответствующих переменных записываются в физ.выхода. Поэтому проблем, программных, быть не должно, антидребезг решается фильтрацией или программно через TON. С while(и другими циклами) могут быть проблемы, приводящие к перегрузке плк, выполнение такого кода по времени должно быть не более ограничений в конфигурации на максимальное выполнение цикла контроллера, поэтому неадекватная задержка на while может сбросить выполнение программы
Из встроенной в CoDeSys 2.3 справки:
Прочитайте про использование конфигурационных переменных (VAR_CONFIG) в той же справке, там есть примеры использования.Цитата:
Что такое глобальные переменные?
Объявленные как глобальные, "нормальные" переменные, реманентные переменные и константы имеют область видимости, включающую весь проект.
Обратите внимание: Если в некотором программном компоненте проекта объявлена локальная переменная, имя которой совпадает с именем глобальной переменной, то в данном компоненте будет работать локальная переменная!
Использование прямых адресов в функциональных блоках противоречит идеологии независимости данных разных экземпляров функционального блока. Конфигурационные, или "шаблонные", переменные решают эту проблему.
Предельно понятно, спасибо!
Ограничение по времени учту, while не использую сам почти (редко), процесс достаточно инерционный, поэтому цикл задавать очень короткий смысла нет.
Учту обязательно. Пока, видимо, вопросы в раздел "для новичков" буду писать )
Помогите, не пойму что надо. Написал функциональный блок (первый в жизни), поставил в проект (тоже первый), при компиляции ошибка 3781.
Что он хочет?
Вложение 31843
Вложение 31844
Для чтения используется режим By poll time, для записи By value change.
Меня смущало то, что чтение и запись разнесены на разные экземпляры UMD, но оба экземпляра работают на один адрес слейва. Воплотил в железе, проверил, вроде работает.
Добрый день!
Не совсем понятно как работает блок RAMP_INT(REAL). Читал, что при подаче TRUE на вход RESET вход IN транслируется на OUT, а в хелпе пишут: "Установка двоичного входа RESET в TRUE вызывает сброс RAMP_INT в начальное состояние". Но по факту получается не так.
При работе блока при подаче true на вход reset, происходит просто остановка работы на текущем значении. При изменении in на out ничего не меняется, он остается на последнем значении. Соответственно, вопрос: как сбросить out блока, или установить нужное значение, с которого нужно начинать работу?
На вход In подается значение, к которому будет стремиться значение на выходе.
на вход ASCEND и DESCEND, подаются числа, которые влияют на скорость изменения значения на выходе.
на вход TIMEBASE задается время за которое изменится значение на выходе, до у ставки.
Если на входах ASCEND и DESCEND значение будет равно 100, то время TIMEBASE будет идти 1 к 1,
а если на входах ASCEND и DESCEND к примеру подать значение 50, то время TIMEBASE будет идти в 2 раза дольше.
В этом то понятно, кроме
Мне казалось ASCEND и DESCEND это значения, на которые происходит прирост/уменьшение out за время TIMEBASE.Цитата:
Если на входах ASCEND и DESCEND значение будет равно 100, то время TIMEBASE будет идти 1 к 1,
а если на входах ASCEND и DESCEND к примеру подать значение 50, то время TIMEBASE будет идти в 2 раза дольше.
Непонятно, как можно сбросить/присвоить OUT, так как он после паузы в работе сохраняет последнее значение.
Понял,спасибо, придётся так и сделать
К сожалению это не такЦитата:
в идеале он равен входу
P.S. Ага, посмотрел исходник - разобрался. Чтобы получить OUT:=IN нужно TIMEBASE приравнять к нулю
Здравствуйте . ПЛК 100 отлично работал год, потом был простой 7 месяцев. Когда запустил, после перерыва, программа стала работать некорректно. Появились какие - то "инвалиды" в таймерах. Грешу на железную часть ПЛК. Датчики в норме. ПРограмму перезаливал - глюки остаются. Подскажите пжс - что это может быть, и как это возможно устранить?
Похоже на то, что дело в дохлой батарейке. Заменил - инвалиды исчезли. Всем спасибо за поддержку
Добрый день. Подскажите, как лучше поступить с программой.
Состоит из 9 подпрограмм. Они незначительно отличаются, но в базе содержат 4 функциональных блока (которые сам написал)
1. Гистерезис с 5 уставками, и управляющими входами.
2. Таймер с 5 уставками и упр. входами
3. блок управления частотником, тоже с управлением, и уставками.
4. объединенный блок блинка и счетчика импульсов.
в общем, размер каждой программы солидный, попробовал все разместить в плк_прг заняло в таком виде почти все пространство отведенное codesis на написание программы, и комп начал глючить, не хватает мощности работать с такой программой.
Рассматриваю 2 варианта:
1. Каждую программу засунуть в функциональный блок (это уже освоил, но есть подозрения, что значительно увеличится размер программы)
2. Создать дерево программ (останавливает то, что вообще не понял как настраивать конфигурацию задач)
Здравствуйте. Подскажите, пожалуйста, почему не работает выход ФБ. При этом, если ту же программу написать в PLC_PRG всё работает. ПЛК160-24.А-М
Вложение 32024
Вложение 32025
Вложение 32026
У Вас в ФБ одной и той же переменной присваиваются значения в разных местах. Актуальным будет то значение у которого номер будет максимальным, в частности №31 (на выходе OR №30). И не важно, что было присвоено переменной AVAR_TEMP_SENSOR раннее.
Необходимо собирать условия вкл. переменной в одном месте, например, вместо трех OR использовать один с шестью входами.
Аналогично и в PLC_PRG. У Вас A13_OUT.11 присваивается в двух местах, работать тоже не будет, актуальным всегда будет значение с выхода OR №53.
Спасибо, понял)