
Сообщение от
Stranger199017
Здравствуйте. Знающие люди подскажите существует ли макрос с нелинейным масштабированием для пр100. Необходимо подключить датчик температуры NTC 10k. Пока вышел из ситуации использую 10 макросов Scale из онлайн библиотеки макросов.
Смотреть под спойлером аналоговые преобразования https://owen.ru/forum/showthread.php...l=1#post397000
Код:
function fNTC: Real; // Универсальный датчик типа NTC, необходимо указывать R0 и B25/100
var_input
R:real;
R0:Real;
B:Real;
end_var
//PRG
fNTC:=1/(1/298.15+1/B*fLn(R/R0))-273.15; // вызов функции "fLn"
end_function
логарифм
Код:
function fLn: Real; //Натуральный логарифм
var_input
X:real;
end_var
//PRG
fLn:=0.6931472*fLb(x); //вызов функции "fLb"
end_function
двоичный логарифм
Код:
function fLb: Real; //Двоичный логарифм
var_input
X:real;
end_var
var
s:real:=0.0;
a:real:=0.5;
i:udint;
b:real;
end_var
//PRG
if X>0 then
if X>=1 then
b:=1;
X:=X;
else
b:=-1;
X:=1/X;
end_if
if x>2 then
s:=udint_to_real( cd32(real_to_udint(x)));
X:=X/ pow(2,s);
end_if;
for i:=0 to 16 do
x:=x*x;
if x>2 then
x:=x/2;
s:=s+a;
end_if;
a:=a*0.5;
end_for
fLb:=s*b;
end_if
end_function
ЗЫ.
использую 10 макросов Scale из онлайн библиотеки макросов.
(кусочно-линейная аппроксимация) по 10 точкам https://owen.ru/forum/showthread.php...l=1#post369459
Код:
function PLA_ST: real; // (c) PeterA
var_input //объявление входных переменных
x1: real;
x2: real;
x3: real;
x4: real;
x5: real;
x6: real;
x7: real;
x8: real;
x9: real;
x10: real;
y1: real;
y2: real;
y3: real;
y4: real;
y5: real;
y6: real;
y7: real;
y8: real;
y9: real;
y10: real;
In: real;
end_var
var //объявление локальных переменных
a:udint; (*Начало интервала поиска*)
b: udint; (*Конец интервала поиска*)
N: udint; (*Число точек в графике*)
i: udint;
x: array [0..9] of real;
y: array [0..9] of real;
end_var
N:= 10;
x[0]:= x1;
x[1]:= x2;
x[2]:= x3;
x[3]:= x4;
x[4]:= x5;
x[5]:= x6;
x[6]:= x7;
x[7]:= x8;
x[8]:= x9;
x[9]:= x10;
y[0]:= y1;
y[1]:= y2;
y[2]:= y3;
y[3]:= y4;
y[4]:= y5;
y[5]:= y6;
y[6]:= y7;
y[7]:= y8;
y[8]:= y9;
y[9]:= y10;
(*Начальные значения интервала поиска*)
a:=0;
b:=N-1;
(*Обрезание графика для крайних точек*)
IF IN<=x[0] THEN
PLA_ST:=y1;
ELSIF IN>= x[N-1] THEN
PLA_ST:= y[N-1];
(*Теперь можно начать поиск*)
ELSE
WHILE (b-a) <> 1 DO (*В конце концов, входной сигнал ТОЧНО попадет между двумя соседними точками X(a) и Х(а+1)*)
i:=(a+b)/2; (*Делим интервал поиска пополам*)
IF IN=x[i+1] THEN (*Может нам повезло, и мы сразу нашли точку? *)
a:=i; b:=i+1; (*Бинго! прекращаем итераций, нечего в пустую молотить :) *)
(*мимо :( ,тогда посмотрим в какую половину интервала попали*)
ELSIF IN>x[i] THEN (*Если входной сигнал больше середины интервала поиска,*)
a:=i; (*то следующий поиск будем делать начиная от середины и до конца массива*)
ELSE (*А если входной сигнал меньше середины интервала поиска,*)
b:=i; (*то следующий поиск будем делать начиная от начала и до середины массива*)
END_IF
(*Таким образом на каждой итерации отбрасываем из поиска заведомо ненужную половину значений
две соседние координаты X(a) и Х(а+1), меду которыми попадает входной сигнал найдем очень быстро
для 8 точек графика нужно не более 3 итераций
при 9..16 точек в графике нужно не более 4 итераций
при 17..32 точек в графике нужно не более 5 итераций
при 33..64 точек в графике нужно не более 6 итераций
при 65..128 точек в графике нужно не более 7 итераций
инфа точная - 100% ;) *)
END_WHILE;
(*Теперь самое простое - сделать линейную аппроксимацию по двум точкам ;) *)
PLA_ST:= y[b] - (x[b] - IN) * (y[b] - y[a]) / (x[b] - x[a]);
END_IF
end_function