мне необходимо отфильтровать аналоговые сигналы методом скользящего среднего! сигнал подается на микроконтроллер. я использую ADUC842. написал программу, но не уверен что правильно реализовал метод скользящего среднего! вот кусок кода, в котором происходит считывание сигналов преобразование их с помощью АЦП в код, далее код преобразуется в напряжение, и потом идет фильтрация:
ADCRead(3); //читаем порт P1.3 и запускаем АЦП U21= (ADCDATAL+(ADCDATAH<<8))&0x0FFF; //снимаем код с АЦП U11= U21/1638; //перевод кода в напряжение (FFF/2,5=1638.4) - для фильтрации if(q==0) { Up1=Un1; //создание предыдущего зн-ия q=1; //взводим флаг } else { Un1=Up1*(1-p)+ Un1*p; //фильтрация (р=1/n, где n-количество отсчетов) Up1=Un1; //создание предыдущего зн-ия U21=Un1*1638; //перевод обратно в код } на сколько я понимаю скользящее среднее используется для фильтрации данных которые заданны массивом. как это реализовать в данном случаи?
на сколько я понимаю скользящее среднее используется для фильтрации данных которые заданны массивом. как это реализовать в данном случаи?
Совершенно верно. Вам нужен массив измерений. Вам нужно определиться с тем, по какому количеству отсчетов Вы хотите делать усреднение (я правильно понял, что Вам нужно получить среднее значение?) Для усреднения все просто - Вы отводите память для массива данных желаемого объема, определяете указатель на текущий элемент массива и длину массива. Обнуляете весь массив и указатель, определяете длину массива. Далее пошагово: 1. Получаете результат измерения, кладете его по адресу "Начало массива+указатель*длину элемента". Длина элемента нужна, если разрядность результата измерения более одного байта. 2. Инкремент указателя, проверка на равенство с длиной массива, если равенство достигнуто, обнуление указателя. 3. Расчет среднего значения элементов массива как суммы всех элементов массива, деленной на длину массива.
Если получение данных идет по прерываниям, то п.1 и п.2 удобно делать в обработчике, а п.3 в теле программы.
При расчете результаты измерений в массиве будут, конечно, находиться не по порядку, но для усреднения это неважно - от перемены мест слагаемых сумма не меняется
все немного по другому. есть аналоговый сигнал (в моем случае он изменяется от 0 до 2,5В), мы задаем количество отсчетов, это ширина усреднения и находим среднее значения точки из определенного диапазона сигнала.
если отталкиваться от этой статьи то необходим массив данных сигнала, но если сигнал у нас постоянно изменяется то как набрать массив, при этом фильтрация осуществляется в реальном времени, а количество осчетов можно задать с ЭВМ. мне подсказали вот такую формулу:
Un1=Up1*(1-p)+ Un1*p; //фильтрация (р=1/n, где n-количество отсчетов) где Up1-предыдущее отфильтрованное значение, а Un1-значение полученное в данный момент с АЦП.
прочитав данную статью я усомнился в истинности данной формулы, и статья тоже не подходит для моего случая, так как в режиме реального времени я не смогу сформировать массив с данными о сигнале! если кто то знает, как это сделать, подскажите пожайлуста!
в режиме реального времени я не смогу сформировать массив с данными о сигнале!
Почему не сможете? Рассмотрим усреднение по 5-ти измерениям, длина массива, соответственно, равна 5. Как это работает: 1. Поступил результат замера (R1). Массив - R1, 0, 0, 0, 0; считаем среднее, выдаем результат 2. Поступил результат замера (R2). Массив - R1, R2, 0, 0, 0; считаем среднее, выдаем результат 3. Поступил результат замера (R3). Массив - R1, R2, R3, 0, 0; считаем среднее, выдаем результат 4. Поступил результат замера (R4). Массив - R1, R2, R3, R4, 0; считаем среднее, выдаем результат 5. Поступил результат замера (R5). Массив - R1, R2, R3, R4, R5; считаем среднее, выдаем результат 6. Поступил результат замера (R6). Массив - R6, R2, R3, R4, R5; считаем среднее, выдаем результат 7. Поступил результат замера (R7). Массив - R6, R7, R3, R4, R5; считаем среднее, выдаем результат
Как видите, результат усреднения выдается с той же частотой, что и получение результатов замера, то бишь в реальном времени. Естественно, что в первых четырех выдачах результат будет отличаться от среднего значения - он будет плавно нарастать к среднему значению, на которое выйдет после пятого замера (после наполнения массива), но это издержки алгоритма усреднения, тут ничего не поделаешь...
чтоб не складывать дофига каждый раз, а обходиться одним вычитанием и одним сложением.
Это зависит от используемой математики и длины массива (ширины окна усреднения, то бишь). Если массив короткий, то проще все сложить, чем организовывать умножение предыдущего усреднения на длину массива, затем вычитание самого раннего замера в массиве, затем сложение с поступившим значением и, наконец, с делением на длину массива. Конечно, если ширина окна усреднения порядка 300 замеров, то, наверное, есть смысл с этим заморачиваться. А для 3-5 усреднений овчинка выделки не стоит...
Но в любом случае, принимать решение о выборе алгоритма усреднения нужно по месту - смотря, какой временной тайминг отводится на решение задачи по усреднению.
P.S. А еще нужно помнить, что трюк с вычитанием-сложением возможен ТОЛЬКО после наполнения массива. ДО наполнения массива среднее придется считать общим суммированием при любой длине массива, так что придется организовывать проверку еще и на это и выбирать процедуру расчета среднего в зависимости от того, наполнен ли массив.
P.P.S. Простите, ступил. Что-то подумал получше и понял, что и при расчетах с вычитанием-сложением все будет работать и без наполнения массива. Просто выдача будет точно также расти от нуля к среднему и выйдет на среднее после наполнения массива В общем, вердикт прежний - можно делать и так, и так. При малой длине массива 3-5 усреднений можно и каждый раз пересчитывать всю сумму, а при длинном массиве однозначно выгоднее алгоритм с вычитанием-сложением.
я тут попробовал смоделировать сигнал с шумом и отфильтровать его скользящим средним с помощью встроенной матлабовской функции и с помощью формулы которую я приводил выше, в своем куске программы, а также с помошью формулы которую взял из приведенной статьи.
так вот фильтрация моей формулой дает эффект не хуже, чем встроенная функция! и не нужно ни какой массив. если Вы работаете в MatLab я могу скинуть Вам файл, в котором я все это проделал, что бы Вы оценили на сколько моя формула точна!
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 6
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения