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

5.5. static — сохранить состояние между циклами

Посчитаем, сколько раз пользователь переключил ручную подстановку. Для этого проектный компонент MetaGen должен помнить предыдущий режим и значение счётчика.

Обе переменные создадим через static. Счётчик опубликуем для отображения, а предыдущий режим оставим внутри алгоритма.

Опишем две переменные и обработку смены режима один раз в шаблоне. MetaGen повторит их для обоих каналов, а при расширении Params — для каждого добавленного канала.

Начните с проекта раздела 5.4 — inout. Сохраните параметры inout, блок COffset, настройки Conf и существующие экземпляры в Inst.

1. Добавьте память компонента

В Data проектного компонента MetaGen Correction добавьте:

Type Mode Area Tag Value Comment Publish
BOOL static — bPreviousManual_|Id| FALSE |Label|. Предыдущий режим —
DINT static — diModeChanges_|Id| 0 |Label|. Количество смен режима 1

static описывает внутренний параметр самого проектного компонента MetaGen Correction. При генерации он объявляется как переменная в секции VAR. Поле Area остаётся пустым.

Параметр bPreviousManual_|Id| хранит режим предыдущего цикла. Он нужен только алгоритму, поэтому Publish выключен. diModeChanges_|Id| хранит число изменений режима; для него Publish включён.

В таблице Data режим называется static. VAR — секция ST, которую по этой строке создаст генератор.

2. Посчитайте переключения

Перед вызовом COffset сравните текущий режим с предыдущим и запомните новое состояние. Полный ST Template:

st
IF inout_bManual_|Id| <> bPreviousManual_|Id| THEN
    diModeChanges_|Id| := diModeChanges_|Id| + 1;
END_IF;
bPreviousManual_|Id| := inout_bManual_|Id|;

Correct_|Id|_Inst(
    in_fValue := |Input|,
    in_fOffset := Conf.Offset_|Id|,
    inout_bManual := inout_bManual_|Id|,
    inout_fManualValue := inout_fManualValue_|Id|
);

Счётчик увеличивается при обоих переходах: из автоматического режима в ручной и обратно. Пока режим не меняется, счётчик остаётся прежним.

3. Найдите переменные в экземпляре

Повторите генерацию и загрузку в RT. В MetaCore → Онлайн откройте Correction_Inst. Счётчики и предыдущие режимы теперь хранятся внутри него. Файл FunctionBlocks/Correction.st содержит:

st
FUNCTION_BLOCK Correction
VAR_IN_OUT
    inout_bManual_1 : BOOL; // Температура подачи. Ручная подстановка
    inout_fManualValue_1 : REAL; // Температура подачи. Ручное значение
    inout_bManual_2 : BOOL; // Температура обратки. Ручная подстановка
    inout_fManualValue_2 : REAL; // Температура обратки. Ручное значение
END_VAR
VAR
    bPreviousManual_1 : BOOL := FALSE; // Температура подачи. Предыдущий режим
    diModeChanges_1 : DINT := 0; // Температура подачи. Количество смен режима
    bPreviousManual_2 : BOOL := FALSE; // Температура обратки. Предыдущий режим
    diModeChanges_2 : DINT := 0; // Температура обратки. Количество смен режима
END_VAR
IF inout_bManual_1 <> bPreviousManual_1 THEN
    diModeChanges_1 := diModeChanges_1 + 1;
END_IF;
bPreviousManual_1 := inout_bManual_1;

Correct_1_Inst(
    in_fValue := fRaw1,
    in_fOffset := Conf.Offset_1,
    inout_bManual := inout_bManual_1,
    inout_fManualValue := inout_fManualValue_1
);

IF inout_bManual_2 <> bPreviousManual_2 THEN
    diModeChanges_2 := diModeChanges_2 + 1;
END_IF;
bPreviousManual_2 := inout_bManual_2;

Correct_2_Inst(
    in_fValue := fRaw2,
    in_fOffset := Conf.Offset_2,
    inout_bManual := inout_bManual_2,
    inout_fManualValue := inout_fManualValue_2
);
END_FUNCTION_BLOCK

Эти переменные находятся внутри экземпляра Correction_Inst, объявленного в Inst. Например, рабочий счётчик первого канала — Correction_Inst.diModeChanges_1.

Значения сохраняются от одного вызова экземпляра к следующему. Поэтому алгоритм может сравнить текущий режим с предыдущим. static сам по себе не задаёт сохранение значения после перезапуска ПЛК: это отдельный вопрос сохраняемой памяти.

4. Проверьте публикацию счётчика

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

st
TYPE _View
STRUCT
    fRaw1 : REAL; // Температура подачи. Измерение
    Correct_1_Inst_out_fValue : REAL; // Температура подачи. Результат
    Correction_Inst_inout_bManual_1 : BOOL := FALSE; // Температура подачи. Ручная подстановка
    Correction_Inst_inout_fManualValue_1 : REAL := 0.0; // Температура подачи. Ручное значение
    Correction_Inst_diModeChanges_1 : DINT; // Температура подачи. Количество смен режима
    fRaw2 : REAL; // Температура обратки. Измерение
    Correct_2_Inst_out_fValue : REAL; // Температура обратки. Результат
    Correction_Inst_inout_bManual_2 : BOOL := FALSE; // Температура обратки. Ручная подстановка
    Correction_Inst_inout_fManualValue_2 : REAL := 0.0; // Температура обратки. Ручное значение
    Correction_Inst_diModeChanges_2 : DINT; // Температура обратки. Количество смен режима
    Alarms_Inst_inout_bReset : Bool; // Сброс аварий/предупреждений
END_STRUCT
END_TYPE

Поля счётчиков появились в View, потому что для них включён Publish. Полей bPreviousManual_1 и bPreviousManual_2 здесь нет: они остались внутри Correction_Inst.

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

st
FUNCTION makeView : BOOL
View.fRaw1 := fRaw1;
View.Correct_1_Inst_out_fValue := Correct_1_Inst.out_fValue;
View.Correction_Inst_diModeChanges_1 := Correction_Inst.diModeChanges_1;
View.fRaw2 := fRaw2;
View.Correct_2_Inst_out_fValue := Correct_2_Inst.out_fValue;
View.Correction_Inst_diModeChanges_2 := Correction_Inst.diModeChanges_2;
END_FUNCTION

Для панели используйте View.Correction_Inst_diModeChanges_1 и View.Correction_Inst_diModeChanges_2. При каждом обновлении туда копируются значения рабочих счётчиков.

Запись нуля в такую копию View не сбросит рабочий счётчик: следующий makeView вернёт его текущее значение. Если потребуется операторский сброс, добавьте отдельную команду inout и обработайте её в алгоритме. В этом упражнении сброс не предусмотрен.

Теперь у каждого канала есть поправка в Conf, ручной режим и задание в View, а также собственный счётчик внутри Correction_Inst. Всё это получено из общего шаблона. Чтобы добавить ещё один канал с теми же возможностями, достаточно объявить его исходный сигнал и добавить строку Params.

Мы задаём алгоритм в ST и правила создания данных в таблицах. MetaGen повторяет их для нужного количества каналов, создаёт экземпляры в Inst, настройки Conf, данные View и код их обновления.

Все режимы Mode · Далее: встроенный интерпретатор

← 5.4. inout6. Встроенный интерпретатор →