Вопрос разработчикам ОЛ: в планах есть реализовать возможность применения ФБ на ST в макросах?
Вид для печати
Интересно как бы выглядел макрос на ST для PT1000 (П)???
приблизительно как в базовой oscat библиотеке функции TEMP_PT или RES_PT
или так ещеЦитата:
function Solver: real;
var_input
res : real;
end_var
var
W1, W2, W3, W4, W5, W6, W7, W8 : real;
X : real;
end_var
if res < 80.306 or res > 174.016 then
Solver := 3.402824E+38;
else
X := res;
W1 := X * -0.01762491988258928 + 2.2043139613577374;
W2 := X * 0.6400488968662336 + -23.674505917485266;
W3 := X * 0.0031304507906330763 + -16.89945922108154;
W4 := X * 0.018556566294323017 + 0.25613106090327786;
W5 := X * 0.0006476412362364319 + -0.04368540456173019;
W6 := X * -0.017567624863696805 + 1.7862783116150094;
W7 := X * 0.01082710470500994 + -0.6758584965318757;
W8 := X * 0.20777585219031725 + -31.05972211421347;
if W1 <= 0.0 then W1 := 0.0; end_if;
if W2 <= 0.0 then W2 := 0.0; end_if;
if W3 <= 0.0 then W3 := 0.0; end_if;
if W4 <= 0.0 then W4 := 0.0; end_if;
if W5 <= 0.0 then W5 := 0.0; end_if;
if W6 <= 0.0 then W6 := 0.0; end_if;
if W7 <= 0.0 then W7 := 0.0; end_if;
if W8 <= 0.0 then W8 := 0.0; end_if;
Solver := W1 * 2.951575310396745 + W2 * 4.116406053413549 + W3 * -0.5520606526690841 + W4 * -0.0006347054648307377 + W5 * 0.0019590873049887846 + W6 * 2.3390859627862177 + W7 * 0.021819488290564692 + W8 * 0.2417143920895591 + -167.4311587881956;
end_if;
end_function
// score 0.999999622
// 10 103.903
// 20 107.794
// 40 115.541
// 80 130.897
Сдается мне что capzap не хочет пускать rovki в ST
В компонентах есть такой код
https://ftp-ow.owen.ru/softupdate/OW...ns/fPt1000.txt
https://ftp-ow.owen.ru/softupdate/OW...c/STFunctions/
Судя по всему, он опирается на другие функции из тех же компонентов.Код:function fPt1000: Real; // функция для датчика термосопротивления PT1000
var_input //объявление входных переменных
R:Real;
end_var
var //объявление локальных переменных
RtR0: Real;
R0: Real:= 1000;
A: Real:= 0.0039083;
B: Real:= -5.775E-07;
D1: Real:= 255.819;
D2: Real:= 9.14550;
D3: Real:= -2.92363;
D4: Real:= 1.79090;
end_var
//PRG
RtR0:= R/R0;
if R>R0 then
fPt1000:=(pow((A*A-4*B*(1-RtR0)),0.5)-A)/(2*B);
else
fPt1000:=fPol_4((RtR0-1),4,0,D1,D2,D3,D4); //вызов функции "fpol_4"
end_if
end_function
Я бы, наверное, попробовал корень квадратный через формулу Ньютона вычислять с ограничением количества итераций.
А полином - без функции, но через схему Горнера, а не так, как в примере.
Код:function fPol_4: Real; //функция вычисления полинома 4й степени
var_input //объявление входных переменных
X : Real;
exp: udint; // степень
D0: Real;
D1: Real;
D2: Real;
D3: Real;
D4: Real;
end_var
var //объявление локальных переменных
i: udint;
d: array [0..4] of Real;
end_var
//PRG
fPol_4:=0;
d[0]:=d0;
d[1]:=d1;
d[2]:=d2;
d[3]:=d3;
d[4]:=d4;
for i := 0 to exp do
fPol_4:=fPol_4 + d[i]*pow(X,udint_to_real(i));
end_for
end_function
Тьфу!..
Стошнило!
Не делайте так!
Про pow поторопился - встроенная функция и корень, наверное, так быстрее извлекать.
Но полином при помощи pow - это позор!
ГОСТ 6651-2009 содержит полиномы и коэффициенты для термопреобразователей сопротивления.
Для платиновых форма зависимости идентичная, но отличаются коэффициенты.
Для Pt1000 (0,00385) они перечислены в исходнике выше.
Для 1000П (0,00391) они равны
Формулы в исходнике соответствуют ГОСТ.Код:R0: Real:= 1000;
A: Real:= 0.0039690;
B: Real:= -5.841E-07;
D1: Real:= 251.903;
D2: Real:= 8.80035;
D3: Real:= -2.91506;
D4: Real:= 1.67611;
Т.е. заменив коэффициенты на указанные, можно получить макрос для 1000П.
Единственно, я бы заменил вычисление полинома в одну строку и даже без цикла.
Код:function f1000P: real;
var_input
R : real;
end_var
var
RtR0: Real;
R0: Real:= 1000;
A: Real:= 0.0039690;
B: Real:= -5.841E-07;
D1: Real:= 251.903;
D2: Real:= 8.80035;
D3: Real:= -2.91506;
D4: Real:= 1.67611;
end_var
RtR0:= R/R0;
if R>R0 then
f1000P:=(pow((A*A-4*B*(1-RtR0)),0.5)-A)/(2*B);
else
RtR0 := RtR0 - 1;
f1000P := (((((D4 * RtR0) + D3) * RtR0) + D2) * RtR0 + D1) * RtR0;
end_if
end_function
Мдя. Здорово всё так.
0.1...0.2* градуса лоховская точность же.
не иначе как что-то суперпрецизионное.
Думаю клиент так и задает с суровым лицом
57.4576 *С
Ни 0.0001 градусом меньше
Да ведь и исходное сопротивление - суперпрецизионное. Максимум же 0.000001%.
Грех это не заполиномить.
вопрос по работе таймеров в функциональных блоках на ST :confused:
создал проект на ПР103, сделал функциональный блок на ST, добавил таймеры TON и TOF, они себя ведут странно в том плане, что в них будто сохраняется отсчет времени, который был начат при предыдущей подаче сигнала на вход. например таймер на 10 сек, подали сигнал на вход, таймер успел отсчитать 5 сек, потом убираем сигнал, при следующей подче сигнала на вход таймер сразу подавал сигнал на выходе.
пересобрал то же самое на блоках, там все нормально, если нет сингала на входе, то таймер сбрасывается.
это потому что у функциональных блоков свои особенности в плане выделения памяти и прочего или чем объяснить такое поведение таймеров на ST?
Покажи код пожалуйста.
Если таймер находится внутри условий типа IF и CASE - то надо уметь его правильно вызывать, чтобы он корректно работал.
Напоминаю мою статью про это (заголовок 7): https://cs-cs.net/funkciya-fun-i-fun...n_tof_tp_blink
Если есть время - прочитай, проверь, так или нет.
Если всё так, как по статье - то тогда лучше писать в ТехПоддержку ОВЕНа.
Чтобы отсчёт таймера ТОN сбросился - его надо ВЫЗВАТЬ со значением FALSE на входе (примерно так fbTON(I := FALSE);). Tсли вы вызываете TON только тогда, когда на входе TRUE - вы получите именно такое поведение, как описали (обычно это вызов тамqера внутри IF).
Отсутствие в FBD конструкции "IF" исключает возникновение ошибок такого рода