Фильтр низких частот

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

  • аппаратные и программные;
  • цифровые и аналоговые;
  • линейные и нелинейные;
  • фильтры средних, низких и высоких частот;
  • и т.п.

В этой статье мы рассмотрим один из самых распространенных электронных фильтров — фильтр низких частот (ФНЧ, low pass filter), а точнее — его программную реализацию. Применительно к робототехнике, данный тип фильтров используется для сглаживания показаний различных датчиков и сигналов управления.

Шум переменного резистора

Итак, рассмотрим простую задачу. Пусть на входе микроконтроллера имеется зашумленный сигнал, например сигнал переменного резистора, подключенного к Ардуино. На рисунке ниже представлен пример такого сигнала.

График сигнала переменного резистора

Здесь, по оси абсцисс отсчитывается время, а по оси ординат показания 10-разрядного АЦП, к которому подключен потенциометр. Проблема в том, что как бы мы плавно не поворачивали ручку переменного резистора, сигнал получаемый микроконтроллером будет всё время колебаться. Видно, что график не плавный, на нём имеются «зубчики».

Это объясняется двумя причинами. Во-первых, во время движения центрального контакта переменного резистора по поверхности резистивного материала
возникает такое явление как «дребезг контактов». Во-вторых, человек в принципе существо «дрожащее», и любое его движение вызывает вибрацию.

Кроме того, даже когда ручка прибора не поворачивается, наблюдаются небольшие колебания сигнала. Это — результат воздействия различных наводок в цепи между АЦП и датчиком. На рисунке ниже зафиксированы именно такие наводки.

График сигнала переменного резистора

Фильтр низких частот

Чтобы сгладить все эти неровности и устранить мелкие колебания, мы воспользуемся самым простым ФНЧ на основе интегратора. Для этого, при каждом считывании сигнала мы будем выполнять следующее действие:

pot = (1-K)*pot + K*pot_raw

Здесь pot — обработанный фильтром сигнал, pot_raw — значение на аналоговом входе контроллера, и наконец K — коэффициент фильтра, который варьируется от 0,0 до 1,0.

Коэффициент K определяет, какие колебания считаются слишком высокими и требуют подавления, а какие следует пропустить с минимальными изменениями. Чем больше K, тем слабее фильтр, и тем более высокие колебания он может пропустить. Ниже представлен результат работы фильтра для K = 0,1.

Фильтр низких частот K=0,1
Синий — исходный сигнал, красный — обработанный. K=0,1
Фильтр низких частот K=0,1
Синий — исходный сигнал, красный — обработанный. K=0,1

Легко заметить, что при K = 0,1 фильтрованный сигнал не имеет шума. Но как понять, какую величину K нам следует использовать?

Подбор коэффициента фильтра

При выборе значения K необходимо отталкиваться от того, какие изменения сигнала нам интересны, а какие мы будем считать за шум. Сделать это можно с помощью следующего выражения:

t = (1-K) * dt / K

где t — период времени, который отделяет слишком быстрые изменения от требуемых; dt — время итерации.

Например, если в нашем случае с потенциометром, K = 0,1, а время между двумя измерениями dt = 20 мс, то время t = (1-0.1) * 0,02 / 0.1 = 0,18 сек. То есть все изменения сигнала, которые длятся меньше 0,18 секунд будут подавляться. Во втором случае (при K = 0,3), мы получим t = 0,047 сек.

Второй смысл времени t заключается в том, что обработанный фильтром  сигнал будет отставать от исходного на это время. Ниже на графике это отставание хорошо заметно.

Фильтр низких частот K=0,1
Синий — исходный сигнал, красный — обработанный. K=0,1

На практике, переменные резисторы имеет смысл фильтровать с коэффициентом K от 0,1 до 0.3.

Пример программы для применения ФНЧ к сигналу переменного резистора

Напишем программу для Ардуино, которая будет считывать сигнал переменного резистора и накладывать на него ФНЧ с коэффициентом K = 0,1.

const byte potPin = A5;
const float K = 0.1;

float val = 0;

void setup() {
    Serial.begin(9600);
    pinMode( potPin, INPUT );
}

void loop() {
    int pot = analogRead( potPin );
    val = val*(1-K) + pot*K;
    Serial.println(int(val));
    delay(20);
}

Фильтрация сигнала акселерометра

Еще одним удачным примером использования ФНЧ может служить обработка сигнала акселерометра. Ниже представлены графики показаний акселерометра с применением фильтр и без, для разных K.

Фильтр низких частот K=0,5
K = 0,5
Фильтр низких частот K=0,1
K = 0,1

Источники шумов у акселерометра, отличаются от источников шума в цепи переменного резистора. Дело в том, что акселерометр регистрирует ускорение прибора, не различая, что явилось его причиной: сила гравитации или внешняя сила приложенная к датчику. Другими словами, если датчик находится в покое, то на него воздействует только сила гравитации, и мы легко узнаем углы наклона датчика относительно поверхности земли. Но если, например, датчик повернуть рукой вокруг одной оси, на него, кроме гравитации, подействует внешний момент силы, что приведет к ошибкам при расчете углов наклона. Другой источник шума — вибрация от двигателей, например, квадрокоптера.

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

К размышлению

Фильтр низких частот отлично помогает, когда необходимо очистить нужный нам сигнал от высокочастотных помех. Примером таких помех может быть шум от наводок или вибрации, наложенный на сигнал от переменного резистора. Другой пример — вибрация поверх сигнала акселерометра или гироскопа.

Главное при работе с ФНЧ — правильно подобрать коэффициент K. Необходимо чтобы сигнал не имел слишком большой задержки с одной стороны, и достаточно хорошо сглаживал сигнал — с другой.

В одной из следующих статей мы расскажем об аппаратном фильтре низких частот, который не требует контроллера.


Изменено:

Фильтр низких частот: 5 комментариев

  1. Я чаще использую фильтр бегущего среднего значения, пишытся в одну строку и работает отлично, особенно на аналоговых портах.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

This site uses Akismet to reduce spam. Learn how your comment data is processed.