Я также выбрал параметр 1st order (первого порядка). Большее значение этого параметра приведет к увеличению числа хранимых предшествующих замеров и крутизны затухания амплитудно-частотной характеристики (АЧХ) на частотах полосы подавления. Для данного примера вполне подойдет значение 1st order. Увеличение порядка потребует выполнения дополнительных вычислений и, возможно, уменьшения частоты следования замеров, чтобы плата Arduino успевала делать это.
Затем идут несколько неактивных полей ввода, имеющих отношение к фильтрам других конструкций, а еще ниже — параметр samplerate (частота замеров). Этот параметр определяет частоту, с которой будет производиться отбор данных, а также частоту, с которой сгенерированный код будет вызываться для фильтрации сигнала.
Далее я определил верхний и нижний пороги полосы подавления. В эти поля можно вводить частоту в герцах или ноту MIDI.
Раздел more (дополнительно) включает пару дополнительных параметров и даже содержит подсказки, как лучше их настроить. В разделе output
Рис. 13.8. Генератор реализаций фильтров для Arduino
(выходной сигнал) можно выбрать тип массива значений, который будет использоваться для фильтрации. Я выбрал тип float type (вещественный). В заключение щелкнул на кнопке Send (Отправить), чтобы сгенерировать код.
Для проверки можно взять за основу пример скетча null filter, который использовался в эксперименте с платой Due. Полный скетч можно найти в пакете примеров под именем sketch_13_05_band_stop_due.
Сначала скопируйте сгенерированный код в буфер обмена и вставьте его в базовый пример null filter сразу после определения констант. Добавьте в код комментарий с адресом URL страницы генератора, чтобы при необходимости можно было вернуться и изменить настройки фильтра: URL хранит выбранные вами значения параметров. Сгенерированный фильтр оформлен в виде класса. Мы еще встретимся с классами в главе 15. А пока просто считайте его черным ящиком, выполняющим фильтрацию.
После вставленного кода добавьте следующую строку:
filter f;
Теперь нужно изменить функцию loop, чтобы вместо простого вывода входного сигнала плата Arduino выводила отфильтрованные значения:
void loop()
{
static long lastSampleTime = 0;
long timeNow = micros();
if (timeNow > lastSampleTime + samplePeriod)
{
int raw = analogRead(analogInPin);
float filtered = f.step(raw);
analogWrite(analogOutPin, (int)filtered);
lastSampleTime = timeNow;
}
}
Чтобы получить отфильтрованное значение, достаточно просто вызвать функцию f.step и передать ей значение, прочитанное с аналогового входа. Возвращаемое значение этой функции и есть отфильтрованное значение, которое нужно привести к типу int перед записью в ЦАП.
Заглянув в функцию step, можно увидеть, что реализация фильтра хранит три последних и один текущий замер. Далее производятся некоторые манипуляции со значениями, а затем они масштабируются коэффициентами, чтобы получилось возвращаемое значение. Разве математика не прекрасна?
На рис. 13.9 показан результат фильтрации. С помощью генератора воспроизводились сигналы разной частоты, амплитуда выходного сигнала (измерялась с помощью осциллографа) записывалась в электронную таблицу, и затем по массиву полученных данных строился график.
Рис. 13.9. АЧХ полосового фильтра на основе Arduino
Преобразование Фурье
Преобразование Фурье — удобный инструмент анализа частотных характеристик сигнала. Как уже говорилось во введении к этой главе, сигналы часто формируются путем наложения разного количества синусоид с разной частотой. Возможно, вам приходилось видеть дисплеи анализаторов спектра на музыкальном оборудовании или средства визуализации в программных проигрывателях MP3. Они имеют вид столбиковой диаграммы. Высота каждого столбика соответствует мощности соответствующей полосы частот, при этом низкочастотные басовые ноты отображаются слева, а высокочастотные — справа.
На рис. 13.10 показано, как один и тот же сигнал может быть представлен в виде одной линии (называется временной областью) и как множество значений мощности сигнала на разных частотах (называется частотной областью).
Алгоритм расчета частотной области из данных временной области сигнала называется быстрым преобразованием Фурье (БПФ). В вычислениях преобразования используются комплексные числа, и его реализация — задача не для слабых духом, если только вы не увлекаетесь математикой.