|
|
  |
АЦП в ATMega8: 8 бит или 10 бит?, Загадка в АЦП ATMega8 (ADC5) |
|
|
|
Apr 23 2007, 16:09
|

Местный
  
Группа: Свой
Сообщений: 208
Регистрация: 6-07-04
Из: Полтава
Пользователь №: 279

|
Цитата(defunct @ Apr 23 2007, 16:04)  Извиняюсь погорячился.. Понедельник - день тяжелый ;> В понедельник бывает.  Цитата(defunct @ Apr 23 2007, 16:04)  А ДШ свежий желательно иметь всегда, особливо когда возникают спорные вопросы. Тут - без каких-либо возражений.
|
|
|
|
|
Apr 23 2007, 16:30
|
Участник

Группа: Свой
Сообщений: 71
Регистрация: 7-07-06
Из: Новосибирск
Пользователь №: 18 652

|
немного не по теме, но сталкивался с ситуацией с тексасовскими ЦАПами. Как это принято имеется семейство с одинаковой цоколевкой и разрядностью 8/10/12 в зависимости от типа (и цены в геометрической прогрессии естественно). Брали 10 -разрядный, а оказалось что у него все 12 разрядов работают. Для себя объяснил что так делается по маркетинговым соображениям. Может и здесь Atmel пытался покончить с архаичным dip'ом. Явно кристаллы одинаковые идут в разные корпуса. В том, что разрядность может в 4 раза пострадать из-за большей длины от кристалла до пина сильно сомневаюсь.
|
|
|
|
|
Apr 25 2007, 11:19
|

Шаман
     
Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221

