PDA

Просмотр полной версии : СПК207. Несколько однотипных процессов.



Korhan
28.10.2015, 22:19
Приветствую.

Не могу вспомнить где видел про несколько однотипных процессов в СПК.
Допустим управление котлами. Где процессы контроля в плк идут параллельно друг другу.
Описал логику для одного котла, а затем ее расширить на 4 котла.

Спасибо.

приборист
28.10.2015, 22:33
Это называется FB.
И потом вызываете из PLC_PRG с необходимыми параметрами.
Либо через конфигуратор задач.

Sulfur
10.11.2015, 10:59
...управление котлами. Где процессы контроля в плк идут параллельно друг другу.
Описал логику для одного котла, а затем ее расширить на 4 котла...
У меня работает проект на СПК110 с "параллельными" процессами, а именно контроллер нагрева многозонной (16 зон) печи. Общая концепция - считываем показания датчиков, обрабатываем, пишем результат в виде процента мощности в выходные блоки (ШИМ). Был написан один канал потом просто скопирован нужное число раз, естественно, с изменением нужных переменных. Полный цикл с учетом опроса "медленных" входных модулей занимает менее 3 сек. Точность поддержания температуры - 0.2*С, Проблем не наблюдается. Думаю, котлы буду малость помедленнее.

vniko
30.11.2015, 17:09
Это называется FB.
И потом вызываете из PLC_PRG с необходимыми параметрами.
Либо через конфигуратор задач.
Данный вариант (без использования массива 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

Входные, выходные и другие индивидуальные переменные экземпляров функциональных блоков удобнее задавать массивом структуры, хотя двухмерный массив думаю тоже подойдет.

smk1635
30.11.2015, 18:21
Данный вариант (без использования массива FB) возможно будет работать только с простейшей логикой. Если в FB будет, например, таймер, то однозначно не подойдет, т.к. экземпляр FB один на все 4 котла.
Я использую в этом случае массивы FB:
Создается один функциональный блок FB_KOTEL, а в программе объявляется массив функциональных блоков KOTEL[i]:
VAR
...
KOTEL: ARRAY[1..1_max] OF FB_KOTEL;
...
END_VAR

Вызов экземпляров функциональных блоков из PLC_PRG:
FOR i:=1 TO i_max DO
...
KOTEL[i](i:=i, ...);
...
END_FOR

Входные, выходные и другие индивидуальные переменные экземпляров функциональных блоков удобнее задавать массивом структуры, хотя двухмерный массив думаю тоже подойдет.

Интересный метод.
А что понимается под не простейшей логикой?

Yegor
01.12.2015, 06:20
Не надо никаких циклов. Эти функциональные блоки всё равно где-то потребуется привязать к реальному миру — там их можно заодно и вызвать. Вот один из старых проектов:

21127

ФБ «UNIT» мог бы быть сколь угодно сложным.
Кстати действия типа Unit.Close, Unit.Abort я таким образом не использую больше.

Николаев Андрей
01.12.2015, 15:05
To vniko:
Хороший класс. Плюс сразу видно спеца, пришедшего с программирования на ПК.
Такая штука - в ПЛК программа априори выполняется циклически сверху вниз. По этому дополнительный цикл или условие нужно использовать только чтобы "не вызывать" какой то из блоков.
А так их можно просто один за другим вставить в поле проекта. Без for и while...
To korhan:
Если у Вас стоит CODESYS 2:
http://www.owen.ru/forum/showthread.php?t=13588
10 и 11 пример для Вас.

Korhan
08.12.2015, 22:20
Спасибо за ответы.

To Николаев Андрей:
Нет, CODESYS 3.5 для СПК207.
Но за примеры, спасибо. Скачал, посмотрю (CODESYS 2 тоже есть).

sa_mut
29.07.2019, 16:53
Данный вариант (без использования массива 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. С написанием ФБ и последующем размножением через массив понятно. Цикл FOR для "оживления" также ясен. А вот что имеется ввиду в последней строке сообщения: "Входные, выходные и другие индивидуальные переменные экземпляров..." Я обычно использую область VAR_INPUT и VAR_OUTPUT сответсвенно. Могли бы Вы написать коротенький пример с применением структуры. Заранее спасибо..

Осинский Алексей
30.07.2019, 10:40
Добрый день, Vniko. С написанием ФБ и последующем размножением через массив понятно. Цикл FOR для "оживления" также ясен. А вот что имеется ввиду в последней строке сообщения: "Входные, выходные и другие индивидуальные переменные экземпляров..." Я обычно использую область VAR_INPUT и VAR_OUTPUT сответсвенно. Могли бы Вы написать коротенький пример с применением структуры. Заранее спасибо..

Сложно сказать, что именно предлагал Vniko, опишу варианты.
Предположим есть у нас ФБ, отвечающий за зону нагрева:



FUNCTION_BLOCK Zone
VAR_INPUT
// Температура в зоне
rTemperature : REAL;
// Давление в зоне
rPressure : REAL;
END_VAR
VAR_OUTPUT
// Какое положение задвижки необходимо задать
rValvePosition : REAL;
END_VAR


А зон таких у нас может быть до 20ти.
1) Делаем так:
1.1) Объявляем структуру, содержащую значения для входов



