Сообщение от
Валенок
Вначале сам 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 определяются в глобальных массивах структур.