Практика использования цифровых фильтров

Делаю тут проект и возникла вот какая проблема. Получаю данные с АЦП (дельта-сигма) микросхемы в которую встроен контроллер и фильтр, но этот фильтр имеет довольно убогую АЧХ, в итоге идёт завал по ВЧ от 60Гц и далее. Выглядит это примерно так:
image

Т.е. такая неравномерность АЧХ нас явно не устраивает (не проходит по техническим требованиям), правда есть возможность повысить частоту дискретизации с 250Гц до 500Гц, чтобы выровнять АЧХ, однако тогда увеличивается объём данных который ещё нужно будет усреднять, что скажется на производительности (проект на STM32F103VE) системы в целом и на общем потреблении энергии (батарейное питание). Но есть и другой путь.

Можно выровнять АЧХ с помощью параметрического цифрового фильтра, в данном случае ВЧ. То есть это тоже самое что эквалайзер, мы поднимаем одни частоты, а другие не трогаем (или заваливаем). Такой метод конечно хорош, но т.к. мы пытаемся восстановить информацию, часть которой была уничтожена другим фильтром на входе (тот что в микросхеме), неизбежно увеличится уровень помех на высоких частотах, т.к. вместе с сигналом мы усилим также и их, но вот насколько?

Итак, идея решения проблемы есть, осталась реализация. Что мы помним о цифровых фильтрах (к тем кто не имел с ними практики) из университетского курса? Разве что такие слова как свёртка, Z-преобразование, импульсная характеристика и т.д. В общем не понятно с какого конца подходить даже, вроде надо какие-то коэффициенты рассчитывать, но что и зачем непонятно, поднимать курс и сидеть с книгами по ЦОС (есть одна на 800 страниц) нет времени, проект стоит и надо что-то делать, и быстро.

Поэтому немного погуглив находим вот такой ресурс в интернете. Это сайт по расчёту цифровых фильтров (и не только!) он-лайн, а сделал его некий Dr Anthony J. Fisher.

Итак задаёмся требованиями которые нам нужны и вводим на сайте. Во-первых, нам нужна плавная характеристика, поэтому однозначно Баттерворт первого порядка ВЧ (highpass). Во-вторых, sample rate, т.е. количество преобразований АЦП в секунду, или частота дискретизации, у нас это 250Гц. Вводим. И наконец, в-третьих, частота среза (-3дБ) — 50Гц, т.к. фильтр на входе режет примерно здесь. Нажимаем отправить и получаем вот такую характеристику нашего будущего фильтра:
image
Красным представлен график амплитуды от частоты Найквиста, синим изменение фазы. 0,5 соответствует половине частоты дискретизации.

Также получаем С код с рассчитанными коэффициентами:
#define NZEROS 1
#define NPOLES 1
#define GAIN   1.726542528e+00

static float xv[NZEROS+1], yv[NPOLES+1];

static void filterloop()
  { for (;;)
      { xv[0] = xv[1]; 
        xv[1] = next input value / GAIN;
        yv[0] = yv[1]; 
        yv[1] =   (xv[1] - xv[0])
                     + (  0.1583844403 * yv[0]);
        next output value = yv[1];
      }
  }

Но это только фильтр, помним, что нам нужно усилить частоты от 50Гц и выше, чтобы выпрямить АЧХ, и эта функция в таком виде нам не поможет, поэтому путём нехитрых манипуляций приводим функцию к такому виду:
#define NZEROS 1
#define NPOLES 1
#define GAIN   1.726542528e+00F
#define OUR_GAIN 2.1F		// наш коэф. усиления фильтра

float xv[NZEROS+1], yv[NPOLES+1];

int void filterloop( int data )
{ 
	xv[0] = xv[1]; 
	xv[1] = (float)data / GAIN;
	yv[0] = yv[1]; 
	yv[1] = ( xv[1] - xv[0] ) + ( 0.1583844403F * yv[0] );
	return (int)(( yv0[1] * OUR_GAIN ) + (float)data );
}


Всё. Чтобы использовать фильтр кидаем данные в параметры функции, а возвращает она отфильтрованные данные. Коэффициент усиления OUR_GAIN подбираем опытным путём, снимая показания с АЦП и замеряя АЧХ.

Таким образом мне удалось поднять АЧХ практически без дополнительной нагрузки на контроллер и мой проект прошёл по техническим требованиям (в медицинской области они весьма не хилые). Я боялся, что сильно возрастёт уровень помех, но он увеличился с 4-5мкВ примерно до 6-8мкВ, что нас устраивает. В заключении могу порекомендовать ещё одну бесплатную программу по расчёту цифровых фильтров — WinFilter, скачать её можно здесь. Насколько она работоспособна не знаю, не проверял, но она может выдавать код в VHDL (и в С естественно), что наверняка пригодится для ПЛИС. Также есть программа от Texas Instuments, по расчёту коэффициентов цифровых фильтров, называется она TIBQ. Всё. Удачи в проектировании цифровых фильтров.

Share post

