Линейно нарастающая функция
Разъяснение программной функции плавного прироста какого либо параметра
Для плавного изменения управляющей переменной (уставка SP), задающей значение технологического процесса, по закону линейно нарастающая функция используется функциональный блок Ramp. Данная задача востребована часто при процессах нагрева или охлаждения для различных инертных процессах (крупные печи, научные внедрения, пищевая промышленность).
Обрабатывает входные значения технологического процесса и формирует выходной аналоговый сигнал, который является уставкой для работы конкретного регулятора. Линейно-нарастающая функция предназначена для растянутого во времени достижения заданной уставки технологическим процессом. Разрядность процесса прироста или замедления зависит от быстродействия процессора (скважности), чем выше разрядность, тем с большей точностью (ровнее линия) будет вестись процесс.
Блок поддерживает возможность временного прекращения набора/снижения линейно-нарастающей функции в зависимости от потребности технологического процесса (например, при отсутствии необходимости регулирования). Позволяет гибко настраивать под технологию.
Логика работы функционального блока позволяет добиться достижения плавающей уставки (FSP) до статической уставки (SP) за заданное (RAMP_TIME) время. Данное замедление регулированием технологического процесса требуется для инерционных процессов.
Тут важно отметить, что для корректной работы данной функции нам потребуется переменная, связанная с системным временем контроллера. Переменная постоянно меняется в коде данного блока. Сам процесс запуска основан на запоминании начального времени и расчета времени, до которого функция будет следовать.
Данный программный код взят из программы написанной для Codesys 2.3, но он с небольшими доработками будет работать и в других системах, где реализован в соответствии со стандартом язык ST(Structured Text).
FUNCTION_BLOCK TE_CALC_SP
VAR_INPUT
TE_SP_1:REAL;(*Значение с которого мы начали стартовать*)
TE_SP_2:REAL;(*Значение к которому мы идем*)
SPEED:REAL;(*Скорость с какой мы должны достичь установленного значения*)
END_VAR
VAR_IN_OUT
START:BOOL;
END_VAR
VAR_OUTPUT
OUT:REAL; (*Выходная переменная, которая привязывается к уставке *)
State:INT; (*Номер шага, на котором мы находимся*)
Complite:BOOL;(*Выставляем флаг, что рамп закончил*)
START_TIME:TIME;(*Время, когда ожидается завершение подсчета*)
FINISH_TIME:TIME;(*Время, когда ожидается завершение подсчета*)
END_VAR
VAR
TIME_MAIN:TIME;(*Общее время прироста рамп-функции*)
First:REAL;(*Начальное значение интервала*)
Second:REAL;(*Конечное значение интервала*)
GRADUS:REAL;(*Считаем разницу в градусах*)
TON2:TON;(*Таймер от зависания в стадии перехода через 0*)
Cur_Timei:DWORD;(*Для расчета перехода через 00:00:00*)
AM:REAL;(*Разница между уставкой и переменной процесса*)
OS:REAL;(*Значение переменной процесса в начале функции*)
Err:REAL;(*Уменьшающаяся ошибка*)
tx:TIME;(*Текущее время ПЛК*)
tx1:TIME;(*Запоминаем время ПЛК в начале счета*)
txr_diff:REAL;(*Нарастающее время в формате REAL*)
fr:REAL;(*Расчитанный коэффициент приращения, угол наклона*)
R_TRIG:R_TRIG;(*Ловим переход, окончание RAMP*)
Теперь немного о коде этого функционального блока. Код выполнен на операторе CASE, что удобно для реализации конечного автомата. Это когда в каждый конкретный момент времени выполняется какая-то часть программного кода, причем весь остальной программный код находится в состоянии ожидания. Возможно делать различные гибкие комбинации подобно языку SFC. Управляется переход с шага на шаг при помощи целочисленной переменной State
CASE State OF
0:(*На этом шаге мы стоим и ждем, инициализируем переменные*)
OUT:=TE_SP_1; (*Присваиваем начальное значение выходу*)
START_TIME:=T#0m; (*Обнуляем начальное время*)
FINISH_TIME:=T#0m; (*Обнуляем конечное время*)
IF START THEN State:=1; END_IF; (*Если нажата кнопка старт, то переходим на следующий уровень*)
1:(*Определяем время начала работы функции, высчитываем время и переходим дальше*)
Complite:=FALSE;(*Сбрасываем признак окончания*)
GRADUS:=ABS(TE_SP_2 - TE_SP_1);(*Посчитали сколько градусов разница*)
First:=TE_SP_1;(* Запомнили первое число*)
Second:=TE_SP_2;(*Запомнили второе число*)
txr_diff:=1;(*Присваиваем 1 переменной, которая отвечает за угол наклона функции*)
TIME_MAIN:=(REAL_TO_TIME(GRADUS/SPEED)*1000*60*60);(*Вычисляем, за сколько времени приращать функцию*)
fr:=txr_diff/DINT_TO_REAL(TIME_TO_DINT(TIME_MAIN));(*Время за которое должна нарастать или убывать функция. Высчитывает коэффициент приращения/убавления*)
tx:=T#0s;(*Обнулили инкремент по времени*)
Err:=0.0;(*Обнулили инкремент по рассогласованию*)
AM:=Second - First;(*Посчитали расстояние в градусах между двумя точками*)
OS:=First; (*Запомнили откуда мы идем*)
tx1:=PLC_TIME; (*Запоминаем время до начала работы рамп*)
START_TIME:=PLC_TIME;
FINISH_TIME:=PLC_TIME+TIME_MAIN;
State:=2;
2:(*Делаем RAMP от первой до второй точки*)
tx:=PLC_TIME;(*Время циклически накапливается*)
txr_diff:=DINT_TO_REAL(TIME_TO_DINT(tx)) - DINT_TO_REAL(TIME_TO_DINT(tx1));(*Разница между запомненным временем и текущим*)
fr:=txr_diff/DINT_TO_REAL(TIME_TO_DINT(TIME_MAIN));(*Время за которое должна нарастать или убывать функция. Высчитывает коэффициент приращения/убавления*)
IF First<Second THEN Err:=Second - OUT; END_IF;(*0-рост*)
IF First>Second THEN Err:=OUT - Second; END_IF;(*1-падение*)
OUT:=AM * fr + OS;(*Общая линейная зависимость*)
R_TRIG(CLK:=Err< 0);(*Ждем перехода через ноль*)
IF R_TRIG.Q THEN State:=3; END_IF;
IF NOT START THEN State:=3; END_IF;
3:(*Рамп отработал*)
OUT:=TE_SP_2;(*Оставляем второе значение на выходе*)
START_TIME:=T#0m;(*Делаем визуализацию переменных времени*)
FINISH_TIME:=TIME_MAIN;(*Делаем визуализацию переменных времени*)
Complite:=TRUE;(*Выставляем признак того, что завершилось*)
IF NOT START THEN State:=0; END_IF;(*Возвращаем, если кнопка START прекратила действовать, на 0 шаг*)
END_CASE;
END_FUNCTION_BLOCK
Особенности применения
Угол наклона линейно-нарастающей функции при первоначальном воздействии (START) происходит по времени (RAMP_TIME), все последующие скачки статической уставки (SP) происходят по скорости один градус в минуту.
Рекомендации по применению
Выход с функционального блока служит уставкой для регулятора. Переменные FSP_SP FSP_PV, обеспечивают визуализацию присвоенных в теле блока значений выходу. FSP_SP присваивается в случае если измеряющая процесса перешла границу SP, а FSP_PV если на вход блока START присваивается значение FALSE. Если переменная INDIRECT активирована (TRUE), то меняется геометрическое расположение угла наклона FSP на противоположное и функция. От выбора значения этого входа зависит характер работы блока линейно-нарастающий или линейно-убывающей функци
Выкладываю еще один код данного ФБ РАМП
#РАМП, #RAMP, #Линейнонарастающаяфункция, #Управлениепроцессомнагрева
Оставьте первый комментарий