реклама на сайте
подробности

 
 
> Усреднение вычислений АЦП
Wantcan
сообщение Jan 10 2009, 05:35
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 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 вычислений,но все равно не так сглаженно получается.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
rvk
сообщение Jan 10 2009, 05:57
Сообщение #2


Частый гость
**

Группа: Свой
Сообщений: 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
Go to the top of the page
 
+Quote Post
Demeny
сообщение Jan 10 2009, 18:33
Сообщение #3


Знающий
****

Группа: Свой
Сообщений: 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 является постоянной времени фильтра, которая вкупе с периодом измерений определяет скорость реакции (инертность) этого фильтра на резкие изменения входных измеряемых величин.


--------------------
Сделано в Китае. Упаковано в России.
Go to the top of the page
 
+Quote Post
rezident
сообщение Jan 10 2009, 18:55
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 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 - с КИХ.
Go to the top of the page
 
+Quote Post
Demeny
сообщение Jan 10 2009, 19:42
Сообщение #5


Знающий
****

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



Цитата(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-цепочки. Отличие EMA от SMA еще в том, что EMA это фильтр с БИХ, а SMA - с КИХ.

Всё это верно, я и не сомневался в Вашей компетентности в этом вопросе. Автор топика просил алгоритм усреднения значений АЦП, поэтому я предложил практическую формулу, не вдаваясь в теорию фильтров, импульсные характеристики, оператор Лапласа и т. п. Эта формула неоднократно мною проверена и прекрасно работает, например, в системах управления газотурбинными двигателями.
Конечно, численно она отличается от простого усреднения, но практически ведёт себя точно также и позволяет избежать хранения и суммирования последних N измерений, что особенно актуально для систем на маломощных вычислителях с ограниченными ресурсами (AVR, PIC).


--------------------
Сделано в Китае. Упаковано в России.
Go to the top of the page
 
+Quote Post
rezident
сообщение Jan 10 2009, 20:26
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(Demeny @ Jan 11 2009, 00:42) *
Конечно, численно она отличается от простого усреднения, но практически ведёт себя точно также
Да как же они могут вести себя одинаково, если у них и ФЧХ и ПХ разные!?
Go to the top of the page
 
+Quote Post
Demeny
сообщение Jan 11 2009, 07:46
Сообщение #7


Знающий
****

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



Цитата(rezident @ Jan 10 2009, 23:26) *
Да как же они могут вести себя одинаково, если у них и ФЧХ и ПХ разные!?

В первом посте автор топика обозначил задачу - "показывать на индикаторе среднее значение", для этой задачи различия КИХ и БИХ фильтров несущественны - оба являются инерционным звеном и справляются с поставленной задачей. Приведённая мной формула экспоненциального скользящего среднего позволяет обойтись без хранения массива измеренных значений и их пересуммирования на каждом цикле измерения.
Может быть, автору окажется полезной статья "Выбор типа скользящих средних" , которую я прикрепил к сообщению. Кстати, в ней на 52 странице приведены импульсные характеристики различных типов усреднения. Сравнив графики б) и г) легко убедиться, что ИХ простого взвешенного усреднения и экспоненциального весьма схожи.
Прикрепленные файлы
Прикрепленный файл  50_55.pdf ( 945.56 килобайт ) Кол-во скачиваний: 437
 


--------------------
Сделано в Китае. Упаковано в России.
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- Wantcan   Усреднение вычислений АЦП   Jan 10 2009, 05:35
|||- - 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
||- - 777777   Цитата(rezident @ Jan 10 2009, 21:55) Воо...   Jan 11 2009, 07:53
||- - Microwatt   Цитата(777777 @ Jan 11 2009, 11:53) Смысл...   Jan 11 2009, 09:03
||- - 777777   Цитата(Microwatt @ Jan 11 2009, 12:03) Ин...   Jan 11 2009, 11:28
|- - 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


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 26th June 2025 - 02:04
Рейтинг@Mail.ru


Страница сгенерированна за 0.01568 секунд с 7
ELECTRONIX ©2004-2016