(* @NESTEDCOMMENTS := 'Yes' *)
(* @PATH := '\/FB\/Unity' *)
(* @OBJECTFLAGS := '0, 8' *)
(* @SYMFILEFLAGS := '2048' *)
FUNCTION_BLOCK RAMP
VAR_INPUT
PV:REAL:=0.0;(*Переменная процесса*)
SP:REAL:=0.0; (*Уставка, к которой стремимся*)
RAMP_TIME:TIME;
INDIRECT:BOOL;
PLC_TIME:TIME;
START:BOOL;
STOP:BOOL;
END_VAR
VAR_OUTPUT
OUT:REAL:=0.0;(*Выход с блока*)
END_VAR
VAR
Selection:INT;
FSP_SP:BOOL;
FSP_PV:BOOL;
R_TRIG:R_TRIG;
AM:REAL;
OS:REAL;
Err:REAL;
PT:TIME;
Second:BOOL;
tx:TIME;
txr_diff:REAL;
tx1:TIME;
fr:REAL;
fr1:REAL;
END_VAR
(* @END_DECLARATION := '0' *)
CASE Selection OF
0:
Selection:=1;
(*Инициализация процесса*)
1:
AM:=SP - PV;
OS:=PV;
PT:=RAMP_TIME;
Second:=FALSE;
Err:=0.0;
R_TRIG (CLK:=FALSE);
IF START THEN Selection:=2; END_IF;
(*Если сетпоинт больше измеренной, то начинаем рост рамп, если меньше, то приравниваем плавающую к уставке*)
2:
IF SP < PV AND NOT INDIRECT THEN Selection:=3;
ELSIF SP > PV AND INDIRECT THEN Selection:=3;
ELSIF SP > PV AND NOT INDIRECT THEN Selection:=4;
ELSIF SP < PV AND INDIRECT THEN Selection:=4; END_IF;
IF STOP THEN Selection:=11; END_IF;
(* Присваиваем плавающей значение уставки*)
3:
OUT:=SP;
FSP_SP:=TRUE;
FSP_PV:=FALSE;
IF SP < PV AND NOT INDIRECT THEN Selection:=1;
ELSIF SP > PV AND INDIRECT THEN Selection:=1; END_IF;
IF STOP THEN Selection:=11; END_IF;
(* Подготавливаем внутренние переменные к подсчету рамп*)
4:
tx:=T#0s;
tx:=T#0s;
Err:=4.0;
AM:=SP - PV;
OS:=PV;
IF NOT Second THEN Selection:=5;
ELSIF Second THEN Selection:=6; END_IF;
IF STOP THEN Selection:=11; END_IF;
(* Двигаем рамп за заданный период времени*)
5:
R_TRIG (CLK:=TRUE);
FSP_SP:=FALSE;
FSP_PV:=FALSE;
IF R_TRIG.Q THEN tx1:=PLC_TIME; END_IF;
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(PT));
fr1:=fr - INT_TO_REAL(TRUNC(fr)); (*возвращает целочисленную часть числа с плавающей запятой.*)
OUT:=AM * fr1 + OS;
IF NOT INDIRECT THEN Err:=SP - OUT;
ELSIF INDIRECT THEN Err:=OUT - SP; END_IF;
IF Err <= ABS(AM/100.0)+ 0.3 OR (PV>SP AND NOT INDIRECT) OR (PV