-
Notifications
You must be signed in to change notification settings - Fork 5
/
NONLIN.scl
100 lines (100 loc) · 6.16 KB
/
NONLIN.scl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
FUNCTION_BLOCK FB115
TITLE =" nonlinear static funktion"
AUTHOR : AUT_1
FAMILY : MODCONT
NAME : NONLIN
VERSION : " 1.0"
// reverse by komatic
(*
С помощью нелинейной статической функции NONLIN входной
сигнал, например, измеренный сигнал от термоэлемента, может
быть преобразован в выходной сигнал согласно требуемому закону
преобразования.
Точки функции NONLIN хранятся в блоке данных общего
использования. Функция NONLIN назначает каждому входному
значению определенное выходное значение. Если уровень
входного сигнала ниже, чем значение в точке 0, то
соответствующее ему значение экстраполируется с наклоном
функции, как между точками 0 и 1; если же значение входного
сигнала выше, чем значение в последней точке (NBR_PTS), то
соответствующее ему значение экстраполируется с наклоном
функции, как между точками NBR_PTS и (NBR_PTS –1). Для
получения практически пригодных результатов с использованием
данного блока значения функции для соседних точек должны
представлять собой монотонно возрастающую
последовательность.
При использовании определенных параметров управления
отдельные выбранные входные сигналы или собственно входная
переменная могут непосредственно передаваться на выход блока
в качестве выходной переменной.
Блок-схема NONLIN Обозначение
*)
VAR_INPUT
INV : REAL ; //входная переменная
DF_OUTV : REAL ; //значение выхода по умолчанию
DB_NBR : BLOCK_DB ; //номер блока данных
DFOUT_ON : BOOL ; //включить выход по умолчанию
TRACK : BOOL ; //передача входа на прямую на выход OUTV=INV
COM_RST : BOOL ; //полный рестарт
END_VAR
VAR_OUTPUT
OUTV : REAL ; //выходная переменная
END_VAR
VAR
n : INT := 1; //текущий указатель на масив
END_VAR
VAR_TEMP
EndPosition : BOOL ; //признак завершения поиска
Factor : REAL ; //кфт наклона (y2 - y1)/(x2 - x1)
rBegin : REAL ; //актуальное начало входного диапазона
rEnd : REAL ; //актуальный конец входного диапазона
END_VAR
BEGIN
IF COM_RST // Если сброс
THEN
n:=1;
OUTV:=0.0;
ELSIF TRACK // Если передача входа на выход
THEN
OUTV:=INV;
ELSE
EndPosition:=0; // признак конца поиска
//------------------------------------------------------------------
REPEAT
rBegin:=DWORD_TO_REAL(DB_NBR.DD[(n-1)*8+2]); // считали вход первой точки X1
rEnd:=DWORD_TO_REAL(DB_NBR.DD[n*8+2]); // считали вход второй точки X2
IF INV>rBegin // если входная переменная больше X1
THEN
IF INV>rEnd // и если входная переменная больше X2
THEN
IF n < WORD_TO_INT(DB_NBR.DW[0]) // если указатель меньше размера таблицы
THEN
rBegin:=rEnd; // X1:=X2
n:=n+1; // увеличиваем указатель
rEnd:=DWORD_TO_REAL(DB_NBR.DD[n*8+2]); // X2:=X2[n]
ELSE
EndPosition:=1; // поиск закончен
END_IF;
ELSE
EndPosition:=1; // поиск закончен
END_IF;
ELSE
IF n > 1 // если указатель больше 1
THEN
n:=n-1; // уменьшаем указатель
rEnd:=rBegin; // X2:=X1
rBegin:=DWORD_TO_REAL(DB_NBR.DD[(n-1)*8+2]); // X1:=X[n-1]
ELSE
EndPosition:=1; // поиск завершен
END_IF;
END_IF;
UNTIL EndPosition // до тех пор пока поиск не завершен
END_REPEAT;
//------------------------------------------------------------------
//Factor:=(Y2 - Y1)/(X2 - X1)
Factor:=(DWORD_TO_REAL(DB_NBR.DD[n*8+6]) - DWORD_TO_REAL(DB_NBR.DD[(n-1)*8+6]))/(rEnd-rBegin);
// OUTV:=Factor*INV+Y1-(X1*rFactor)
OUTV:=INV*Factor + DWORD_TO_REAL(DB_NBR.DD[(n-1)*8+6]) - rBegin*Factor;
END_IF;
IF DFOUT_ON THEN OUTV:=DF_OUTV; END_IF; // если выход по умолчанию
END_FUNCTION_BLOCK