хорошая мысля. но уже до этого была куплена линейка датчик уровня. установлен. даже ее сейчас не хотят переделать. и бо говорят нефиг трогать. работаем с тем что есть.
Вид для печати
Netadmin, в понедельник сброшу пример по своему датчику топлива.
Правда у меня пересчет в scada выполняется, но думаю в лоджик на ST можно сделать аналогичное.
изначально это было сделано вообще на трм Вложение 80102 но сами понимаете это вариант никакой. мало того что емкость не линейна. так еще и датчик в двух частях емкости. конус и цилиндр.
Готовая функция линейной апроксимации на 10 точек от Petera, можно снять зависимость объёма от уровня или зависимость объёма от давления.
На конус сделать 6-8 точек, выше конуса достаточно 2 точек. Тарировать в конусе и выше можно например, по 5-10 литров.
https://owen.ru/forum/showthread.php?t=35489&page=5
Спасибо неравнодушным, если что это не корыстный интерес. друг пришел на производства пластика. попросил улучшить визуализацию расхода жидкости. то-есть не как у них было в условных единицах на ТРМ а в литрах. Пока решили на конус забить. он как запас.
Можно тупо бахнуть всю таблицу в массив, и считать по нему:
Код:FUNCTION GRAPH : REAL;
VAR_INPUT
x :REAL;
END_VAR
VAR
arX: ARRAY[0..49] OF REAL := [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50];
arY: ARRAY[0..49] OF REAL := [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50];
i: udint;
END_VAR
IF x < arX[0] THEN GRAPH := arY[0];
ELSIF x > arX[49] THEN GRAPH := arY[49];
ELSE
FOR i:=0 TO 48 DO
IF x >= arx[i] AND x <= arx[i+1] THEN
GRAPH := LINEAR(x, arx[i], arx[i+1], ary[i], ary[i+1]);
END_IF;
END_FOR;
END_IF;
end_function
FUNCTION LINEAR : REAL;
VAR_INPUT
rX, rX1, rX2, rY1, rY2 : REAL;
END_VAR
IF rX2 = rX1 THEN LINEAR := rY2;
ELSE LINEAR := (rX - rX1) * (rY2 - rY1) / (rX2 - rX1) + rY1;
END_IF;
end_function
Только это подойдёт для одной плотности, если в ёмкость нальют что-то более или менее плотное, то всё коту под хвост.
Хотя для поплавкового ду пойдут. Для давления нет.
Попробовал решить задачу измерения объёма в усечённом конусе двумя способами:
1. Выразил объём прямого (полного) конуса через высоту конуса и угол между основанием и образующей (т.е. выразил радиус через высоту и подставил в формулу объёма). Далее взял три точки - начало отсчёта датчика, середину конуса и верхнюю часть конуса - для них известны и уровень и объём. Получил систему из двух уравнений относительно двух переменных - высота конуса до нижней точки измерения датчика и угол между основанием и образующей. Получил квадратное уравнение, решил.
2. Взял точки и при помощи метода наименьших квадратов нашёл полином второй степени. Тут всё просто - в институте на чисметах делал, осталась программка на Pascal. Думаю, что для тех, кто чисметы не изучал - существуют онлайн сервисы аппроксимации МНК.
Какие результаты.
Очень удивился, что лобовое решение при помощи интерполяции по 3 точкам (1-й способ) дал неудовлетворительные результаты - вместо параболы получилась функция гиперболы с перегибом.
А вот аппроксимация дала весьма хорошие результаты.
У меня нет MS Office - работаю в Libre Office, поэтому исходники прикладывать нет смысла, покажу распечатки в pdf - и вывод формулы (как оказалось не нужной) и результаты вычислений по формуле и МНК.
Итого. Как бы поступил лично я.
Нет ничего универсального и эта программа пишется не для всех конусных и не только бункеров, а для конкретного. А для конкретного бункера на диапазоне 35-60 см хорошо применим полином второй степени, коэффициенты для которого получены МНК. Поэтому решение такое:
1. на диапазоне измерений от 35 до 60 см объём вычисляется по аппроксимационному полиному.
2. на диапазоне 60 см и более - по линейной формуле для цилиндра (может придётся разбить на несколько участков)
В примере программы не стал усердствовать с точностью вычислений для цилиндрической части, просто для примера показал с каким-то коэффициентом.
Код:function BunkerVolume: real;
var_input
rLevel: real;
end_var
var
a: array [0..2] of real := [7.8577289377217835E-002, -3.0897496947466449E-003, 1.4868742368739197E-004];
rVolumeMin: real := 0.152;
rVolumeMax: real := 0.429;
rResult: real;
i: udint;
end_var
if rLevel < 35.0 then
rResult := rVolumeMin;
elsif rLevel <=60.0 then
rResult := 0;
for i := 0 to 2 do
rResult := rResult * rLevel + a[2-i];
end_for;
elsif rLevel <= 200.0 then
rResult := rVolumeMax + 0.0348 * (rLevel - 60.0);
end_if;
BunkerVolume := rResult;
end_function
Надеюсь плотность налитой жидкости не будет являться государственным секретом(тайной), непонятно к чему разговор, в смысле, даже в теплосчётчиках объём воды пересчитывается в массу в зависимости от температуры, но насколько я понял и этого товарищу не надо, в смысле, сверхвысокой точности, коль он измеритель уровня применил с точностью плюс-минус лапоть, в смысле, состоящий из линейки герконов, любой датчик избыточного давления, коих у Овена великое множество, измерит точнее, даже без пересчёта массы в объём, товарищ вроде объём хочет, при использовании тензодатчиков аналогичная ситуация!
И, совсем непонятно зачем датчики применять более чем в 10 раз дороже(наверно куры денег не клюют) датчика избыточного давления и даже дороже датчиков дифференциального давления, для измерения уровня в сосудах под избыточным давлением:
Вложение 80121
короче, маразмом попахивает, мне так кажется!
Могу добавить, примерно лет 10 назад покупали четыре датчика дифференциального давления, как раз для этой цели(о которой писал), короче, они примерно в 3 раза были дешевле овенских и к тому же и более надёжные оказались, в смысле, до сих пор работают и проблем с ними не возникало, короче, лучше в 10 раз по совокупности качеств, это по моим подсчётам, марку не буду называть, а то заругают!
https://disk.yandex.ru/d/hUyNm800NC2x5g
Всё что говорится сейчас было давно уже опробовано.
Без высшей математики все прекрасно знали ,что ? чего ? и сколько ?(за это "дадут с учётом смягчающих ")
Однако расчёты были весьма точные.
Вот примерно такая же емкость высотой 35-60 см. Это ,конечно, шутка. Но делается всё как-то гораздо проще ..
На уровне задачек для подготовки к ЕГЭ.
и этого товарищу не надо, в смысле, сверхвысокой точности, коль он измеритель уровня применил с точностью плюс-минус лапоть
Ну просто замечательно сказано..
не является тайной. обычное базовое масло для изготовления пластика. по поводу что было применено. повторяю. так видел задачу и ее реализация мастер который за пару месяцев уволился до прихода моего друга на предприятия. Собственно все что Сергей сейчас высказал. я слово в слово сказал моему другу. на что начальник сказал работаем с тем что имеем. ибо как было замечено стоил этот датчик с учетом что приехал целым только на 3 раз огого сколько. единственное на что развели "Убедили" начальника это использовать ПР200. такие дела.
Netadmin если в емкости всегда одна жидкость (одни характеристики), то работать будет.
Так, правильно, формулу получили только до уровня 60 см.
Пробовал я всю таблицу загнать в эксель - точность получается до 2%, но больше литра. Поэтому, как, вариант, разбивать таблицу на части (например 35-60, 60-85, 85-104, 104-123 и 123-140) и для каждой части высчитывать свою формулу
https://owen.ru/forum/showthread.php...l=1#post451065 ну или чуть ниже, где в массив данные записать, не помогает ?
Да ладно, загнал всю таблицу в массив через одну, вместо 108 точек получилось 54 переменных в массиве, считает правильно по таблице.Вложение 80131 с точностью 0.1%
Так как в таблице 35 см это 0, то вычел эти 35 см, только для проверки соответствия таблице. В реале вычитание можно убрать.
Таблица выложена только до 141 см, дальше массив можно продолжить. Достаточно 2-6 точек.
Netadmin,
меня интересовала принципиальная возможность решения. Сил хватило на копирование с фотографии таблицы 25 пар значений (дальше "рука бойца набирать устала").
Но все данные, методики, примеры кода я привёл, чтобы Вы дальше смогли по аналогии продолжить.
Для завершения работы я бы попробовал сначала получить график табличной зависимости в Exel (или Calc из LibOo) - просто посмотреть плавность.
Далее, попробовал при помощи МНК получить полином для всего диапазона из 100 пар чисел, проверил его в Exel. Если результаты не устроили бы - разделил бы таблицу на несколько участков и при помощи МНК для каждого нашёл бы полином.
Т.к. МНК это не интерполяция, а аппроксимация, то на стыках диапазонов потребовалось бы проверить непрерывность.
Ещё можно попробовать увеличить полином до третьей степени, т.к. объём конуса зависит от куба высоты (уровня). На диапазоне 35-60 это не проявлялось заметно, но до 140 может оказаться существенным.
Есть ещё такая штука, как интерполяция кубическими сплайнами - как раз получается серия кусочных функций (полиномов) с гладкими "стыками". Можете попробовать. Сколько помню, формулы были несложные, только у меня от ВУЗовских лабораторок исходники не сохранились. Но интернет всё порешает.
Вы уж простите старика, мне лень в выходной день несколько часов сидеть и подгонять результаты экспериментов по разделению диапазонов, по проверке повышения степени полинома.
Собственно, больше нечего добавить - алгоритмическое решение есть, остаётся только вычислить коэффициенты для формул. Что будет не получаться - спрашивайте.
Хотя kondor3000 уже предложил решение при помощи кусочно-линейной интерполяции.
https://owen.ru/forum/showthread.php...l=1#post451105
Раз оно работает - применяйте.
У меня по сути это наверное то же, что и предлагает kondor3000 при помощи кусочно-линейной интерполяции
На примере датчика топлива в баке генератора с неправильной формой. з.ы. это скрипт C#
числа в else if это показания датчика при тарировке, числа в формуле scaler вторые это литраж. Scaler - это наверное то же самое, что и LINEAR в срипте на ST от petera и kondor3000.Код:public double Benzscale (double inp)
{
double res = 0;
if (inp > 0 & inp < 773) res = Scaler (inp, 53, 773, 0, 5);
else if (inp > 773 & inp < 1468) res = Scaler (inp, 774, 1467, 5, 10);
else if (inp > 1467 & inp < 2061) res = Scaler (inp, 1468, 2060, 10, 15);
else if (inp > 2060 & inp < 2452) res = Scaler (inp, 2061, 2451, 15, 20);
else if (inp > 2451 & inp < 2870) res = Scaler (inp, 2452, 2869, 20, 25);
else if (inp > 2869 & inp < 3278) res = Scaler (inp, 2870, 3277, 25, 30);
else if (inp > 3277 & inp < 3700) res = Scaler (inp, 3278, 3699, 30, 35);
else if (inp > 3699 & inp < 4096) res = Scaler (inp, 3700, 4095, 35, 36);
return res;
}
Собственно все проще. Чем меньше диаметр конуса, тем меньше объем нужен для тарировки, так как при таком методе погрешность не накапливается, а сидит внутри каждого диапазона.
По мере увеличения диаметра конуса, можно увеличивать объем тарировочный, чтобы погрешность не выходила за какой-то диапазон.
Набрал все пары от 35 до 140Покажу все пары, вдруг кто-то захочет повторить вычисления:
пропустил через МНК и получил полином третьей степени. Он очень точно вычисляет на всём указанном диапазоне.
Не знаю, почему так ошибся - вывел зависимость объёма пропорциональную кубу уровня, но решил, что квадратичная зависимость идеально подойдёт.
Сейчас увеличил степень и всё сошлось.
Но, к слову, если бы "материально не заинтересованный, но просто помогающий другу" Netadmin сразу привёл таблицу в редактируемом виде, то время потраченное на её набор, я потратил бы на обработку.Код:Функция y(x) имет вид
y(x)=a[3]*x^3+a[2]*x^2+a[1]*x^1+a[0] ,
где
a[3]= 6,7480106322967544E-007
a[2]= 5,2652074851971609E-005
a[1]= 1,4053194590600596E-003
a[0]= 9,4316767126307200E-003
Думаю, что с разделением диапазона уровня для вычисления объёма конусной и цилиндрической частей бункера сложностей не будет.
Чтобы избежать переполнения разрядной сетки и ускорить сами вычисления, полином лучше вычислять по схеме Горнера, тут сложностей тоже быть не должно.
Будут вопросы - задавайте.
Во вложении программа с новым полиномом и инструменты расчёта и проверки - программа на Pascal, таблица для Calc (аналог Exel).
;)
Я то карты раскрыл - полином получен (методом наименьших квадратов (МНК). Там всё просто и в ВУЗах и в колледжах на чисметах преподают. Вот и у меня с ВУЗа осталась собственная реализация по методичке к лабораторке.
А как Вы получили формулы?
Мне кажется, что регрессионный анализ - это "надстройка" над МНК - при помощи пересчёта входных данных меняют формулу зависимости с полинома на другую произвольную, потом используют МНК, пересчитывают полиноминальные коэффициенты в коэффициенты из новой формулы. Часто, регрессия ограничена прямой линией - полиномом первой степени - для удобства пересчёта коэффициентов.
Это в SciLab?
Спасибо.
Богат Python библиотеками, простыми в использовании...
Видимо, нужно уже браться за ум и осваивать, хотя бы на уровне обработки строк, математического анализа.
Доброго дня)
У меня есть индикатор технологических параметров ARM-ITP2.4.P
Он работает в режиме slave, но я не могу придумать как сделать так чтобы он будучи подключенным к пр102, в зависимости от включенного входа отсчитывал 30 секунд или минуту
Доброе утро, на столе имею: ПЛК110-60 и УПП ONI SFB (3 шт.) с RS485.
Подскажите, как правильно их опросить?
У них по умолчанию у всех 1 адрес. Т.е. сначала ПЛК должен обратиться к каждому отдельно, перезаписать адрес. И потом уже ко всем вместе для считывания сигналов работа/авария?
Делаете опрос одного, включаете по одному и меняете адреса, потом включаете все вместе с разными адресами.
Опросить и поменять адреса можно любым ОРС сервером, например Овен ОРС https://owen.ru/catalog/opc_serveri
Благодарю, попробую.
Время и чтобы он сбрасывался по достижению определенной уставки
Здравствуйте. Только начинаю знакомиться с ПР200.
Есть два ПР200, стоят в разных местах. Подскажите, пожалуйста, как на первом реле узнать, что на втором сработал какой-то дискретный вход?
Заранее спасибо.