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:
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 содержит:
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. Его содержимое:
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. Его содержимое:
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 и код их обновления.