Приветствую.
Не могу вспомнить где видел про несколько однотипных процессов в СПК.
Допустим управление котлами. Где процессы контроля в плк идут параллельно друг другу.
Описал логику для одного котла, а затем ее расширить на 4 котла.
Спасибо.
Приветствую.
Не могу вспомнить где видел про несколько однотипных процессов в СПК.
Допустим управление котлами. Где процессы контроля в плк идут параллельно друг другу.
Описал логику для одного котла, а затем ее расширить на 4 котла.
Спасибо.
Это называется FB.
И потом вызываете из PLC_PRG с необходимыми параметрами.
Либо через конфигуратор задач.
У меня работает проект на СПК110 с "параллельными" процессами, а именно контроллер нагрева многозонной (16 зон) печи. Общая концепция - считываем показания датчиков, обрабатываем, пишем результат в виде процента мощности в выходные блоки (ШИМ). Был написан один канал потом просто скопирован нужное число раз, естественно, с изменением нужных переменных. Полный цикл с учетом опроса "медленных" входных модулей занимает менее 3 сек. Точность поддержания температуры - 0.2*С, Проблем не наблюдается. Думаю, котлы буду малость помедленнее.
Последний раз редактировалось Sulfur; 10.11.2015 в 11:01.
Данный вариант (без использования массива FB) возможно будет работать только с простейшей логикой. Если в FB будет, например, таймер, то однозначно не подойдет, т.к. экземпляр FB один на все 4 котла.
Я использую в этом случае массивы FB:
Создается один функциональный блок FB_KOTEL, а в программе объявляется массив функциональных блоков KOTEL[i]:
VAR
...
KOTEL: ARRAY[1..i_max] OF FB_KOTEL;
...
END_VAR
Вызов экземпляров функциональных блоков из PLC_PRG:
FOR i:=1 TO i_max DO
...
KOTEL[i](i:=i, ...);
...
END_FOR
Входные, выходные и другие индивидуальные переменные экземпляров функциональных блоков удобнее задавать массивом структуры, хотя двухмерный массив думаю тоже подойдет.
Последний раз редактировалось vniko; 01.12.2015 в 14:45.
Не надо никаких циклов. Эти функциональные блоки всё равно где-то потребуется привязать к реальному миру — там их можно заодно и вызвать. Вот один из старых проектов:
fb_io.png
ФБ «UNIT» мог бы быть сколь угодно сложным.
Кстати действия типа Unit.Close, Unit.Abort я таким образом не использую больше.
To vniko:
Хороший класс. Плюс сразу видно спеца, пришедшего с программирования на ПК.
Такая штука - в ПЛК программа априори выполняется циклически сверху вниз. По этому дополнительный цикл или условие нужно использовать только чтобы "не вызывать" какой то из блоков.
А так их можно просто один за другим вставить в поле проекта. Без for и while...
To korhan:
Если у Вас стоит CODESYS 2:
http://www.owen.ru/forum/showthread.php?t=13588
10 и 11 пример для Вас.
Последний раз редактировалось Николаев Андрей; 01.12.2015 в 15:07.
Спасибо за ответы.
To Николаев Андрей:
Нет, CODESYS 3.5 для СПК207.
Но за примеры, спасибо. Скачал, посмотрю (CODESYS 2 тоже есть).
Добрый день, Vniko. С написанием ФБ и последующем размножением через массив понятно. Цикл FOR для "оживления" также ясен. А вот что имеется ввиду в последней строке сообщения: "Входные, выходные и другие индивидуальные переменные экземпляров..." Я обычно использую область VAR_INPUT и VAR_OUTPUT сответсвенно. Могли бы Вы написать коротенький пример с применением структуры. Заранее спасибо..
Сложно сказать, что именно предлагал Vniko, опишу варианты.
Предположим есть у нас ФБ, отвечающий за зону нагрева:
А зон таких у нас может быть до 20ти.Код:FUNCTION_BLOCK Zone VAR_INPUT // Температура в зоне rTemperature : REAL; // Давление в зоне rPressure : REAL; END_VAR VAR_OUTPUT // Какое положение задвижки необходимо задать rValvePosition : REAL; END_VAR
1) Делаем так:
1.1) Объявляем структуру, содержащую значения для входов
1.2) Объявляем структуру, содержащую значения для выходовКод:TYPE ZoneInputs : STRUCT // Температура в зоне rTemperature : REAL; // Давление в зоне rPressure : REAL; END_STRUCT END_TYPE
1.3) Объявляем массивы структур, содержащие данные для входов и выходовКод:TYPE ZoneOutputs : STRUCT // Температура в зоне rTemperature : REAL; // Давление в зоне rPressure : REAL; END_STRUCT END_TYPE
1.4) Объявляем массив ФБ наших зон:Код:PROGRAM PLC_PRG VAR CONSTANT m_c_usiMaxZones : USINT := 20; END_VAR VAR m_astInputs : ARRAY [1..m_c_usiMaxZones] OF ZoneInputs; m_astOutputs : ARRAY [1..m_c_usiMaxZones] OF ZoneOutputs; END_VAR
1.5) Наполнение PLC_PRG делаем примерно таким:Код:PROGRAM PLC_PRG VAR CONSTANT m_c_usiMaxZones : USINT := 20; END_VAR VAR m_astInputs : ARRAY [1..m_c_usiMaxZones] OF ZoneInputs; m_astOutputs : ARRAY [1..m_c_usiMaxZones] OF ZoneOutputs; m_afbZones : ARRAY [1..m_c_usiMaxZones] OF Zone; END_VAR
2) Честно говоря особых преимуществ перед следующим подходом не вижу:Код:m_astInputs[1].rTemperature := 10.0; // Тут скорее будут данные с датчиков m_astInputs[1].rPressure := 12.2; // ... и т.д. FOR i := 1 TO m_c_usiMaxZones DO m_afbZones[i].rPressure := m_astInputs[i].rPressure; m_afbZones[i].rTemperature := m_astInputs[i].rTemperature; m_afbZones[i](); m_astOutputs[i].rValvePosition := m_afbZones[i].rValvePosition; END_FOR // Устанавливаем положения задвижек получив значения из m_astOutputs[i].rValvePosition
2.1) В том месте, где нужны наши зоны объявляем массив ФБ
2.2) Тело программы делаем примерно таким:Код:PROGRAM PLC_PRG VAR CONSTANT m_c_usiMaxZones : USINT := 20; END_VAR VAR m_afbZones : ARRAY [1..m_c_usiMaxZones] OF Zone; i : USINT; END_VAR
Код:m_afbZones[1].rTemperature := 10.0; // Тут скорее будут данные с датчиков m_afbZones[1].rPressure := 12.2; // ... и т.д. FOR i := 1 TO m_c_usiMaxZones DO m_afbZones[i](); END_FOR // Устанавливаем положения задвижек получив значения из m_afbZones[i].rValvePosition
OSCAT.ru читать стандарты и статьи по автоматизации на русском без регистрации и СМС