Перейти к содержанию
    

АЦП в ATMega8: 8 бит или 10 бит?

Извиняюсь погорячился.. Понедельник - день тяжелый ;>

В понедельник бывает. ;)

А ДШ свежий желательно иметь всегда, особливо когда возникают спорные вопросы.

Тут - без каких-либо возражений.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

немного не по теме, но сталкивался с ситуацией с тексасовскими ЦАПами. Как это принято имеется семейство с одинаковой цоколевкой и разрядностью 8/10/12 в зависимости от типа (и цены в геометрической прогрессии естественно). Брали 10 -разрядный, а оказалось что у него все 12 разрядов работают. Для себя объяснил что так делается по маркетинговым соображениям.

Может и здесь Atmel пытался покончить с архаичным dip'ом. Явно кристаллы одинаковые идут в разные корпуса. В том, что разрядность может в 4 раза пострадать из-за большей длины от кристалла до пина сильно сомневаюсь.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В старых ревизиях было 8 бит. Потом в новой ревизии стало 10 bit ADC. Ограничение по корпусам не видел, т.е. на всех корпуса 10 bit. Или я что то проглядел.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я новичок, поэтому наверное сейчас задам глупый вопрос!

Пишу прогу для вольтметра, использую Мегу16 со встроенным АЦП. Делаю 128 выборок, суммирую и затем делю на 128. Получаю результат. Мне сказали, что теперь нужно применить вычисление скользящего среднего. А как это сделать, я не знаю! Может, кто-нибудь подскажет или даст ссылку на это чудо! :help:

Изменено пользователем Anjey_N

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Мне сказали, что теперь нужно применить вычисление скользящего среднего. А как это сделать, я не знаю!
Поиск по форуму по словосочетанию "скользящее среднее" дает несколько результатов, уже не говоря о том, сколько результатов на такое же словосочетание дает google.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

я делал простое усреднение так:

Xi = (Xi + Xi+1) / 2

Xi+1 результат нового измерения

только частоты выборок должна быть больше скорости изменения сигнала иначе фигня получиться.

в общем вмде можно так записать:

Xi = (k/n)*Xi + (p/n)*Xi+1

от коэффициентов будет зависеть скорость приближения к устоявшемуся значению.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я новичок, поэтому наверное сейчас задам глупый вопрос!

Пишу прогу для вольтметра, использую Мегу16 со встроенным АЦП. Делаю 128 выборок, суммирую и затем делю на 128. Получаю результат. Мне сказали, что теперь нужно применить вычисление скользящего среднего. А как это сделать, я не знаю! Может, кто-нибудь подскажет или даст ссылку на это чудо! :help:

Делаете кольцевой массив на количество выборок и переменную для суммы.

С каждой новой выборкой вычитаете из суммы самое старое значение из массива, пишете на его место значение выборки, прибавляете к сумме значение выборки и делите сумму на количество элементов в массиве (константа).

Как проинициализировать массив решайте сами.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Мне сказали, что теперь нужно применить вычисление скользящего среднего. А как это сделать, я не знаю!

 

Пример скользящего усреднения по 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-ти точкам (без использования массивов)

 

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. :blink:

и вообще странный какой-то алгоритм - возвращать результат целочисленного деления (накопленной суммы + константа) на константу.

 

PS я всегда пользуюсь методом с кольцевым массивом, как описал IgorKossak

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

нерабочий примерчик-то. вызвал 16 раз функцию с аргументом CurrVal = 10, в результате получил 6. через 20 итераций получил 7. :blink:

Пример рабочий. Вы дальше повызывайте.

Хотите чтоб быстрее получался рез-тат усредняйте по 8-ми или по 4-м точкам.

 

и вообще странный какой-то алгоритм - возвращать результат целочисленного деления (накопленной суммы + константа)

Почитайте какую-нить книжку по усреднению прежде чем выступать.

Константа эта для устранения абсолютной погрешности в 0.5LSB при накоплении суммы.

 

PS я всегда пользуюсь методом с кольцевым массивом

У вас видать памяти в МК всегда много..

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В общем виде фильтрация выглядит примерно так (для чайников):

 

// Размер массива - должен быть степенью двойки!!
#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 раз.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Можно испоьзовать алгоритм апериодического звена. Строится он по принципу интегратора ( сумматора накопителя) охваченного отрицательной обратной связью. Это позволяет уйти от скользящего массива, правда требуется сумматор (интегратор) двойной длины по сравнению с длиной результатов измерений и переменная для хранения предыдущего фильтрованного результата.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В общем виде фильтрация выглядит примерно так (для чайников):

 

// Размер массива - должен быть степенью двойки!!
#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 раз.

 

 

Спасибо, буду разбираться и учиться! :w00t:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Пример рабочий. Вы дальше повызывайте.

Хотите чтоб быстрее получался рез-тат усредняйте по 8-ми или по 4-м точкам.

Фильтр неплохой, сам пользуюсь :-)

Но это, IMHO, не скользящее среднее.

Реакция скользящего среднего на единичный скачок - прямая линия с выходом на уровень, т.е. если у нас было "много" нулей и вдруг пошло 32, то на 16-ом значении (при скользящем усреднении окном в 16 отсчётов) на выходе уже будет 32.

А этот "экспоненциальный" фильтр имеет поведение как у RC-цепочки.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...