Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Как правильно фильтровать?
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
inventor
Задача такая - у меня АЦП может работать только на минимальной частоте 1000 Гц.
мне нужны кратные частоты: 125, 250 и 500.
Получить их можно проведя децимацию, предварительно перед которой
отфильтровав все что выше чстоты найквиста.
т.е. для получения данных на частоте 500,
я запускаю измерения на 1000 Гц,
фильтрую все что выше 250
и беру каждый второй отсчет.
Не стал заморачиваться с фильтрами - смотрю они уже есть в армовсеом коде
(те у кого STM в папке SMSIS)
у меня процессор СС3200 - не нашел примеров именно для него,
пока взял библиотечку у STM - она подходит к техасу (ф-я void arm_fir_decimate_fast_q31(///)).
Есть несколько вопросов, у меня может быть от 1-го канала до 8-ми,
вот как их всех одновременно фильтровать?
Код, который делает АРМ я так понимаю УЖЕ оптимизирован
по скорости, объему и прочему, сокращено количество циклов и всяких MAC операций.
как сделать "нормальную" фильтрацию одновременно всех 8-ми каналов,
и сколько навскидку времени уйдет на вызов функции фильтрации
т.е. переписать саму функцию фильтрации, чтобы использовать только 1 функцию
вместо идкущих подряд 8 и что то другое.
у кого какие мысли?

TSerg
Поставить 8 CPU.
kovigor
Цитата(TSerg @ Oct 28 2015, 15:52) *
Поставить 8 CPU.

Или реализовать фильтры на ПЛИС. А иначе никак, ИМХО, "синхронной" фильтрации по 8 каналам не достичь ...
Хотя, если у вас время между отсчетами достаточное большое ... Получаем, например, по 32 отсчета с каждого канала и для каждого из каналов вызываем функцию фильтрации. Таких вызовов будет 8. Главное, чтобы все они уложились в промежуток между входными отсчетами (с некоторым запасом), тогда при получении 33-го входного отсчета мы сможем выдать выходной отсчет, запомнить 33-й входной отсчет и "пустить его в работу" ...
ViKo
Зачем "одновременно"? Обрабатывайте блоки от каждого канала по-очереди. Блок сделайте равным коэффициенту децимации. После каждого вызова функции получите одну точку результата для одного канала. Чисто теоретически, imho.
Tarbal
Если вам не нужно 1000 герцовых измерений, то на входе АЦП ставьте аналоговый фильтр, который отрезает выше 250, тогда фильтрация при первой децимации не понадобится.
inventor
Цитата(ViKo @ Oct 28 2015, 16:17) *
Зачем "одновременно"? Обрабатывайте блоки от каждого канала по-очереди. Блок сделайте равным коэффициенту децимации. После каждого вызова функции получите одну точку результата для одного канала. Чисто теоретически, imho.

то есть сначала для первого отсчета, через 32 отсчета для второго, через 64 для третьего?
Правильно?
насчте синхронной филттрации.
у меня не звук, где это было бы допустимо
там сейсмоданные и желательно знать когда сигналы к чему относятца.
сейчас у меня обычный FIR фильтр, который дает задержку на 32 отсчета,
т.е. на 32 миллисекунды.
хотелось бы чтобы время, которое я записываю с данными датчиков
соответсвовало первому отсчету в пачке.
а таким образом (не одновременная фильтрация)
время будет соответсвовать только примерно.
Tarbal
Цитата(ViKo @ Oct 28 2015, 17:17) *
Зачем "одновременно"? Обрабатывайте блоки от каждого канала по-очереди. Блок сделайте равным коэффициенту децимации. После каждого вызова функции получите одну точку результата для одного канала. Чисто теоретически, imho.


Я так понял, что надо на лету в реалтайме обрабатывать.
kovigor
Цитата(Tarbal @ Oct 28 2015, 16:26) *
Я так понял, что надо на лету в реалтайме обрабатывать.

А я понял, что надо одновременно брать отсчеты по восьми каналам и одновременно обрабатывать. Короче, пусть ТС объяснится ...
Tarbal
Цитата(inventor @ Oct 28 2015, 17:24) *
то есть сначала для первого отсчета, через 32 отсчета для второго, через 64 для третьего?
Правильно?


Можно и так. Но есть и другой способ:
Записали в буфер и три раза разными дорожками пустили. Все зависит от ваших целей.
ViKo
Цитата(inventor @ Oct 28 2015, 16:24) *
то есть сначала для первого отсчета, через 32 отсчета для второго, через 64 для третьего?
Правильно?

Функция обрабатывает блоки данных. Ваша задача сформировать эти блоки. Если у вас 8 каналов, распихивайте принятые с АЦП данные по 8-ми массивам (блокам). И вызывайте функцию для обработки каждого из блоков. Я бы сделал входной блок размером с к-т децимации, и как только он заполнен, вызывал бы функцию.

Вообще, какая там математика - децимация. Возьмите 2(4, 8) выборки, сложите и поделите на 2 (4, 8). rolleyes.gif

Цитата(inventor @ Oct 28 2015, 16:24) *
сейчас у меня обычный FIR фильтр, который дает задержку на 32 отсчета,
т.е. на 32 миллисекунды.
хотелось бы чтобы время, которое я записываю с данными датчиков
соответсвовало первому отсчету в пачке.

Сдвиньте результат на 32 шага назад. rolleyes.gif
TSerg
Цитата(inventor @ Oct 28 2015, 16:24) *
то есть сначала для первого отсчета


Что-то Вы путаете кислое с пресным. На одном процессоре невозможно параллельно обработать многоканальный поток данных - только последовательно.

Можно организовать быстрый ввод по одному отсчету с каждого канала и до поступления очередных отсчетов реализовать FIR-ы по всем каналам.
Сдвиг по времени каждого отсчета определиться максимально допустимой частотой переключения опроса датчиков.
Время - условное понятие. Если известна частота опроса датчиков, то shift легко вычисляется.
Tarbal
Цитата(ViKo @ Oct 28 2015, 17:35) *
Вообще, какая там математика - децимация. Возьмите 2(4, 8) выборки, сложите и поделите на 2 (4, 8). rolleyes.gif


Децимация действительно легко делается, но предшествующая ей фильтрация требует подсчета свертки.
Да еще и с высокой точностью, что обычная целая математика не прокатит.
ViKo
Цитата(Tarbal @ Oct 28 2015, 16:58) *
Децимация действительно легко делается, но предшествующая ей фильтрация требует подсчета свертки.
Да еще и с высокой точностью, что обычная целая математика не прокатит.

Если входной сигнал сразу отфильтровать (тем самым, ААА-фильтром) под частоту дискретизации после децимации, то и фильтрации не надо.
Среднее арифметическое - тоже фильтр НЧ.
Простейшая децимация - просто отбросить ненужные выборки, как будто их и не было.
TSerg
Цитата(Tarbal @ Oct 28 2015, 16:58) *
Д обычная целая математика не прокатит.


Смотря какой фильтр sm.gif
inventor
Цитата(ViKo @ Oct 28 2015, 17:05) *
Простейшая децимация - просто отбросить ненужные выборки, как будто их и не было.

так у меня уже сделано - брал 2-й, 4-й и 8-й отсчет
просто не хочу нехороших эффектов с наложением.
мне кажется цифровой фильтр все таки должен быть.

ViKo
Цитата(inventor @ Oct 28 2015, 17:14) *
так у меня уже сделано - брал 2-й, 4-й и 8-й отсчет
просто не хочу нехороших эффектов с наложением.
мне кажется цифровой фильтр все таки должен быть.

Конечно. Зачем же игнорировать работу АЦП. Возьмите среднее арифметическое... disco.gif
Если хочется "фильтр", можно и целочисленной арифметикой обойтись. Можно даже без умножений. Пусть будет не идеальная АЧХ, подпадающая под известные фамилии. Но фильтровать все равно будет.
К примеру, для 4 выборок: взять с весом 0,5 1,5 1,5 0,5
AlexandrY
Цитата(inventor @ Oct 28 2015, 14:05) *
Код, который делает АРМ я так понимаю УЖЕ оптимизирован
по скорости, объему и прочему, сокращено количество циклов и всяких MAC операций.


Не видно чтобы там код был оптимизирован. Он же на C-и написан. Там оптимизацию еще делать и делать.

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

Ну и наконец компилируем все в IAR. Получим еще с несколько десятков процентов приращения производительности.
Tarbal
Цитата(ViKo @ Oct 28 2015, 18:23) *
Конечно. Зачем же игнорировать работу АЦП. Возьмите среднее арифметическое... disco.gif
Если хочется "фильтр", можно и целочисленной арифметикой обойтись. Можно даже без умножений. Пусть будет не идеальная АЧХ, подпадающая под известные фамилии. Но фильтровать все равно будет.
К примеру, для 4 выборок: взять с весом 0,5 1,5 1,5 0,5


Moving average фильтр имеет прямоугольное окно, что порождает сильные боковые лепестки. Анти-алиасинг фильтр -- зверь потоньше. Там полиномы Чебышева или Якоби в ходу.

Если на то пошло, то можно и совсем не фильтровать. Тоже как-то будет работать.
ViKo
Цитата(Tarbal @ Oct 28 2015, 17:38) *
Moving average фильтр имеет прямоугольное окно, что порождает сильные боковые лепестки. Анти-алиасинг фильтр -- зверь потоньше. Там полиномы Чебышева или Якоби в ходу.

Да, боковые лепестки. В которые, если на входе сигнал был отфильтрован, уже ничего не попадет. Надо выбрать, что реально можно успеть сделать.
Tarbal
Все зависит от задачи. Но надо знать больше о проблеме. Что-то можно делать, а что-то не стоит.
Например если разница в спектральном разрешении между разными сериями (500, 250 и 125) не важна и спектра до 62 герц хватит для всех выборок, то можно сразу поставить на входе анти-аллиасинг на 62 герца и делать только децимацию. Фильтрация не нужна.

Цитата(ViKo @ Oct 28 2015, 18:41) *
Да, боковые лепестки. В которые, если на входе сигнал был отфильтрован, уже ничего не попадет. Надо выбрать, что реально можно успеть сделать.


Все зависит от деталей. Для чего-то да, а для другого нет.
SasaVitebsk
Цитата(AlexandrY @ Oct 28 2015, 17:34) *
Не видно чтобы там код был оптимизирован. Он же на C-и написан. Там оптимизацию еще делать и делать.
Сначала надо избавится от передачи аргументов по указателям. Лучше вообще аргументы сделать статическими переменными. Автоматные переменные тоже делаем статическими.
Потом развернуть циклы, длина фильтра известна заранее, значит убираем ее из аргументов.
Выравниваем функцию в памяти, выравниваем данные в памяти. Избавляемся от копирования коэффициентов.
Делаем функцию инлайновой.

Ну и наконец компилируем все в IAR. Получим еще с несколько десятков процентов приращения производительности.

Вот именно. Как по мне, проблема не в том, что "на С написано", а в том, что они данные под свою задачу оптимизировали. А в реальном проекте данные поступают в зависимости от способа их получения.
По поводу целочисленных фильтров - зависит от числа значащих разрядов, при обработке, от разрядности входных данных, от формы и зашумлённости входного сигнала.
Я себе делаю мат модель, имитирую входной сигнал, зашумляю его, потом дискретезирую его (имитирую АЦП) а потом прогоняю своей прогой и так вылизываю алгоритм. Порой, всё равно на реальном объекте нюансы возникают, но, тем не менее, удаётся сэкономить время на отладке в разы.
На мат моделе вылазят разные штуки, важные для понимания. Так, к примеру, столкнулся в последней задаче, что результат обработки (декодирование у меня было) сильно зависел от стабильности амплитуды полезного сигнала. Пришлось ввести АРУ. Сделал 2 варианта - программный и аппаратный. Результат практически идентичный, хотя, по идее аппаратный должен быть эффективнее, так как повышает число значащих разрядов.
И вообще. На таких задачах, как я убедился, самое главное - возможность максимально точно сымитировать входное воздествие.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.