Rovki писал(а): ↑21.08.2022{, 14:32}
Но если строго подходить к фильтру ,то он должен быть полосовым ,отфильтровывать не только ВЧ ,но НЧ помехи, что очень важно ввиду слабых ИП и меняющейся нагрузки Для аналоговых сигналов.
Цифровые фильтры не фильтруют частоты, они фильтруют ЦИФРЫ (значения)! На то они и цифровые фильтры.
Хорошо, давайте медленно пережевывать основные принципы.
1. До того как аналоговый сигнал попал на пин АЦП, вы можете фильтровать его физическим способом - RC, LC фильтрами, активными методами...
2. Как только аналоговый сигнал попал на АЦП это уже не аналоговый сигнал. Это поток значений с дискретностью по времени. Те если мы хотим оцифровать высокие частоты нам необходимо иметь частоту дискретизации хотя бы на порядок больше частоты сигнала, максимальной частоты которую мы оцифровываем. Другими словами, чтобы оцифровать сигнал 10кГц, надо иметь частоту оцифровки 100кГц. Такое могут далеко не все контроллеры. К примеру AЦП AVR(16МГЦ) может качественно снимать сигнал 1 раз в 120мкс а это всего 8кГц и при условии что контроллер больше ничем не занят. Т.е. Максимально доступная для оцифровки частота до 1000Гц. С ооочень большой натяжкой.
О каких высоких частотах Вы говорите
Rovki? О чем вообще речь?
3. Теперь о шуме сигнала и помеховых пиках.
Пришлось создать блок генератора шумной синусоиды. Что не сделаешь ради
Rovki.
Так вот фильтрация шума и фильтрация помех ЦИФРОВОГО сигнала осуществляется разными фильтрами и с разной частотой дискретизации (тактирования).
Начнем с помеховых пиков. Как правило они очень короткие по времени. Их период измеряется десятками-сотнями микросекунд. Чтобы отфильтровать эти неправильные цифровые значения используются медианные фильтры.
Что такое медианный фильтр.
Берутся несколько последовательно пришедших значений и из них выбирается среднее. Не рассчитывается! А ВЫБИРАЕТСЯ.
Пример:
1, 2, 2, 2, 5, 18, 30 - медиана в этом случае будет
2, потому как есть 3 числа больше или равно
2 и 3 числа меньше или равно
2.
Т.к. период пиков очень короткий, то и снимать показания надо часто, с дискретностью равной примерно максимально возможному периоду этих помех. В противном случае медианный фильтр будет фильтровать лишнее и искажать сигнал.
Т.к. снимать и фильтровать надо часто, значит делать надо это очень быстро. Медианные фильтры именно под это и заточены. Один из фильтров которые я Вам давал выбирает медиану из трех значений и выполняется за 3-4 такта процессора (не путать с циклами программы), а это 2-3 мкс (для AVR). Быстрее ничего не бывает, никаких фильтров.
Бегущее среднее.
Как Вы правильно разобрались это сумма некоего количества последовательных значений деленная на это количество значений. В чистом виде фильтр
Бегущее среднее работает подобным образом, как Вы его сделали на стеке. Не совсем конечно, но похоже.
На стеке это очень медленно.
Ну представьте, у вас куча переменных каждую надо прочитать, потом передвинуть в стеке, потом все сложить, а потом еще разделить. Это огромное количество процессорного времени, особенно деление, которое является самой долгой из простых математических операций, а еще если это float, как у Вас, то вообще беда. А еще и вычисления с переменным количеством значений. А Еще Вы там что то предлагаете по изменению частоты дискретизации во время работы.
Именно по причине быстродействия используют аналог фильтра
Бегущее среднее -
Экспоненциальный фильтр.
Если по простому, то берется
среднее арифметическое предыдущих значений, умножается на 15 к этому прибавляется новое значение и делится на 16. Полученное значение становится новым
средним арифметическим.
Псевдокод.
((Старое среднее арифметическое * 15) + новое значение) / 16 = Новое среднее арифметическое;
Старое среднее арифметическое = Новое среднее арифметическое;
Теперь почему 16. Это степень двойки. Таким образом долгая операция деления заменяется сдвигом на 4 бита. Что происходит за один такт процессора (0,0625 мкс). Вместо 16 может быть 2,4,8,16,32 и т.д.
Как видно, в данном случае нет огромного количества переменных их всего две
среднее арифметическое и
новое значение, а соответственно существенно экономится память и процессорное время на вычисления.
Есть у этого метода и минус. Это точность. Конечное значение занижается в пределах тех четырех бит которые срезаются при сдвиге. Поэтому такой фильтр будет не очень хорошо работать на маленьких значениях (меньше 200-300).
Теперь по дискретизации (тактированию) бегущего среднего. Чем чаще мы снимаем показания тем ближе к реальному времени сигнала, но фильтрация(выпрямление графика) слабей. И наоборот, чем реже вносим новое значение, тем больше отставание от исходного сигнала. Количество суммируемых значений так же влияет на фильтрацию и отставание.
Про другие фильтры, типа Кальмана, рассказывать не буду. Постарайтесь осознать и переварить уже сказанное. Медианный и бегущее среднее(экспоненциальный), это два основных фильтра используемых в маломощных контроллерах.