Интересно как бы выглядел макрос на 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.
Мдя. Здорово всё так.
0.1...0.2* градуса лоховская точность же.
не иначе как что-то суперпрецизионное.
Думаю клиент так и задает с суровым лицом
57.4576 *С
Ни 0.0001 градусом меньше
Да ведь и исходное сопротивление - суперпрецизионное. Максимум же 0.000001%.
Грех это не заполиномить.
вопрос по работе таймеров в функциональных блоках на ST
создал проект на ПР103, сделал функциональный блок на ST, добавил таймеры TON и TOF, они себя ведут странно в том плане, что в них будто сохраняется отсчет времени, который был начат при предыдущей подаче сигнала на вход. например таймер на 10 сек, подали сигнал на вход, таймер успел отсчитать 5 сек, потом убираем сигнал, при следующей подче сигнала на вход таймер сразу подавал сигнал на выходе.
пересобрал то же самое на блоках, там все нормально, если нет сингала на входе, то таймер сбрасывается.
это потому что у функциональных блоков свои особенности в плане выделения памяти и прочего или чем объяснить такое поведение таймеров на ST?
Покажи код пожалуйста.
Если таймер находится внутри условий типа IF и CASE - то надо уметь его правильно вызывать, чтобы он корректно работал.
Напоминаю мою статью про это (заголовок 7): https://cs-cs.net/funkciya-fun-i-fun...n_tof_tp_blink
Если есть время - прочитай, проверь, так или нет.
Если всё так, как по статье - то тогда лучше писать в ТехПоддержку ОВЕНа.
Пишите код так, как будто сопровождать его будет склонный к насилию психопат, который знает, где вы живёте. © Steve McConnell
Мой рабочий блог со статьями про щиты и автоматику ОВЕН - Cs-Cs.Net | Почта: Info@Cs-Cs.Net | Канал в ТГ @CsCsNetLab
Чтобы отсчёт таймера ТОN сбросился - его надо ВЫЗВАТЬ со значением FALSE на входе (примерно так fbTON(I := FALSE). Tсли вы вызываете TON только тогда, когда на входе TRUE - вы получите именно такое поведение, как описали (обычно это вызов тамqера внутри IF).
Отсутствие в FBD конструкции "IF" исключает возникновение ошибок такого рода