I. Разработка программы
MetaGen

4. Собственный функциональный блок

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

Одна строка-шаблон в Instances и один вызов в ST Template дадут два экземпляра и два вызова. Добавите третий канал в Params — генератор создаст третий экземпляр, его настройки, вызов и поля для панели.

1. Напишите блок COffset

В меню MetaGen → Добавить функциональный блок создайте COffset. Вставьте:

st
VAR_INPUT
    in_fValue : REAL;
    in_fOffset : REAL;
END_VAR

VAR_OUTPUT
    out_fValue : REAL;
END_VAR

out_fValue := in_fValue + in_fOffset;

У ST-документа нет таблицы Data: входы, выходы и внутренние переменные объявляются в самом тексте. Имя документа станет именем типа блока. MetaPlatform добавит заголовок и завершение объекта.

Найдите файл FunctionBlocks/COffset.st. Его содержимое:

st
FUNCTION_BLOCK COffset
VAR_INPUT
    in_fValue : REAL;
    in_fOffset : REAL;
END_VAR

VAR_OUTPUT
    out_fValue : REAL;
END_VAR

out_fValue := in_fValue + in_fOffset;
END_FUNCTION_BLOCK

Этот исходник не содержит подстановок. Количество экземпляров и их подключение зададим в компоненте Correction.

2. Задайте экземпляры

В Correction сохраните две строки Params из предыдущей главы и заполните Instances:

Instance Function block Comment
Correct_|Id|_Inst COffset |Label|. Коррекция

Здесь записана одна строка, хотя каналов два. MetaGen раскрывает её для каждой строки Params: для Id = 1 создаёт Correct_1_Inst, для Id = 2 — Correct_2_Inst.

В файле GVL/Inst.st найдите этот фрагмент:

st
    Correct_1_Inst : COffset;
    Correct_2_Inst : COffset;
    Correction_Inst : Correction;

Все три экземпляра находятся в Inst. Correct_1_Inst и Correct_2_Inst заданы таблицей Instances, а основной экземпляр Correction_Inst добавляет MetaGen по имени компонента.

Первый экземпляр корректирует температуру подачи, второй — температуру обратки. У них одинаковый код COffset, но отдельные входы и результаты. При отладке их можно раскрыть по отдельности в Inst.

3. Опубликуйте выходы блоков

В Data сохраните global и conf, а прежнюю строку out замените строкой val:

Type Mode Area Tag Value Comment Publish
REAL global — |Input| — |Label|. Измерение 1
REAL conf — Offset_|Id| |Offset| |Label|. Поправка 1
REAL val Correct_|Id|_Inst out_fValue — |Label|. Результат 1

В режиме val указываем параметр, который уже объявлен в функциональном блоке. Area указывает на экземпляр из Instances, а Tag — на его параметр. В нашем примере global обращается к fRaw1 по короткому имени, поэтому там Area пустая. Для val указываем имя экземпляра: по нему MetaGen определяет, откуда брать out_fValue.

После подстановок получатся источники Correct_1_Inst.out_fValue и Correct_2_Inst.out_fValue. Режим val не объявляет эти выходы повторно: их объявление находится в COffset.

4. Вызовите блок

В ST Template замените формулу:

st
Correct_|Id|_Inst(
    in_fValue := |Input|,
    in_fOffset := Conf.Offset_|Id|
);

Сохраните проект, повторите генерацию и загрузку в RT. В MetaCore → Онлайн откройте Correction_Inst: в нём должны быть вызовы двух экземпляров. Затем откройте Correct_1_Inst и Correct_2_Inst. Для начальных значений результаты остаются 22.0 и 23.5.

Сгенерированный код выглядит так:

Найдите файл FunctionBlocks/Correction.st. Его содержимое:

st
FUNCTION_BLOCK Correction
Correct_1_Inst(
    in_fValue := fRaw1,
    in_fOffset := Conf.Offset_1
);

Correct_2_Inst(
    in_fValue := fRaw2,
    in_fOffset := Conf.Offset_2
);
END_FUNCTION_BLOCK

У Correction больше нет собственных выходов fResult_1 и fResult_2: соответствующая строка out удалена из Data. Результат хранится в выходах экземпляров COffset.

5. Посмотрите, откуда теперь берётся результат

Настройки остаются прежними.

Найдите файл Types/_Conf.st. Его содержимое:

st
TYPE _Conf
STRUCT
    Offset_1 : REAL := 2.0; // Температура подачи. Поправка
    Offset_2 : REAL := -1.5; // Температура обратки. Поправка
END_STRUCT
END_TYPE

В View теперь публикуются выходы экземпляров COffset.

Найдите файл Types/_View.st. Его содержимое:

st
TYPE _View
STRUCT
    fRaw1 : REAL; // Температура подачи. Измерение
    Correct_1_Inst_out_fValue : REAL; // Температура подачи. Результат
    fRaw2 : REAL; // Температура обратки. Измерение
    Correct_2_Inst_out_fValue : REAL; // Температура обратки. Результат
    Alarms_Inst_inout_bReset : Bool; // Сброс аварий/предупреждений
END_STRUCT
END_TYPE

Найдите файл Functions/makeView.st. Его содержимое:

st
FUNCTION makeView : BOOL
View.fRaw1 := fRaw1;
View.Correct_1_Inst_out_fValue := Correct_1_Inst.out_fValue;
View.fRaw2 := fRaw2;
View.Correct_2_Inst_out_fValue := Correct_2_Inst.out_fValue;
END_FUNCTION

Смена out на val изменила источник опубликованного результата:

Вариант Рабочее значение Копия для внешнего доступа
Выход проектного компонента MetaGen, out Correction_Inst.fResult_1 View.Correction_Inst_fResult_1
Выход экземпляра функционального блока, val Correct_1_Inst.out_fValue View.Correct_1_Inst_out_fValue

Вызов Correction_Inst() остаётся в основном сгенерированном алгоритме. Он обращается к основному экземпляру из Inst и вызывает два экземпляра COffset, также объявленные в Inst. Затем makeView() копирует их результаты в View для отображения на панели.

Если связать панель с этими данными, оператор будет задавать две поправки в Conf, а индикаторы — показывать результаты из View. Само вычисление выполняют два экземпляра COffset, объявленные в Inst.

Добавление следующего канала

В этом проекте мы описали один тип блока, одну строку Instances, один вызов и три строки Data. Благодаря двум строкам Params генератор создал два независимых канала со всеми объявлениями и связями.

Если добавить fRaw3 в GVL и третью строку Params по упражнению предыдущей главы, в Inst появится Correct_3_Inst : COffset, в Correction — его вызов, в Conf — Offset_3, в View — Correct_3_Inst_out_fValue. Копировать вызов, объявления и присваивания в makeView вручную не нужно.

Так же масштабируется прикладной компонент: один шаблон насоса — строки параметров для всех насосов — отдельный код и данные каждого механизма. Общие изменения вносятся в одном месте, в шаблоне.

Далее: режимы Mode

← 3. Один шаблон — несколько каналов5. Режимы Mode →