|
Усреднение вычислений АЦП |
|
|
|
Jan 10 2009, 05:35
|
Участник

Группа: Участник
Сообщений: 27
Регистрация: 11-12-08
Из: Earth
Пользователь №: 42 366

|
Подскажите хороший алгоритм для усреднения вычислений АЦП,я сделал так- Код // Read the 8 most significant bits // of the AD conversion result unsigned char read_adc(unsigned char adc_input){ ADMUX=adc_input|ADC_VREF_TYPE; // Start the AD conversion ADCSRA|=0x40; // Wait for the AD conversion to complete while ((ADCSRA & 0x10)==0); ADCSRA|=0x10; return ADCH;}
while (1){....
ta++;if(ta==21)ta=0; tempADC=(read_adc(0)/5); tempADC1=tempADC+(read_adc(0)/5); if(ta==20)temp=tempADC1/2;tempADC=0;tempADC1=0; т.е. показывать на индикаторе среднее число из 20 вычислений,но все равно не так сглаженно получается.
|
|
|
|
|
 |
Ответов
|
Jan 10 2009, 05:57
|
Частый гость
 
Группа: Свой
Сообщений: 165
Регистрация: 13-05-06
Из: Камышин
Пользователь №: 17 067

|
Конечно не сглаженно, потому что Вы сняв двадцать значений стираете и начинаете набирать по новой. И кстати складываете Вы двадцать значений, а делите только на два. Если это такая фишка, чтобы результат в итоге умножить на два, тогда понятно. И деление на 5 я провожу в самом конце, всего один раз над переменной temp. Это сделает более точными вычисления.
Поэтому у Вас есть усреднение не скользящее, а среднее на каждые отдельно взятые двадцать значений. Простой способ сделать скользящее, это вычитать самое раннее и прибавлять последнее. Но при этом обязательно накопится ошибка вычислений. Продвинутый способ, как писал в другой ветке resident, это хранить все двадцать последних значений в массиве, и делать среднее по нему, примерно вот так: unsigned char tempData[20]; unsigned char ta=0; unsigned char i; unsigend short temp;
while (1){....
ta++;if(ta==20) ta=0; tempData[ta]=read_adc(0);// деление на 5 перенесено в расчет temp
temp = 0; for(i=0;i<20;i++){ temp += tempData[i]; } temp =temp/100; // 20*5
}
В этом случае, переменная temp будет содержать усреднение последних снятых двадцати значений, и обновляться будет при каждом чтении АЦП.
Сообщение отредактировал rvk - Jan 10 2009, 06:04
|
|
|
|
|
Jan 10 2009, 18:33
|

Знающий
   
Группа: Свой
Сообщений: 648
Регистрация: 11-02-06
Из: Санкт-Петербург
Пользователь №: 14 237

|
Цитата(rvk @ Jan 10 2009, 08:57)  Продвинутый способ, как писал в другой ветке resident, это хранить все двадцать последних значений в массиве, и делать среднее по нему, примерно вот так: ........... Для усреднения по последним 20 значениям совсем необязательно хранить последние 20 значений в массиве, зачем расходовать память и ресурсы процессора, чтобы их каждый раз суммировать. А если нужно будет усреднять по 10000 значений ? Вот простой способ получать усреднённое значение каждый раз при получении текущего измеренного значения: Код T_average = T_average + (T_current - T_average) / 20.0 где T_average - среднее значение на данный момент времени, T_current - мгновенное измеренное значение, снятое, например, с АЦП в текущий момент времени. Этот пример НЧ-фильтра измерений практически эквивалентен усреднению последних 20 значений. Однако здесь число усреднений (20) необязательно может быть целым значением. Вообще говоря, в этой формуле число 20.0 является постоянной времени фильтра, которая вкупе с периодом измерений определяет скорость реакции (инертность) этого фильтра на резкие изменения входных измеряемых величин.
--------------------
Сделано в Китае. Упаковано в России.
|
|
|
|
|
Jan 10 2009, 18:55
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(Demeny @ Jan 10 2009, 23:33)  Этот пример НЧ-фильтра измерений практически эквивалентен усреднению последних 20 значений. Вообще-то это пример фильтра EMA (экспоненциальное скользящее среднее), а не SMA (простое скользящее среднее). В общем виде EMA выглядит как рекурсия Y(i+1)=Y(i)+(X(i)–Y(i))*K, где K=2/(N+1), Y(i+1) выходное значение фильтра, Y(i) - предыдущее выходное значение фильтра, X(i) - значение текущего отсчета. N имеет тот же смысл, что и "тау" RC-цепочки. Отличие EMA от SMA еще в том, что EMA это фильтр с БИХ, а SMA - с КИХ.
|
|
|
|
|
Jan 11 2009, 07:53
|

Профессионал
    
Группа: Участник
Сообщений: 1 091
Регистрация: 25-07-07
Из: Саратов
Пользователь №: 29 357

|
Цитата(rezident @ Jan 10 2009, 21:55)  Вообще-то это пример фильтра EMA (экспоненциальное скользящее среднее), а не SMA (простое скользящее среднее). В общем виде EMA выглядит как рекурсия Y(i+1)=Y(i)+(X(i)–Y(i))*K, где K=2/(N+1), Y(i+1) выходное значение фильтра, Y(i) - предыдущее выходное значение фильтра, X(i) - значение текущего отсчета. N имеет тот же смысл, что и "тау" RC-цепочки. Смысл может и тот же, а насчет численного значения я сильно сомневаюсь. Чтобы получить фильтр с постоянной времени tau, коэффициент вычисляется по формуле K = 1 - exp(-T/tau), где T - период следования входных отсчетов.
|
|
|
|
|
Jan 11 2009, 09:03
|
Гуру
     
Группа: Почетный участник
Сообщений: 6 851
Регистрация: 25-08-08
Из: Запорожье
Пользователь №: 39 802

|
Цитата(777777 @ Jan 11 2009, 11:53)  Смысл может и тот же, а насчет численного значения я сильно сомневаюсь. Чтобы получить фильтр с постоянной времени tau, коэффициент вычисляется по формуле K = 1 - exp(-T/tau), где T - период следования входных отсчетов. Вот то-то и оно. Знания и вера входят в конфликт. Инженер, чтобы устранить мигание цифр на индикаторе, возьмет среднее арифметическое от 2-4 измерений. Или даже в АЦП что-нибудь из двух компонентов придумает. Программист, ничтоже сумняшеся, будет брать экспоненту. При сем потребуется мощный процессор, плавающая запятая, дополнительные килобайты памяти, цикл решения задачи вырастет... Но он же за это не платит.
|
|
|
|
|
Jan 11 2009, 11:28
|

Профессионал
    
Группа: Участник
Сообщений: 1 091
Регистрация: 25-07-07
Из: Саратов
Пользователь №: 29 357

|
Цитата(Microwatt @ Jan 11 2009, 12:03)  Инженер, чтобы устранить мигание цифр на индикаторе, возьмет среднее арифметическое от 2-4 измерений. Или даже в АЦП что-нибудь из двух компонентов придумает. Программист, ничтоже сумняшеся, будет брать экспоненту. При сем потребуется мощный процессор, плавающая запятая, дополнительные килобайты памяти, цикл решения задачи вырастет... Но он же за это не платит. Во-первых, вашему "инженеру" для устранения мигания цифр нужно, как я уже писал здесь, не прикрывать свое дерьмо усреднением, а устранять его, потому что если он не в состоянии получить без помех 10 разрядов, то какой он нахрен инженер - самый дешевый китайский мультиметр дает точность в два раза большую. А во-вторых, если шум имеется в самом сигнале и его надо устранять, то имейте в виду, что цифровая фильтрация - наука несколько более сложная, нежели вычисление среднего арифметического. Для начала надо исследовать характер помех - они могут оказаться не шумовыми, а например, в сигнале могут наблюдаться скачки в одну сторну - такое часто встречается если помеха идет по земле от мощных потребителей. Тогда никаким усреднением вы эту помеху не устраните, а если устраните, то получите неправильный результат. Если помеха действительно представляет собой шумовой сигнал, то небходимо оценить ее спектр - если его частота сравнима со спектром полезного сигнала, то фильтровать ее также бесполезно. Наконец, если частота помехи существенно выше - нужно посмотреть насколько отличаются часоты сигнала и помехи и насколько отличаются их амплитуды и оценить необходимую крутизну характеристики фильтра для гарантированного подавления помехи и, следовательно, его порядок. Что же касается фильтра T_ave += (T_in - T_ave) / K то для него не требуется никакой плавающей точки - он работает c целыми переменными практически в таком виде как я здесь написал. Если же вы имеете в виду экспоненту для для вычисления K, то она вычисляется один раз на калькуляторе, а если она является степенью двойки, то не требуется даже деления, можно обойтись сдвигами. А дополнительные килобайты нужны как раз при вычислении среднего арифметического - в данном случае кроме текущего и предыдущего отсчетов хранить ничего не требуется.
|
|
|
|
Сообщений в этой теме
Wantcan Усреднение вычислений АЦП Jan 10 2009, 05:35   Demeny Цитата(rezident @ Jan 10 2009, 21:55) Воо... Jan 10 2009, 19:42    rezident Цитата(Demeny @ Jan 11 2009, 00:42) Конеч... Jan 10 2009, 20:26     Demeny Цитата(rezident @ Jan 10 2009, 23:26) Да ... Jan 11 2009, 07:46      rezident Цитата(Demeny @ Jan 11 2009, 12:46) Кстат... Jan 11 2009, 17:04       Tanya Цитата(rezident @ Jan 11 2009, 20:04) Для... Jan 12 2009, 08:02       777777 Цитата(rezident @ Jan 11 2009, 20:04) Дей... Jan 12 2009, 12:44       demiurg_spb Цитата(rezident @ Jan 11 2009, 20:04) Для... Jan 16 2009, 16:04  rvk Цитата(Demeny @ Jan 10 2009, 21:33) Вот п... Jan 10 2009, 19:02 Wantcan ЦитатаИ кстати складываете Вы двадцать значений, а... Jan 10 2009, 06:12 rvk Ну используйте вместо for вложенный цикл while:
t... Jan 10 2009, 06:19 Alex11 Есть еще один способ получить скользящее среднее. ... Jan 10 2009, 09:27 Herz Цитата(Alex11 @ Jan 10 2009, 11:27) Есть ... Jan 10 2009, 11:20 Wantcan С последним способом у меня не получилось-цифры ск... Jan 10 2009, 10:52 rvk Не забывайте только про переполнение temp. Если зн... Jan 10 2009, 11:23 rezident Цитата(rvk @ Jan 10 2009, 16:23) Чтобы с ... Jan 10 2009, 11:34 777777 Цитата(Wantcan @ Jan 10 2009, 08:35) Подс... Jan 11 2009, 07:46 Wantcan Спасибо за все ответы,на этой неделе не будет врем... Jan 11 2009, 16:59 Папа Карло Возник вопрос по формуле T_average = T_average + (... Jan 21 2009, 15:16 777777 Цитата(Папа Карло @ Jan 21 2009, 18:16) В... Jan 21 2009, 16:05  Палыч Цитата(777777 @ Jan 21 2009, 19:05) T_ave... Feb 13 2009, 07:09   777777 Цитата(Палыч @ Feb 13 2009, 10:09) Вот, и... Feb 13 2009, 11:55    Палыч Цитата(777777 @ Feb 13 2009, 14:55) Получ... Feb 13 2009, 12:59     777777 Цитата(Палыч @ Feb 13 2009, 15:59) Матема... Feb 14 2009, 11:18      ReAl Цитата(777777 @ Feb 14 2009, 13:18) Тогда... Feb 14 2009, 15:07 haker_fox Хочу сказать, что для фильтрации данных с АЦП прим... Jan 23 2009, 15:38 Wantcan haker_fox, прошу тнуть пальцем в то место форума,о... Feb 12 2009, 17:53 777777 Цитата(Wantcan @ Feb 12 2009, 20:53) hake... Feb 13 2009, 06:15  blackfin Цитата(777777 @ Feb 13 2009, 09:15) То ес... Feb 13 2009, 06:26   Tanya Цитата(blackfin @ Feb 13 2009, 09:26) Так... Feb 13 2009, 07:05   777777 Цитата(blackfin @ Feb 13 2009, 09:26) Так... Feb 13 2009, 11:40    blackfin Цитата(777777 @ Feb 13 2009, 14:40) Да, н... Feb 13 2009, 11:46 xemul Цитата(Палыч @ Feb 13 2009, 15:59) ...
По... Feb 13 2009, 14:08 Wantcan Пожалуйста,помогите переделать найденный на этом ф... Mar 2 2009, 16:57 Wantcan Остановился на таком варианте
Код ta++; if(ta=... Mar 16 2009, 11:10 Флюктуация ваккума Нужно создать в оперативной памяти закольцованный ... Aug 15 2015, 12:22 Bronislav Такой вариант не подойдет?
for(i=0;i<20;i++) ... Sep 4 2015, 06:15
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|