|
Цитата(Anjey_N @ Apr 24 2007, 19:50)  Я новичок, поэтому наверное сейчас задам глупый вопрос! Пишу прогу для вольтметра, использую Мегу16 со встроенным АЦП. Делаю 128 выборок, суммирую и затем делю на 128. Получаю результат. Мне сказали, что теперь нужно применить вычисление скользящего среднего. А как это сделать, я не знаю! Может, кто-нибудь подскажет или даст ссылку на это чудо!  Делаете кольцевой массив на количество выборок и переменную для суммы. С каждой новой выборкой вычитаете из суммы самое старое значение из массива, пишете на его место значение выборки, прибавляете к сумме значение выборки и делите сумму на количество элементов в массиве (константа). Как проинициализировать массив решайте сами.
|
|
|
|
|
Apr 26 2007, 00:52
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(Anjey_N @ Apr 24 2007, 18:50)  Мне сказали, что теперь нужно применить вычисление скользящего среднего. А как это сделать, я не знаю! Пример скользящего усреднения по 16-ти точкам (без использования массивов) Код int UpdateAverage( int CurrVal ) { static int Sum = 0; int tmp = (Sum + (16 >> 1)) >> 4; // среднее = (Sum + n/2) / n, где n = 16 Sum += CurrVal - tmp; return tmp; } <Усредненное значение АЦП> = UpdateAverage( <Текущее значение АЦП> );
|
|
|
|
|
Apr 26 2007, 06:56
|

Mute Beholder
  
Группа: Свой
Сообщений: 260
Регистрация: 4-04-07
Из: Третья планета от Солнца
Пользователь №: 26 754

|
Цитата(defunct @ Apr 26 2007, 03:52)  Пример скользящего усреднения по 16-ти точкам (без использования массивов) Код int UpdateAverage( int CurrVal ) { static int Sum = 0; int tmp = (Sum + (16 >> 1)) >> 4; // среднее = (Sum + n/2) / n, где n = 16 Sum += CurrVal - tmp; return tmp; } <Усредненное значение АЦП> = UpdateAverage( <Текущее значение АЦП> ); нерабочий примерчик-то. вызвал 16 раз функцию с аргументом CurrVal = 10, в результате получил 6. через 20 итераций получил 7. и вообще странный какой-то алгоритм - возвращать результат целочисленного деления (накопленной суммы + константа) на константу. PS я всегда пользуюсь методом с кольцевым массивом, как описал IgorKossak
--------------------
Common sense is not so common.
|
|
|
|
|
Apr 26 2007, 13:07
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(Snaky @ Apr 26 2007, 05:56)  нерабочий примерчик-то. вызвал 16 раз функцию с аргументом CurrVal = 10, в результате получил 6. через 20 итераций получил 7.  Пример рабочий. Вы дальше повызывайте. Хотите чтоб быстрее получался рез-тат усредняйте по 8-ми или по 4-м точкам. Цитата и вообще странный какой-то алгоритм - возвращать результат целочисленного деления (накопленной суммы + константа) Почитайте какую-нить книжку по усреднению прежде чем выступать. Константа эта для устранения абсолютной погрешности в 0.5LSB при накоплении суммы. Цитата PS я всегда пользуюсь методом с кольцевым массивом У вас видать памяти в МК всегда много..
|
|
|
|
|
Apr 26 2007, 13:08
|
Участник

Группа: Участник
Сообщений: 21
Регистрация: 25-04-07
Пользователь №: 27 294

|
В общем виде фильтрация выглядит примерно так (для чайников): Код // Размер массива - должен быть степенью двойки!! #define ARRAY_SIZE 16
// Функция берет текущее значение и возвращает отфильтрованное int GetMovingAverage(int current_value) { static int filter_array[ARRAY_SIZE]; static unsigned int index = 0; static int sum = 0;
// Вычитаем удаляемое значение из суммы и прибавляем текущее sum += current_value - filter_array[index]; // Вставляем текущее значение в массив filter_array[index] = current_value; // Изменяем индекс. Не забывать, что ARRAY_SIZE должен быть степенью двойки!! index = (index + 1) & (ARRAY_SIZE - 1); // Возвращаем отфильтрованное значение. return sum / ARRAY_SIZE; } Реальные типы переменных должны быть согласованы с размерностью данных. Данные считаются недостоверными, пока функция не будет вызвана ARRAY_SIZE раз.
|
|
|
|
|
Apr 26 2007, 17:21
|
Участник

Группа: Участник
Сообщений: 21
Регистрация: 25-04-07
Пользователь №: 27 294

|
VladimirYU А как это выражается формулами?
|
|
|
|
|
Apr 26 2007, 21:35
|

Частый гость
 
Группа: Участник
Сообщений: 80
Регистрация: 12-01-07
Из: Энергодар Украина
Пользователь №: 24 374

|
Цитата(Lepeksiy @ Apr 26 2007, 13:08)  В общем виде фильтрация выглядит примерно так (для чайников): Код // Размер массива - должен быть степенью двойки!! #define ARRAY_SIZE 16
// Функция берет текущее значение и возвращает отфильтрованное int GetMovingAverage(int current_value) { static int filter_array[ARRAY_SIZE]; static unsigned int index = 0; static int sum = 0;
// Вычитаем удаляемое значение из суммы и прибавляем текущее sum += current_value - filter_array[index]; // Вставляем текущее значение в массив filter_array[index] = current_value; // Изменяем индекс. Не забывать, что ARRAY_SIZE должен быть степенью двойки!! index = (index + 1) & (ARRAY_SIZE - 1); // Возвращаем отфильтрованное значение. return sum / ARRAY_SIZE; } Реальные типы переменных должны быть согласованы с размерностью данных. Данные считаются недостоверными, пока функция не будет вызвана ARRAY_SIZE раз. Спасибо, буду разбираться и учиться!
|
|
|
|
|
Apr 26 2007, 23:17
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(defunct @ Apr 26 2007, 12:07)  Пример рабочий. Вы дальше повызывайте. Хотите чтоб быстрее получался рез-тат усредняйте по 8-ми или по 4-м точкам. Фильтр неплохой, сам пользуюсь :-) Но это, IMHO, не скользящее среднее. Реакция скользящего среднего на единичный скачок - прямая линия с выходом на уровень, т.е. если у нас было "много" нулей и вдруг пошло 32, то на 16-ом значении (при скользящем усреднении окном в 16 отсчётов) на выходе уже будет 32. А этот "экспоненциальный" фильтр имеет поведение как у RC-цепочки.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|