А где N и S?
Вид для печати
Вы предложили линейную зависимость - это кривая первого порядка. Константа - нулевого. Не всегда достаточно линейной функции, но и выше 3-го тоже редко применятся для практических задач. Почему Вы относитесь с сарказмом к обычным решениям?
Заказчик сам теплотехник, знает, что делает, но с программированием - никак. Установка сложнее, чем просто котёл, и 3х ходовой там есть, и не только он.
Мне была поставлена конкретная задача - сделать настраиваемую уставку в зависимости от уличной t, чем я и занимаюсь. У каждого свои цели, это верно.
[QUOTE=EFrol;458208]Ну, если очень хочется, то я бы сделал так:
Здравствуйте!Код:function PLAst: real;
var_input
Y0, Y1, Y2, Y3, Y4, Y5, Y6, Y7, Y8, Y9, Y10: real;
Y11, Y12, Y13, Y14, Y15, Y16, Y17, Y18, Y19, Y20: real;
X: real;
end_var
var
i: udint;
ri: real;
end_var
for i := 0 to 20 do
ri := udint_to_real(i);
if X * ri >= 5 * ri and X * ri < (ri + 1) * 5 then exit; end_if
end_for
case i of
0: PLAst := Y0 + (Y1 - Y0) / 5 * (X - (5 * ri));
1: PLAst := Y1 + (Y2 - Y1) / 5 * (X - (5 * ri));
2: PLAst := Y2 + (Y3 - Y2) / 5 * (X - (5 * ri));
3: PLAst := Y3 + (Y4 - Y3) / 5 * (X - (5 * ri));
4: PLAst := Y4 + (Y5 - Y4) / 5 * (X - (5 * ri));
5: PLAst := Y5 + (Y6 - Y5) / 5 * (X - (5 * ri));
6: PLAst := Y6 + (Y7 - Y6) / 5 * (X - (5 * ri));
7: PLAst := Y7 + (Y8 - Y7) / 5 * (X - (5 * ri));
8: PLAst := Y8 + (Y9 - Y8) / 5 * (X - (5 * ri));
9: PLAst := Y9 + (Y10 - Y9) / 5 * (X - (5 * ri));
10: PLAst := Y10 + (Y11 - Y10) / 5 * (X - (5 * ri));
11: PLAst := Y11 + (Y12 - Y11) / 5 * (X - (5 * ri));
12: PLAst := Y12 + (Y13 - Y12) / 5 * (X - (5 * ri));
13: PLAst := Y13 + (Y14 - Y13) / 5 * (X - (5 * ri));
14: PLAst := Y14 + (Y15 - Y14) / 5 * (X - (5 * ri));
15: PLAst := Y15 + (Y16 - Y15) / 5 * (X - (5 * ri));
16: PLAst := Y16 + (Y17 - Y16) / 5 * (X - (5 * ri));
17: PLAst := Y17 + (Y18 - Y17) / 5 * (X - (5 * ri));
18: PLAst := Y18 + (Y19 - Y18) / 5 * (X - (5 * ri));
19: PLAst := Y19 + (Y20 - Y19) / 5 * (X - (5 * ri));
20: PLAst := Y20;
end_case
end_function
Начал помаленьку разбираться с задачей. Не вижу, где в Вашем примере задаётся нижняя граница t, с которой сравнивается Х ?
Нижний порог согласован: -50
Если Х<-50, то уставка = Y0
Если -50<= Х <-45, то уставка = Y0 + (Y1-Y0)*(X - (-50)) / 5
Если -45<= Х <-40, то уставка = Y1 + (Y2-Y1)*(X - (-45)) / 5
...
Получается, в функцию надо добавить константу base := -50
И выход рассчитывать так: 0: PLAst := Y0 + (Y1 - Y0) / 5 * (X - (5 * ri + base));
Но надо и вход как-то подправить, чтоб правильно попадать в нужные Y(n)..Y(n+1), пока не понимаю как это сделать.
Можно и c базовой:
Код:function PLAst: real;
var_input
Y0, Y1, Y2, Y3, Y4, Y5, Y6, Y7, Y8, Y9, Y10: real;
Y11, Y12, Y13, Y14, Y15, Y16, Y17, Y18, Y19, Y20: real;
X: real; // Текущая
end_var
var
i: udint; // Номер отрезка
dX: real; // Смещение от начала отрезка
base: real := -50.0; // Базовая
end_var
if X < base then // Меньше базовой
i := 0;
else // Больше базовой - определяем номер отрезка
for i := 1 to 20 do // Проверяем каждый отрезок
// Если X попадает в отрезок - определяем смещения от начала отрезка и выходим из цикла
if X < base + 5 * udint_to_real(i) then
dX := X - base - 5 * udint_to_real(i - 1); exit;
end_if
// В i будет номер найденного отрезка
end_for
end_if
if X > base + 5 * 20 then i := 21; end_if // X выходит за диапазон
// Определяем значение Y
case i of
0: PLAst := Y0; // Меньше базовой
1: PLAst := Y0 + (Y1 - Y0) / 5 * dX;
2: PLAst := Y1 + (Y2 - Y1) / 5 * dX;
3: PLAst := Y2 + (Y3 - Y2) / 5 * dX;
4: PLAst := Y3 + (Y4 - Y3) / 5 * dX;
5: PLAst := Y4 + (Y5 - Y4) / 5 * dX;
6: PLAst := Y5 + (Y6 - Y5) / 5 * dX;
7: PLAst := Y6 + (Y7 - Y6) / 5 * dX;
8: PLAst := Y7 + (Y8 - Y7) / 5 * dX;
9: PLAst := Y8 + (Y9 - Y8) / 5 * dX;
10: PLAst := Y9 + (Y10 - Y9) / 5 * dX;
11: PLAst := Y10 + (Y11 - Y10) / 5 * dX;
12: PLAst := Y11 + (Y12 - Y11) / 5 * dX;
13: PLAst := Y12 + (Y13 - Y12) / 5 * dX;
14: PLAst := Y13 + (Y14 - Y13) / 5 * dX;
15: PLAst := Y14 + (Y15 - Y14) / 5 * dX;
16: PLAst := Y15 + (Y16 - Y15) / 5 * dX;
17: PLAst := Y16 + (Y17 - Y16) / 5 * dX;
18: PLAst := Y17 + (Y18 - Y17) / 5 * dX;
19: PLAst := Y18 + (Y19 - Y18) / 5 * dX;
20: PLAst := Y19 + (Y20 - Y19) / 5 * dX;
21: PLAst := Y20; // Выходит за диапазон
end_case
end_function
Да. Если есть выход из цикла, то можно.
А если номер отрезка определять делением?
Отличное предложение!!!
Код:function PLAst: real;
var_input
Y0, Y1, Y2, Y3, Y4, Y5, Y6, Y7, Y8, Y9, Y10: real;
Y11, Y12, Y13, Y14, Y15, Y16, Y17, Y18, Y19, Y20: real;
X: real; // Текущая
end_var
var
i: udint; // Номер отрезка
dX: real; // Смещение от начала отрезка
base: real := -50.0; // Базовая
end_var
if X < base then // Меньше базовой
i := 0;
else // Больше базовой - определяем номер отрезка
i := real_to_udint(X - base) / 5 + 1;
if i > 20 then i := 21; else dX := X - base - 5 * udint_to_real(i - 1); end_if
end_if
// Определяем значение Y
case i of
0: PLAst := Y0; // Меньше базовой
1: PLAst := Y0 + (Y1 - Y0) / 5 * dX;
2: PLAst := Y1 + (Y2 - Y1) / 5 * dX;
3: PLAst := Y2 + (Y3 - Y2) / 5 * dX;
4: PLAst := Y3 + (Y4 - Y3) / 5 * dX;
5: PLAst := Y4 + (Y5 - Y4) / 5 * dX;
6: PLAst := Y5 + (Y6 - Y5) / 5 * dX;
7: PLAst := Y6 + (Y7 - Y6) / 5 * dX;
8: PLAst := Y7 + (Y8 - Y7) / 5 * dX;
9: PLAst := Y8 + (Y9 - Y8) / 5 * dX;
10: PLAst := Y9 + (Y10 - Y9) / 5 * dX;
11: PLAst := Y10 + (Y11 - Y10) / 5 * dX;
12: PLAst := Y11 + (Y12 - Y11) / 5 * dX;
13: PLAst := Y12 + (Y13 - Y12) / 5 * dX;
14: PLAst := Y13 + (Y14 - Y13) / 5 * dX;
15: PLAst := Y14 + (Y15 - Y14) / 5 * dX;
16: PLAst := Y15 + (Y16 - Y15) / 5 * dX;
17: PLAst := Y16 + (Y17 - Y16) / 5 * dX;
18: PLAst := Y17 + (Y18 - Y17) / 5 * dX;
19: PLAst := Y18 + (Y19 - Y18) / 5 * dX;
20: PLAst := Y19 + (Y20 - Y19) / 5 * dX;
21: PLAst := Y20; // Выходит за диапазон
end_case
end_function
Спасибо!
После сравнения последних вариантов, надеюсь я разобрался, как они работают.
Если операция MOD работает с типом real, то нахождение dX можно упростить до
dX := X mod 5
Проверил, ошибок нет, в железе ещё не проверял.
PS: Нет, не прокатило. MOD работает только с целыми числами.
Возникла ещё ошибка/предупреждение при подключении макроса Pt1000 из онлайн базы.
Там было подключение с выхода на вход в блоке SEL_FLOAT2, заменил на линию задержки.
Вложение 82849
Всё получилось, больше всего времени ушло на пользовательское меню: вывод значений, сообщение о неисправных датчиках и настройка параметров.
В процессе понадобилось добавить гистерезис, и чтобы не изобретать велосипед, решил воспользовался поиском на этом форуме. Результатов много, но в выдаче не конкретные сообщения, а только темы с десятками-сотнями страниц. На тот момент я не разобрался в поиске, можно выводить темы, а можно сообщения. В общем, сделал по своему:
Вложение 82949
За пределами скриншота только чуть изменённый макрос PLAst от EFrol. Кстати, насчёт высоких порядков - в макросе Pt1000 из онлайн базы используется кв.корень, 1, 2, 3 и 4-я степень входного параметра. И самодельные макросы SEL_FLOAT - наверное на момент написания Pt1000 ещё не было встроенных fSEL и SEL.