kv_addr 0 23 апреля, 2007 Опубликовано 23 апреля, 2007 · Жалоба Извиняюсь погорячился.. Понедельник - день тяжелый ;> В понедельник бывает. ;) А ДШ свежий желательно иметь всегда, особливо когда возникают спорные вопросы. Тут - без каких-либо возражений. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Vade_nsk 0 23 апреля, 2007 Опубликовано 23 апреля, 2007 · Жалоба немного не по теме, но сталкивался с ситуацией с тексасовскими ЦАПами. Как это принято имеется семейство с одинаковой цоколевкой и разрядностью 8/10/12 в зависимости от типа (и цены в геометрической прогрессии естественно). Брали 10 -разрядный, а оказалось что у него все 12 разрядов работают. Для себя объяснил что так делается по маркетинговым соображениям. Может и здесь Atmel пытался покончить с архаичным dip'ом. Явно кристаллы одинаковые идут в разные корпуса. В том, что разрядность может в 4 раза пострадать из-за большей длины от кристалла до пина сильно сомневаюсь. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
arttab 0 24 апреля, 2007 Опубликовано 24 апреля, 2007 · Жалоба В старых ревизиях было 8 бит. Потом в новой ревизии стало 10 bit ADC. Ограничение по корпусам не видел, т.е. на всех корпуса 10 bit. Или я что то проглядел. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Anjey_N 0 24 апреля, 2007 Опубликовано 24 апреля, 2007 (изменено) · Жалоба Я новичок, поэтому наверное сейчас задам глупый вопрос! Пишу прогу для вольтметра, использую Мегу16 со встроенным АЦП. Делаю 128 выборок, суммирую и затем делю на 128. Получаю результат. Мне сказали, что теперь нужно применить вычисление скользящего среднего. А как это сделать, я не знаю! Может, кто-нибудь подскажет или даст ссылку на это чудо! Изменено 24 апреля, 2007 пользователем Anjey_N Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 24 апреля, 2007 Опубликовано 24 апреля, 2007 · Жалоба Мне сказали, что теперь нужно применить вычисление скользящего среднего. А как это сделать, я не знаю!Поиск по форуму по словосочетанию "скользящее среднее" дает несколько результатов, уже не говоря о том, сколько результатов на такое же словосочетание дает google. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
arttab 0 25 апреля, 2007 Опубликовано 25 апреля, 2007 · Жалоба я делал простое усреднение так: Xi = (Xi + Xi+1) / 2 Xi+1 результат нового измерения только частоты выборок должна быть больше скорости изменения сигнала иначе фигня получиться. в общем вмде можно так записать: Xi = (k/n)*Xi + (p/n)*Xi+1 от коэффициентов будет зависеть скорость приближения к устоявшемуся значению. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
IgorKossak 0 25 апреля, 2007 Опубликовано 25 апреля, 2007 · Жалоба Я новичок, поэтому наверное сейчас задам глупый вопрос! Пишу прогу для вольтметра, использую Мегу16 со встроенным АЦП. Делаю 128 выборок, суммирую и затем делю на 128. Получаю результат. Мне сказали, что теперь нужно применить вычисление скользящего среднего. А как это сделать, я не знаю! Может, кто-нибудь подскажет или даст ссылку на это чудо! Делаете кольцевой массив на количество выборок и переменную для суммы. С каждой новой выборкой вычитаете из суммы самое старое значение из массива, пишете на его место значение выборки, прибавляете к сумме значение выборки и делите сумму на количество элементов в массиве (константа). Как проинициализировать массив решайте сами. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
defunct 0 26 апреля, 2007 Опубликовано 26 апреля, 2007 · Жалоба Мне сказали, что теперь нужно применить вычисление скользящего среднего. А как это сделать, я не знаю! Пример скользящего усреднения по 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( <Текущее значение АЦП> ); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Snaky 0 26 апреля, 2007 Опубликовано 26 апреля, 2007 · Жалоба Пример скользящего усреднения по 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 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
defunct 0 26 апреля, 2007 Опубликовано 26 апреля, 2007 · Жалоба нерабочий примерчик-то. вызвал 16 раз функцию с аргументом CurrVal = 10, в результате получил 6. через 20 итераций получил 7. :blink: Пример рабочий. Вы дальше повызывайте. Хотите чтоб быстрее получался рез-тат усредняйте по 8-ми или по 4-м точкам. и вообще странный какой-то алгоритм - возвращать результат целочисленного деления (накопленной суммы + константа) Почитайте какую-нить книжку по усреднению прежде чем выступать. Константа эта для устранения абсолютной погрешности в 0.5LSB при накоплении суммы. PS я всегда пользуюсь методом с кольцевым массивом У вас видать памяти в МК всегда много.. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
lepeksiy 0 26 апреля, 2007 Опубликовано 26 апреля, 2007 · Жалоба В общем виде фильтрация выглядит примерно так (для чайников): // Размер массива - должен быть степенью двойки!! #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 раз. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladimirYU 0 26 апреля, 2007 Опубликовано 26 апреля, 2007 · Жалоба Можно испоьзовать алгоритм апериодического звена. Строится он по принципу интегратора ( сумматора накопителя) охваченного отрицательной обратной связью. Это позволяет уйти от скользящего массива, правда требуется сумматор (интегратор) двойной длины по сравнению с длиной результатов измерений и переменная для хранения предыдущего фильтрованного результата. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
lepeksiy 0 26 апреля, 2007 Опубликовано 26 апреля, 2007 · Жалоба VladimirYU А как это выражается формулами? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Anjey_N 0 26 апреля, 2007 Опубликовано 26 апреля, 2007 · Жалоба В общем виде фильтрация выглядит примерно так (для чайников): // Размер массива - должен быть степенью двойки!! #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: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ReAl 0 26 апреля, 2007 Опубликовано 26 апреля, 2007 · Жалоба Пример рабочий. Вы дальше повызывайте. Хотите чтоб быстрее получался рез-тат усредняйте по 8-ми или по 4-м точкам. Фильтр неплохой, сам пользуюсь :-) Но это, IMHO, не скользящее среднее. Реакция скользящего среднего на единичный скачок - прямая линия с выходом на уровень, т.е. если у нас было "много" нулей и вдруг пошло 32, то на 16-ом значении (при скользящем усреднении окном в 16 отсчётов) на выходе уже будет 32. А этот "экспоненциальный" фильтр имеет поведение как у RC-цепочки. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться