Цифровые фильтры, фильтрация сигнала (Ликбез)

Ответить
Аватара пользователя
Dryundel
Полковник
Сообщения: 2401
Зарегистрирован: 22.05.2017{, 23:15}
Репутация: 783
Откуда: Ярославль
Имя: Андрей
Контактная информация:

Цифровые фильтры, фильтрация сигнала (Ликбез)

#1

Сообщение Dryundel » 08.03.2023{, 16:43}

Этим топиком начинаю небольшую серию статей о цифровой фильтрации в FLProg.

Я долго думал с чего начать и что вообще рассказывать по данной теме. О фильтрации и фильтрах есть огромное количество статей в Интернете. Все вроде расписано, разобрано по косточкам, но вопросов меньше не становится, особенно в среде пользователей FLProg. Поэтому начну с основной, грубой, фатальной, но тем не менее очень часто встречающейся ошибки.

Основная ошибка фильтрации.

На форуме, да и в чатах довольно много Пользовательских Блоков различных цифровых фильтров. Одни из них имеют вход EN для тактирования, другие настройки таймингов в параметрах пользователя, третьи вообще ничего такого не предлагают. Не скажу что всегда, но очень часто, вижу вот такую картину.
.
0.jpg
0.jpg (11.47 КБ) 1461 просмотр
.
Ну и потом тирада. Типа не работает этот фильтр. Фильтрует очень плохо. И т.д.
Конечно же не совсем корректно называть вход тактирования обозначением En.
Естественно первое что приходит в голову неискушенному пользователю это то, что если на входе true - фильтр фильтрует, если же false - не фильтрует. Значит надо тупо инвертировать вход и всё.

И что же получается в итоге.
Каждый раз, когда очередь в цикле доходит до алгоритма блока, этот алгоритм исполняется. И это происходит в каждом цикле.

А что же делает алгоритм.
В каждом цикле он берет очередную переменную со входа, складывает ее в буфер и в купе с переменными взятыми со входа ранее высчитывает какое то среднее или медианное значение.

Вроде бы все норм, с первого взгляда. НО! Время меду циклами составляет микросекунды (иногда миллисекунды). А сигнал какого нибудь датчика изменяется к примеру 1 раз в секунду. Нам надо сравнивать и обрабатывать эти разные значения, а вместо этого, мы тысячу раз (каждый цикл) загоняем в буфер алгоритма одно и то же значение. В результате на выходе имеем почти то же самое что и на входе. Но процессор наш потрудился, мы с успехом заняли его процессорное время, тем самым еще и усугубив быстродействие и так не особо мощного контроллера.

Рассмотрим процесс на примере медианного фильтра из 3х.
У такого фильтра буфер на три значения. И очень часто слышу - "Три значения для фильтрации очень мало". Это далеко не так.
Для наглядности я нарисовал условную диаграмму сигнала с помехой, которую требуется отфильтровать.
.
1.jpg
.
Алгоритм медианы из 3х такой.
Берем со входа три последовательных значения складываем их в буфер, находим медиану и выдаем на выход. При получении следующей переменной, выкидываем из буфера самую старую переменную и заменяем ее новой, после чего повторяем нахождение медианы.
Если мы делаем это каждый цикл, то медиана будет очень близка к исходному значению и на выходе сигнал почти не изменится.
Для того, чтобы отфильтровать помеху, частота выборки (период дискретизации) должен быть как минимум больше чем время действия этой помехи.
Для достижения хорошего результата, необходимо знать или хотя бы представлять тайминги фильтруемых помех. Можно взять с небольшим запасом время тактирования. Но слишком большой таймаут выборки будет фильтровать лишнее и создавать задержку выходного сигнала относительно входного. Особенно это будет заметно на алгоритмах с большим буфером.

Как же регулировать дискретизацию выборки.
Все очень просто. Тактирование можно реализовать обычным генератором. Обязательным моментом в этом случае будет R-триггер. Он не позволит делать выборки на всем протяжении высокого уровня в сигнале генератора.
.
2.jpg
2.jpg (10.38 КБ) 1461 просмотр
.
Так же можно тактировать плату на которой находится фильтр. Вот в этом случае вход En можно и инвертировать (подать true).
Тактирование платы может оказаться полезным если используется цепочка разных фильтров и их время тактирования совпадает.

.

Аватара пользователя
Dryundel
Полковник
Сообщения: 2401
Зарегистрирован: 22.05.2017{, 23:15}
Репутация: 783
Откуда: Ярославль
Имя: Андрей
Контактная информация:

Цифровые фильтры, фильтрация сигнала (Ликбез)

#2

Сообщение Dryundel » 09.03.2023{, 12:38}

В глобальной сети можно встретить много статей на тему классификации цифровых фильтров. Их делят на типы, категории, разновидности и т.д. Эту лабуду вы сможете найти и без меня. Все это деление весьма условно. Основная задача фильтров - исключить из цифровой последовательности сигнала нежелательные значения или усреднить их.
.
Что такое цифровой сигнал и что фильтруют цифровые фильтры..
Этот раздел посвящен самым азам. Поэтому искушенные читатели могут его пропустить.
.
Для того, чтобы понять что делают цифровые фильтры, прежде всего необходимо понимать, что такое цифровой сигнал. Все что приходит в процессор с любых пинов контроллера является цифровым сигналом. Не смотря на то, что пины делятся на цифровые и аналоговые, при разработке проекта, мы имеем дело с цифровой последовательностью.
Цифровые пины дают нам последовательность в бинарной (двоичной) системе исчисления и значения могут быть 0 оли 1.
Аналоговые пины, с помощью АЦП, могут оперировать десятичными значениями от 0 и до максимально позволяющего значения исходя из битности АЦП. К примеру в Atmega328 АЦП 10-битный, а это значения от 0 до 1023.

Вы можете возразить - при чем тут цифровые пины и что там фильтровать?
На самом деле при создании почти любого проекта Вы применяете такой цифровой фильтр. Это либо чекбокс "Включить защиту от дребезга", либо блок Bounce. А это не что иное как фильтр сигнала по времени. Про дребезг контактов поищите информацию где нибудь еще. Я же кратко скажу, что в самый первый момент нажатия кнопки возникает последовательность из 0 и 1 длящаяся миллисекунды. Ее то и требуется отфильтровывать.
Что такое чекбокс "Включить защиту от дребезга" или блок Bounce. Это два последовательных таймера. Задержка на включение и задержка на выключение. Вы легко можете заменить блок Bounce двумя блоками таймеров на 40мс.
.
3.jpg
3.jpg (7.78 КБ) 1318 просмотров
.
Точно так же можно отфильтровать сигнал и с аналогового входа при старте контроллера, когда в начале данные датчика еще не установились в рабочий режим.
.
4.jpg
4.jpg (5.49 КБ) 1318 просмотров
.
Или отсечь кратковременные помехи во время работы.
.
5.jpg
5.jpg (7.98 КБ) 1318 просмотров
.
Для тех, кому интересно как это работаетПоказать
Формируем сигнал с помехой. Пропускаем его через импровизированный фильтр коротких помех и выводим результат на плоттер.
.
7.jpg
.
Тест1.flp
(1.9 МБ) 24 скачивания
.
6.jpg
.
На входе сигнал с помехой (верхний график). На выходе фильтрованный сигнал (нижний график).

Внимание! В проекте использован блок несимметричного генератора и из FLProg 8.1.0 , IDE выдаст ошибку. Это баг версии.
Исправить ее легко. В строке с ошибкой (выделится красным) замените _isTimer на flprog::isTimer .
.
Похожим образом можно отсечь слишком большие "выбросы" из потока данных, те которых в принципе не должно быть но они иногда появляются. К примеру датчик DS18B20 в совокупности с некоторыми ПБ для него, любит выдать что то типа -127. Если фильтровать это сглаживающими фильтрами, то все равно будет некоторое отклонение от реальной температуры. Поэтому перед сглаживающим фильтром надо отсечь не желательные значения. Сделать это можно так.
.
8.jpg
8.jpg (12.36 КБ) 1297 просмотров
В этом случае пройдут только те данные которые находятся в объявленном диапазоне от 0 до 50. Остальные отсекутся.
.
А можно просто отфильтровать конкретное нежелательное значение.
.
9.jpg
9.jpg (7.86 КБ) 1297 просмотров
Тогда это конкретное значение не попадет на выход нашего очень простого фильтра.
.
Подобным образом можно организовать фильтрацию нескольких конкретных значений или нескольких диапазонов.
.
ВСЁ ЭТО ЦИФРОВЫЕ ФИЛЬТРЫ !
Не смотря на свою простоту, они очень эффективные в конкретных случаях. Вы не найдете их ни в пользовательских блоках ни в описываемых алгоритмах в Интернете. Это как бы само собой разумеющаяся логика. Можно придумать и еще кучу таких простых решений. Они не нагрузят ваш контроллер. И в то же время будут отлично решать вашу задачу.

.

Аватара пользователя
Dryundel
Полковник
Сообщения: 2401
Зарегистрирован: 22.05.2017{, 23:15}
Репутация: 783
Откуда: Ярославль
Имя: Андрей
Контактная информация:

Цифровые фильтры, фильтрация сигнала (Ликбез)

#3

Сообщение Dryundel » 10.03.2023{, 22:23}

Алгоритмы цифровых фильтров.

Существует огромное множество алгоритмов цифровой фильрации. Все они основаны на математических операциях. И как я писал выше большую роль играет правильность выбора фильтра и его настройки для каждого конкретного сигнала.
Самыми распространенными и наиболее универсальными я бы назвал медианный фильтр и бегущее среднее арифметическое. Очень часто их используют в паре, отфильтровывая сигнал поочередно. Это дает наилучший эффект.
Немаловажной задачей при фильтрации является и легкость алгоритма для процессора. Чем короче формула и меньше буфер фильтра, тем меньше он нагружает процессор. С другой стороны, как правило большие алгоритмы фильтруют качественней. Однако зачастую за качество фильтрации приходится платить временем. Время задержки выходного сигнала по отношению к исходному увеличивается. Поэтому надо стремиться к золотой середине.

Рассмотрим работу фильтров с разными настройками.

Медиана из 3х

Не большое пояснение о том что такое медиана в цифровой фильтрации. Лучше всего на примере.
Из числового ряда 100, 89, 54, 3, 3, 2, 0 медианой будет 3
Медиана это не среднее значение, а такое у которого справа и слева от него (на числовой прямой) будет одинаковое количество значений которые больше или равны и меньше или равны ему из взятого цифрового ряда.
Я расположил значения в порядке убывания, но это только для наглядности. Последовательность ряда может быть любой.

При правильной настройке медианный фильтр хорошо справляется с короткими "выбросами", какой бы величины они небыли.

Пример такой фильтрации.
Сигнал - меандр.
Пиковые выбросы 30 мс
Тактирование 35 мсПоказать
На выходе чистый сигнал без помех.
10.jpg
Тактирование 15 мсПоказать
Отфильтровалась лишь часть помех, а часть осталась
11.jpg
Тактирование 10 мсПоказать
Фильтрации не произошло, хотя фильтр честно выбирал медиану.
12.jpg
Тактирование 800 мсПоказать
Отфильтровался и исказился сам полезный сигнал.
13.jpg
Тестовый проектПоказать
Тест3.flp
(2.57 МБ) 23 скачивания
14.jpg
Теперь рассмотрим более продвинутые примеры. Специально для этого я написал блок шумящего сигнала. Может генерить синус, меандр, треугольник. Ну и блоки фильтров тоже только что "из под пера". Все в beta версиях но вполне рабочее.
Тактирование блоков можно осуществлять по встроенному таймеру, по циклам программы, по входу Tick, ну и самой платой. В последнем случае надо выбрать таймер и установить время "0".
Сам проектПоказать
Тест5.flp
(3.03 МБ) 31 скачивание
15.jpg
15.jpg (26.72 КБ) 1163 просмотра
.
Вот такая картинка получается.
На входе цепочки фильтров шумящий сигнал (оранжевый) под ним исходный сигнал, ну и на выходе отфильтрованная и почти чистая синусоида (зеленый). Можно было бы сделать ее еще глаже, но время запаздывания увеличится.
.
16.jpg
.
Пробуйте, тестируйте, изменяйте параметры фильтров и генератора шумящего сигнала. Все наглядно.
Не забудьте установить скорость на плоттере 115200.

17.jpg
17.jpg (9.58 КБ) 999 просмотров
Самой первой строчкой, стартового топика, я обещал небольшую серию статей.
А эта идея тянет на полгода. :)


Продолжение редактируется .....


.

Ответить

Вернуться в «Обучающие примеры работы в FLProg»