Автор |
Сообщение |
|
|
Заголовок сообщения: |
Re: Линейная апроксимация |
Цитата |
|
Спасибо,буду пробовать.
Спасибо,буду пробовать.
|
|
|
![Сообщение Сообщение](./styles/subsilver2/imageset/icon_post_target.gif) |
Добавлено: 02 июл 2012, 20:53 |
|
|
![](images/spacer.gif) |
|
|
Заголовок сообщения: |
Re: Линейная апроксимация |
Цитата |
|
[quote="aui2002"]Вы не могли бы проверить,что-то я там накрутил с переменными.Там и int, и float.[/quote] Да я тут не ахти какой проверяльщик, т.к. на Си больше читаю, чем пишу, а потому всех тонкостей языка не чувствую... Тем не менее, посмотрел, явного "криминала" не видно.
[quote="aui2002"]Там и int, и float. Вроде работает,но может можно как-то упростить.[/quote] В смысле упростить? За счет смены типа переменной особого упрощения не получится...
Можно слегка оптимизировать математику.
Например, у Вас идет выбор интервала с последовательной проверкой от 1 до 8. Это не оптимальный алгоритм, т.к. производится много пустых проверок. Наиболее оптимальный вариант поиска соответствия числу интервала - "метод середины отрезка" (как по научному называется, не помню).
Выглядит это следующим образом. Допустим, есть отрезок от 0 до 8, разбитый на 8 интервалов: [0;1);[1;2);[2;3);[3;4);[4;5);[5;6);[6;7);[7;8], и некоторое число A. Нужно определить, в какой интервал оно попадает. (Квадратная скобочка в интервале говорит о том, что крайнее число входит в интервал, круглая - что не входит, т.е. при шаге 0,1 в первый интервал войдут 0;0,1;0,2;0,3;0,4;0,5;0,6;0,7;0,8;0,9. А вот 1 уже будет принадлежать второму интервалу)
1) Разбиваем отрезок пополам. Середина у него получается между 4-м и 5-м интервалами. Проверяем в какую половину попадет число А, т.е. смотрим А<4 или нет. 2) Ту половину, в которую попало число еще раз бьем пополам. Середина попадает между 2-м и 3-им либо между 6-м и 7-м интервалом. Проверяем в какую половинку половинки (четверть) попадает А, т.е. смотрим А<2 либо А<6, в зависимости от того в какую часть отрезка попали в п.1. 3) Теперь уже делим пополам ту четвертинку, в которую попали в п.2. Сравниваем А с соответствующим граничным значением значением, и, оп-ля, мы уже знаем, в каком интервале лежит число.
Таким образом, чтобы понять, в какой интервал попадает число, нам нужно сделать максимум 3 проверки, а не максимум 8, как в Вашем варианте.
Кстати, какое [u]во время движения[/u] должно быть нормальное давление масла? Если 3 кгс/см2 и больше, то такты МК будут ощутимо экономиться.
Ну еще можно попробовать интерполяцию через пропорцию, тогда в теле ифа можно обойтись одним (на крайняк, двумя) выражением, вместо трех. Поправки в данном случае тоже можно вводить в каждый интервал, поэтому не думаю, что точность пострадает...
|
|
|
![Сообщение Сообщение](./styles/subsilver2/imageset/icon_post_target.gif) |
Добавлено: 01 июл 2012, 00:44 |
|
|
![](images/spacer.gif) |
|
|
Заголовок сообщения: |
Re: Линейная апроксимация |
Цитата |
|
3) Отказаться от аппроксимации и попробовать интерполяцию между двумя точками, но ресурсов это отъест немерено и не факт, что даст хороший результат...
Контроллер mega8A. Памяти заняло 2,7К. Вы не могли бы проверить,что-то я там накрутил с переменными.Там и int, и float.Вроде работает,но может можно как-то упростить. В интервалах 0-1,1-2 погрешность была - 0,3 ,на остальных - 0,2. Программно подкорректировал и все совпало до десятых. Очень доволен.
3) Отказаться от аппроксимации и попробовать интерполяцию между двумя точками, но ресурсов это отъест немерено и не факт, что даст хороший результат...
Контроллер mega8A. Памяти заняло 2,7К. Вы не могли бы проверить,что-то я там накрутил с переменными.Там и int, и float.Вроде работает,но может можно как-то упростить. В интервалах 0-1,1-2 погрешность была - 0,3 ,на остальных - 0,2. Программно подкорректировал и все совпало до десятых. Очень доволен.
|
|
|
![Сообщение Сообщение](./styles/subsilver2/imageset/icon_post_target.gif) |
Добавлено: 29 июн 2012, 07:59 |
|
|
![](images/spacer.gif) |
|
|
Заголовок сообщения: |
Re: Линейная апроксимация |
Цитата |
|
[quote="avrmastak"]Все,как всегда,оказалось гораздо проще! Взял 8 участков,каждый участок разделил на 10.Получил точность 0,1.Затем с помощью ифов определяю участок,и от верхнего значения отнимаю результат АЦП. Все отлично работает! Плюс есть возможность корректировки каждого участка. И не надо никаких ужасных формул.[/quote] Это, по сути, 3-ий вариант: интерполяция по дискретным участкам (см. пост от 23 июня). Правда, реализация только через одни ифы по 80-и участкам получается громоздкая. Обычно интервал бьют на достаточно крупные части (в вашем случае хватило бы восьми через единицу), потом смотрят, в какой интервал попадает значение, а внутри интервала считают через пропорцию по формуле вида Х=(a*b)/c. Но и Ваш вариант неплох, если обеспечивает необходимые точность и быстродействие. Ну и если прошивка в контроллер помещается )).
Кстати, на каком МК в итоге остановились?
[quote="avrmastak"]Но, все-равно, СПАСИБО за консультации, узнал для себя много нового, надеюсь в будущем пригодится. [/quote] Да не за что )) Обращайтесь ))
|
|
|
![Сообщение Сообщение](./styles/subsilver2/imageset/icon_post_target.gif) |
Добавлено: 29 июн 2012, 00:21 |
|
|
![](images/spacer.gif) |
|
|
Заголовок сообщения: |
Re: Линейная апроксимация |
Цитата |
|
Но, все-равно, СПАСИБО за консультации, узнал для себя много нового, надеюсь в будущем пригодится.
Но, все-равно, СПАСИБО за консультации, узнал для себя много нового, надеюсь в будущем пригодится.
|
|
|
![Сообщение Сообщение](./styles/subsilver2/imageset/icon_post_target.gif) |
Добавлено: 28 июн 2012, 23:58 |
|
|
![](images/spacer.gif) |
|
|
Заголовок сообщения: |
Re: Линейная апроксимация |
Цитата |
|
Все,как всегда,оказалось гораздо проще! Взял 8 участков,каждый участок разделил на 10.Получил точность 0,1.Затем с помощью ифов определяю участок,и от верхнего значения отнимаю результат АЦП. Все отлично работает! Плюс есть возможность корректировки каждого участка. И не надо никаких ужасных формул.
Все,как всегда,оказалось гораздо проще! Взял 8 участков,каждый участок разделил на 10.Получил точность 0,1.Затем с помощью ифов определяю участок,и от верхнего значения отнимаю результат АЦП. Все отлично работает! Плюс есть возможность корректировки каждого участка. И не надо никаких ужасных формул.
|
|
|
![Сообщение Сообщение](./styles/subsilver2/imageset/icon_post_target.gif) |
Добавлено: 28 июн 2012, 23:56 |
|
|
![](images/spacer.gif) |
|
|
Заголовок сообщения: |
Re: Линейная апроксимация |
Цитата |
|
[quote="avrmastak"] Е - это экспонента, т.е. подставлять 2,71828? [/quote] Нет, это не экспонента, а порядок, т.е. степень числа 10. Экспонента обозначается маленькой e. Сокращенная запись, чтобы не папиться с кучей нулей Например: [b]2E3=2*10^3(два умножить на десять в кубе)=2*1000=2000[/b] или [b]2E-3=2*10^-3(два умножить на десять в минус третьей степени)=2*0,001=0,002[/b]
[quote="avrmastak"]И как понять выражение -6E-07x3?[/quote] -6E-07x3=-6*0,0000007*X*X*X (х3=икс в кубе). Тут Вас, видимо, смутил ноль перед семеркой? Он просто отбрасывается и получается -6E-7x^3 (значком ^ иногда обозначают степень)
Для функции P=f(R) вместо Х подставляем наше R2, которое считается все по той же формуле: R2= -(ADC*R1*Vref)/(ADC*Vref-Vin*1024)
[quote="avrmastak"]Не очень силен в математике.[/quote] Как говорит моя мама: абсолютно все знать и уметь невозможно. 8-)
|
|
|
![Сообщение Сообщение](./styles/subsilver2/imageset/icon_post_target.gif) |
Добавлено: 23 июн 2012, 23:02 |
|
|
![](images/spacer.gif) |
|
|
Заголовок сообщения: |
Re: Линейная апроксимация |
Цитата |
|
Можно еще вопрос... Не очень силен в математике. В формуле y = -6E-07x3 + 0,0003x2 - 0,0787x + 11,045 Е - это экспонента, т.е. подставлять 2,71828? И как понять выражение -6E-07x3?
Можно еще вопрос... Не очень силен в математике. В формуле y = -6E-07x3 + 0,0003x2 - 0,0787x + 11,045 Е - это экспонента, т.е. подставлять 2,71828? И как понять выражение -6E-07x3?
|
|
|
![Сообщение Сообщение](./styles/subsilver2/imageset/icon_post_target.gif) |
Добавлено: 23 июн 2012, 21:46 |
|
|
![](images/spacer.gif) |
|
|
Заголовок сообщения: |
Re: Линейная апроксимация |
Цитата |
|
По датчику ... Нашел только это: "Датчик ММ393А при отсутствии давления должен иметь сопротивление 310...320 Ом, при давлении в 4 кг/см2 — 115...130 Ом, при давлении в 6 кг/см2 — 55...65 Ом, при давлении в 8 кг/см2 — 0...15 Ом." Значения сопротивления в остальных точках мерял сам,подавая воздух с компрессора и меряя тестером. Мои значения почему-то отличаются от заявленных.
По контроллеру ... Завтра переделаю под mega8 и попробую вариант №2.
Вложения: |
393.rar [221.15 КБ]
Скачиваний: 712
|
По датчику ... Нашел только это: "Датчик ММ393А при отсутствии давления должен иметь сопротивление 310...320 Ом, при давлении в 4 кг/см2 — 115...130 Ом, при давлении в 6 кг/см2 — 55...65 Ом, при давлении в 8 кг/см2 — 0...15 Ом." Значения сопротивления в остальных точках мерял сам,подавая воздух с компрессора и меряя тестером. Мои значения почему-то отличаются от заявленных.
По контроллеру ... Завтра переделаю под mega8 и попробую вариант №2.
|
|
|
![Сообщение Сообщение](./styles/subsilver2/imageset/icon_post_target.gif) |
Добавлено: 23 июн 2012, 21:27 |
|
|
![](images/spacer.gif) |
|
|
Заголовок сообщения: |
Re: Линейная апроксимация |
Цитата |
|
Вложения: |
Exel.xls [28.5 КБ]
Скачиваний: 732
|
[quote="avrmastak"]Вариант P=f(ADC) мне кажется самый достоверный. [/quote] Да не сказал бы... Если судить по коэффициенту детерминированности (R^2), они очень близки по точности относительно друг друга. Аппроксимация тем точнее, чем R^2 ближе к 1. А если смотреть чисто формально, то самый большой R^2 у P=f(R). Но это различие уже в тысячных долях, так что не особо существенно...
[quote="avrmastak"]Только как быть с точками 0 и 1? Или написать if(adc>857){buf[1]=buf[2]=0;}. Если меньше 2 атм выводить нули?[/quote] Строго говоря, обоснованной считается только искусственная "подмена" крайних точек, поэтому я бы так не делал... Пусть при значении adc=932 выводится 0, а все что выше считается по формуле.
Тут можно задуматься о повышении точности аппроксимации. Навскидку, есть 3 варианта: 1) Увеличить количество калибровочных точек до 30-35 (условие малой выборки), причем на проблемном интервале 0-2 точек должно быть больше, чем на любом из остальных. 2) Заменить линейную аппроксимирующую функцию на полином 3-ей степени, например, Тогда R^2 станет где-то 0,992-0,997 (см. вложение). 3) Отказаться от аппроксимации и попробовать интерполяцию между двумя точками, но ресурсов это отъест немерено и не факт, что даст хороший результат...
Можно также, в порядке эксперимента, объединить варианты 1 и 2, т.е. 30 точек и кубическая аппроксимация.[quote="avrmastak"]Контроллер - tiny26.[/quote] Как говорится, маловато будет... ) Тем более, если начинать борьбу за точность показаний и в последующем делать автокалибровку.
А автокалибровку, мне кажется, со временем все-таки придется добавлять, т.к. сезонные перепады температур все равно будут влиять на точность показаний... Ну и термоконтроль, скорее всего, понадобится...
Лучше бы запилить все это дело на Меге какой-нибудь... 8 или 16.
Кстати, я так понял у Вас датчик от "Жигулёнка", с виду напоминающий кондовый выпрямительный диод? А нет ли к нему чего-нибудь наподобие даташита, может в нем уже указана какая-нибудь методика калибровки?
|
|
|
![Сообщение Сообщение](./styles/subsilver2/imageset/icon_post_target.gif) |
Добавлено: 23 июн 2012, 20:25 |
|
|
![](images/spacer.gif) |
|