Конечно можно, но это все время, которое можно было бы и не тратить, когда вот они, готовые лежат. А теребить постоянно людей с форума тоже не выход.
Вообще, я сейчас не конкретную задачу решаю, а просто нашел время поковырять новый функционал в виде ST - и понимаю, что ему еще очень далеко до совершенства.
А то, что блок на ST нельзя вставить в обычный макрос - вообще жуть, ставит крест на красивом структурированном проекте, все придется пихать в один экран. На презентациях Овен говорит о замене ПЛК63/73 на ПРххх, (в которых вообще не надо задуматься, какой блок на чем написан, вызываешь их друг из друга в произвольном порядке), а тут такое :/.
Интересно как бы выглядел макрос на 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
Bad programmers worry about the code. Good programmers worry about data structures and their relationships
среди успешных людей я не встречала нытиков
Барбара Коркоран
Сдается мне что 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
Последний раз редактировалось FPavel; 28.03.2025 в 21:52.