TYPE ZoneInputs :
STRUCT
// Температура в зоне
rTemperature : REAL;
// Давление в зоне
rPressure : REAL;
END_STRUCT
END_TYPE


1.2) Объявляем структуру, содержащую значения для выходов


TYPE ZoneOutputs :
STRUCT
// Температура в зоне
rTemperature : REAL;
// Давление в зоне
rPressure : REAL;
END_STRUCT
END_TYPE


1.3) Объявляем массивы структур, содержащие данные для входов и выходов


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.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;
m_afbZones : ARRAY [1..m_c_usiMaxZones] OF Zone;
END_VAR


1.5) Наполнение PLC_PRG делаем примерно таким:


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) Честно говоря особых преимуществ перед следующим подходом не вижу:
2.1) В том месте, где нужны наши зоны объявляем массив ФБ


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


2.2) Тело программы делаем примерно таким:


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

sa_mut
02.08.2019, 16:24
Спасибо, Алексей

согласен с Вами:
2) Честно говоря особых преимуществ перед следующим подходом не вижу:

Я также делаю по версии 2. Вот и хотел понять, что подразумевает Vniko и для используется массив структур. Ведь если алгоритм все равно обрабатывается в ФБ, то INPUT/OUTPUT переменные ФБ-ков получается просто будут дублировать данные массива структур. Что собственно и видно из приведенного Вами примера. Будем надеется Vniko объявится и подскажет какую пользу несут эти дополнительные массивы.

Валенок
03.08.2019, 10:37
что подразумевает Vniko
Попробую ответить за некропосты от vniko (если что - он поправит).

Вначале сам vniko не понял что приборист (п#2) сказал тоже самое что и он.
Как уже отметили, Вар.1 и 2 - одно и тоже по конечному результату, но "особенности" есть.


..Честно говоря особых преимуществ перед следующим подходом не вижу: Никто и не говорит что вар.1 лучше всегда. Вообще не бывает одного "наилучшего варианта навсегда" для чего-то ни было. Лучший вариант может быть только для конкретного объекта и конкретных условий. Условия включают в себя и возможности реализатора решения))