Comments 17

    +1
    а фаза не важна в медицинской области?
      –1
      Я думаю тут фаза не важна. На падение АЧХ фаза не может влиять, фаза — это же просто сдвиг.
        0
        Почему не важна?
        При изменении фазы сигнал может измениться очень существенно (АЧХ при этом особо не поменяется, т.к. частоты все те же, просто смещенные). Обычно все используются фильтры класса «нулевого фазового сдвига», т.е. меняют только энергетический (амплитудный) спектр.
          0
          фаза это просто сдвиг во временной области, заметные искажения могут быть только при резких перепадах фазы, чего здесь нет, но в любом случае здесь это неважно, т.к. основная информация располагается в диапазоне до 60 Гц, поднять АЧХ нужно было для того, чтобы просто пройти по требованиям. Тестовые сигналы уже пропускал и искажений не заметил.
            0
            > фаза это просто сдвиг во временной области
            Вот именно, поэтому при сдвиге синуса АЧХ останется ровно тем же самым, но форма сигнала может поменяться кардинальным образом. Все распространенные фильтры не меняют фазу, в том числе и фильтр Баттерворда в применении к обработке сигналов.

            Тестовые сигналы уже пропускал и искажений не заметил.
            Искажения могут быть и незаметны — смотря насколько менять фазу и какие элементы ряда затрагиваются.

            Кстати, а почему вы решили что описанный в расчете фильтр меняет фазу? Мне кажется не меняет
              0
              Искажения могут быть и незаметны — смотря насколько менять фазу и какие элементы ряда затрагиваются.
              На меандре максимум видны небольшие пики.

              Кстати, а почему вы решили что описанный в расчете фильтр меняет фазу? Мне кажется не меняет
              Ну, наверное потому, что на графике он показан синей линией, а ось справа +pi и -pi говорит нам о том, что фаза плавно меняется на отрезке от 0 до 125Гц
              0
              Если сдвиг по фазе для НЧ области будет сильно отличаться от того же параметра ВЧ области, то искажетия будут уже сказываться.

              К примеру, если сдвиг по фазе будет постоянным для всех частот, то для на выходе фильтра мы получим тот же входной сигнал, сдвинутый во времени (т.е. просто исходный сигнал с задержкой), что нестрашно в данном контексте.
              А теперь представьте, что мы разложили исходный сигнал на отдельные гармоники, а потом прибавили к разным гармоникам разное смещение во времени и затем сложили обратно. Мы получим «как бы» рассинхронизацию составляющих сигнала.
                0
                на самом деле, если использовать фильтры 1го порядка то можно особо по этому поводу не парится, тут изменения фазы незначительно, а вот 2го и более, это да. Короче думать нужно какие инструменты использовать, нет одного метода на все случаи жизни
        0
        Боюсь показаться снобом :-), но существует распространенная практика, когда используется в статье в первый раз аббревиатура (АЧХ, ВЧ, ВПРДШ:-))) и т.п., то указывается расшифровка. Типа: "… имею мнение хрен оспоришь (ИМХО)....", или наоборот: "… ИМХО (имею мне....)....". Не уверен, что все подписанные на хаб «Алгоритмы» должны знать, что значат ФЧХ и ВЧ, я вот не знаю.
          +3
          Ну, это же тема для специалистов, как можно читать про фильтры и не знать что такое амплитудно-частотная характеристика(АЧХ)? Обо всём не расскажешь же, тут есть ещё ЦОС, ПЛИС, ВЧ, страшное сокращение Гц...)
            +1
            Ну можно же использовать в начале статьи тэг abbr с title: АЧХ
              0
              мм, пока ещё не знаю как, первая же статья, попозже посмотрю
              0
              Согласен, что обо всем не рассказать, однако уверен, что после расшифровки аббревиатур, которые вы используете, большинству людей не придется объяснять, что это такое и сразу все станет понятным. Такие правила «приличия» не зря придумали, поверьте :-)
              0
              Если Вы этого не знаете, он вряд ли сумеет в статье рассказать, о чем именно идет речь. Гугл наверняка сумеет это лучше.
              ЗЫ: ФЧХ — Фазо-Частотная Характеристика, ВЧ — Высокие Частоты.
                0
                Спасибо за расшифровку. Википедия, после этого мне не понадобилась.
                Я знаю, что такое фаза, частота, соответственно мне не сложно догадаться, что такое фазо-частотная характеристика. И мне не нужно объяснять, что такое высокие частоты, мне достаточно просто 1 раз увидеть, что ВЧ — высокие частоты. Могу только еще раз повторить, как человек не шибко крутой, но публиковавший некоторое количество статей в научных и околонаучных журналах, не зря существует практика: расшифруй аббревиатуру и потом используй, это так просто, но упростит жизнь некоторым читателям :-)
              0
              Если вы испольузется собственный OUR_GAIN, то можно съэкономить немного процессорного времени, убрав деление xv[1] = (float)data / GAIN;
                0
                да, я пытался, что-то у меня правда не получилось, похоже там и коэффициенты надо пересчитывать, попробуйте на свой страх и риск

              Only users with full accounts can post comments. Log in, please.