Для вар.1 - например необходимость отделения структурированных данных от "тела" ФБ для сетевого обмена. Не всегда сами ФБ можно расположить непосредственно в сети, а именно для КДС3 еще и категорически опасно. Индусятина с ручной правкой допустима (по мне и ввиду отсутствия удобной альтернативы) только в привязке к физическому миру (показана и в вар.1 и вар 2. и от Yegor п#6). Но от физ.входов до физ.выходов может быть большое кол-во дополнительных и необходимых для наблюдения данных.

vniko
19.03.2020, 16:34
Вначале сам vniko не понял что приборист (п#2) сказал тоже самое что и он.

То что хотел сказать приборист (п#2), думаю может уточнить только он. Если буквально воспринимать его пост, то получается такой алгоритм: создаётся FB и из программы вызывается один его экземпляр, каждый раз для разных объектов (с разными входными и выходными переменными). Поэтому я и уточнил, что лучше использовать несколько экземпляров FB (массив FB), для каждого однотипного объекта свой. Входные и выходные переменные FB удобно определить как структуры, а для массива FB, следовательно, надо определить массивы структур.
Вариант с одним экземпляром FB для нескольких объектов, полагаю, тоже имеет право на существование, но с ограничениями.

sa_mut, пример с определением и применением структуры привел Осинский Алексей. Только, как правильно заметил уважаемый Валенок, варианты 1 и 2 это одно и тоже. А "особенность" состоит в том, что в варианте 1 указано откуда берутся массивы входных переменных и куда отправляются массивы выходных переменных массива FB. В варианте 2 эта "особенность" просто пропущена.

sa_mut, если Вы определили массивы структур для массива FB, то Вам нет необходимости дублировать переменные в VAR_INPUT и в VAR_OUTPUT при определении самого FB. Да, забыл добавить важное замечание - массивы структур для FB я определяю в глобальных переменных.
У меня в VAR_INPUT для FB только:
i: USINT; //номер экземпляра FB.
В VAR_OUTPUT для FB ничего не определяю.
Обращение к переменным массивов структур в FB:
ИмяМассиваСтруктуры[i].ИмяЭлементаСтруктуры
Массив FB определяю в программе, из которой будут вызываться экземпляры FB.
Вызываю экземпляры FB в этой программе в теле цикла FOR i:=1 TO i_max DO так:
ИмяМассиваFB[i](i:=i);

Согласно моей реализации однотипных процессов, поправлю вариант 1 из поста #10 Осинского Алексея:
Пускай это будет вариант 3, а сам вариант 1 из #10 я бы никому не посоветовал. Зачем дублировать входные и выходные переменные FB? Ведь их и без того много.

3) Делаем так:

3.0) Предположим есть у нас ФБ, отвечающий за зону нагрева:


FUNCTION_BLOCK Zone
VAR_INPUT
i : USINT; //номер экземпляра FB.
END_VAR
VAR_OUTPUT
END_VAR


А зон таких у нас может быть сколько угодно, задано 20.

3.1) Объявляем структуру, содержащую значения для входов


TYPE ZoneInputs :
STRUCT
// Температура в зоне
rTemperature : REAL;
// Давление в зоне
rPressure : REAL;
END_STRUCT
END_TYPE


3.2) Объявляем структуру, содержащую значения для выходов


TYPE ZoneOutputs :
STRUCT
// Какое положение задвижки необходимо задать
rValvePosition : REAL;
END_STRUCT
END_TYPE


3.3) Объявляем массивы структур, содержащие данные для входов и выходов в GVL


VAR_GLOBAL CONSTANT
m_c_usiMaxZones : USINT := 20;
END_VAR
VAR_GLOBAL
m_astInputs : ARRAY [1..m_c_usiMaxZones] OF ZoneInputs;
m_astOutputs : ARRAY [1..m_c_usiMaxZones] OF ZoneOutputs;
END_VAR


3.4) Объявляем массив ФБ наших зон:


PROGRAM PLC_PRG
VAR
m_afbZones : ARRAY [1..m_c_usiMaxZones] OF Zone;
i : USINT; //номер экземпляра FB.
END_VAR


3.5) Наполнение PLC_PRG делаем примерно таким:


m_astInputs[1].rTemperature := 10.0; // Тут скорее будут данные с датчиков
m_astInputs[1].rPressure := 12.2;
// ... и т.д.

FOR i := 1 TO m_c_usiMaxZones DO
m_afbZones[i](i:=i);
END_FOR

// Устанавливаем положения задвижек получив значения из m_astOutputs[i].rValvePosition


То есть, основное отличие варианта 2 от варианта 3:
Вариант 2 - переменные FB определяются во входных/выходных переменных FB.
Вариант 3 - переменные FB определяются в глобальных массивах структур.