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

Что такое БПФ и как вы можете реализовать его на Arduino?

  1. FFT
  2. Частота дискретизации
  3. Количество образцов
  4. Бункеры
  5. Arduino
  6. Установка библиотеки
  7. Наш пример и код
  8. Результаты
  9. Последняя глава

В этом сообщении мы сначала кратко обсудим преобразование Фурье и БПФ. Затем мы покажем вам один из способов реализации FFT на Arduino.

Быстрое преобразование Фурье (также известное как FFT ) - это алгоритм, который вычисляет дискретное преобразование Фурье (DFT). Мы не собираемся углубляться в относительно сложную математику вокруг преобразования Фурье, но один важный принцип здесь заключается в том, что любой сигнал (даже непериодический) может быть достаточно точно восстановлен путем добавления синусоидальных сигналов вместе с различными частотами и амплитудами. Чем больше синусоидальных сигналов мы складываем вместе, тем больше наш восстановленный сигнал будет выглядеть как исходный. Теоретически, с бесконечным количеством синусоидальных сигналов мы получаем сигнал, идентичный оригиналу.

Отказ от ответственности: отныне мы будем использовать только термин FFT (для простоты), хотя DFT или просто преобразование Фурье могут быть правильным термином в некоторых случаях.

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

Ниже приведен хороший GIF, который показывает, как шесть синусоидальных сигналов, сложенных вместе, могут напоминать прямоугольный сигнал

GIF источник неизвестен (giphy).

FFT

Алгоритм FFT использует этот принцип и, по существу, позволяет вам видеть, какие частоты присутствуют в любом аналоговом сигнале, а также видеть, какие из этих частот являются наиболее доминирующими . Это очень полезно в огромном количестве приложений. Графики, подобные синему с единственными шипами (f ^) в GIF выше, это то, что вы обычно получаете после запуска FFT:

  • Ось X - это частота - чем выше эта ось, тем выше частота.
  • Ось Y - это амплитуда - чем выше эта ось, тем больше амплитуда.

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

Если вы примените БПФ к синусоидальному сигналу без шума, вы получите только один пик . Это логично, так как вам нужен только один синусоидальный сигнал, чтобы воссоздать синусоидальный сигнал.

Однако, если вы примените БПФ к прямоугольному сигналу (как показано в GIF), вы получите экспоненциально убывающий график , на котором присутствует много частот с четным интервалом между ними. Самая низкая частота имеет наибольшую амплитуду (это основная частота прямоугольного сигнала), а самые высокие частоты имеют самые низкие амплитуды.

Частота дискретизации

Теорема Найквиста-Шеннона о сэмплировании говорит нам, что для возможности дискретизации сигнала частота дискретизации должна быть как минимум вдвое больше частоты сигнала, который мы пытаемся сэмплировать . Другими словами, БПФ сможет обнаруживать частоты только до половины частоты дискретизации .

На обычном Arduino частота дискретизации довольно ограничена. Операция АЦП (с использованием analogRead ()) занимает около 100 мкс, а другие операции относительно медленные из-за тактовой частоты 8 или 16 МГц.

Количество образцов

Алгоритм FFT работает с конечным числом выборок . Это число должно быть 2n, где n - целое число (в результате получается 32, 64, 128 и т. Д.). Чем больше это число, тем медленнее будет алгоритм. Однако, со многими образцами вы получите большее разрешение для результатов.

Бункеры

Термин bin связан с результатом FFT, где каждый элемент в массиве результатов является bin. Можно сказать, что это «разрешение» БПФ. Каждый бин представляет частотный интервал , как гистограмма. Количество бинов, которые вы получаете, составляет половину количества выборок, охватывающих диапазон частот от нуля до половины частоты дискретизации .

Arduino

Есть, конечно, несколько способов реализации FFT на Arduino. Вы можете реализовать это с нуля или использовать готовую библиотеку . В этом посте мы сделаем последнее.

Установка библиотеки

Первое, что вам нужно сделать, это установить библиотеку, что очень просто. Мы используем arduinoFFT от kosme , который не следует путать с этот библиотека.

Чтобы установить arduinoFFT, откройте окно «Управление библиотеками», введите fft в строке поиска и установите последнюю версию.

Чтобы установить arduinoFFT, откройте окно «Управление библиотеками», введите fft в строке поиска и установите последнюю версию

Теперь вы готовы начать кодирование!

Наш пример и код

Здесь мы будем использовать установку Arduino Uno и генератор сигналов . Единственные провода - два от генератора сигналов, где один идет к A0 на Arduino, а другой идет к GND . Наш сигнал имеет амплитуду и смещение, так что он почти охватывает весь диапазон 0-5 В , что хорошо соответствует свойствам нашего АЦП.

В отличие от примера кода, поставляемого с библиотекой, мы применяем БПФ к надлежащему аналоговому сигналу. Пример кода генерирует симулированный синусоидальный сигнал и применяет к нему БПФ.

Вот код:

#include "arduinoFFT.h" #define SAMPLES 128 // Должно быть степенью 2 #define SAMPLING_FREQUENCY 1000 // Гц, должно быть меньше 10000 из-за АЦП arduinoFFT FFT = arduinoFFT (); без знака int sampling_period_us; неподписанные длинные микросекунды; double vReal [ОБРАЗЦЫ]; двойной вимаг [ОБРАЗЦЫ]; void setup () {Serial.begin (115200); sampling_period_us = round (1000000 * (1.0 / SAMPLING_FREQUENCY)); } void loop () {/ * SAMPLING * / for (int i = 0; i <SAMPLES; i ++) {microseconds = micros (); // переполняется примерно через 70 минут! vReal [i] = analogRead (0); vImag [i] = 0; while (micros () <(микросекунды + sampling_period_us)) {}} / * FFT * / FFT.Windowing (vReal, SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD); FFT.Compute (vReal, vImag, SAMPLES, FFT_FORWARD); FFT.ComplexToMagnitude (vReal, vImag, SAMPLES); двойной пик = FFT.MajorPeak (vReal, SAMPLES, SAMPLING_FREQUENCY); / * РЕЗУЛЬТАТЫ ПЕЧАТИ * / //Serial.println(peak); // Распечатать, какая частота является наиболее доминирующей. for (int i = 0; i <(SAMPLES / 2); i ++) {/ * Просмотреть все эти три строки в последовательном терминале, чтобы увидеть, какие частоты имеют какие амплитуды * / //Serial.print((i * 1.0 * SAMPLING_FREQUENCY) / ОБРАЗЦЫ, 1); //Serial.print (""); Serial.println (vReal [i], 1); // Просмотр только этой строки в последовательном плоттере для визуализации бинов} // delay (1000); // Повторяем процесс каждую секунду ИЛИ: while (1); // Выполнить код один раз}

Этот код имеет три «режима печати»:

  • Линия 41 может выводить на терминал, какая частота является наиболее доминирующей.
  • Строки 47-49 могут выводить на терминал значения каждого бина.
  • Строка 49 напечатает, может распечатать на плоттере визуализацию всех бункеров.

Последние две строки (52 и 53) являются взаимоисключающими. Либо вы запускаете БПФ один раз, либо запускаете его повторно с определенным интервалом.

Если мы посмотрим на верхнюю часть кода, то увидим, что количество сэмплов равно 128. У Arduino Uno недостаточно памяти для поддержки 256 сэмплов.

Вы также можете распечатать сэмплированный сигнал в цикле сэмплирования. Помните, что функция Serial.println () довольно медленная и может повлиять на вашу частоту дискретизации.

Результаты

Следующие графики извлекаются из последовательного плоттера Arduino после запуска БПФ на нескольких различных сигналах с частотой дискретизации 128 Гц и 128 выборками.

Числа на оси X на графиках ниже - это не частота, а номер элемента (он же bin). На графиках ниже элемент № 64 - это верхняя ячейка (~ 500 Гц). Поскольку наш входной сигнал имеет смещение по постоянному току, мы получаем нулевой пик в результатах.

Результаты БПФ синусоидального сигнала ~ 75 Гц. Благодаря 128 выборкам мы имеем 64 ячейки, которые распределены по частоте 0-500 Гц из-за частоты выборки 1000 Гц. L

L

Результаты БПФ синусоидального сигнала ~ 400 Гц.

Результаты БПФ синусоидального сигнала ~ 400 Гц

Результаты БПФ прямоугольного сигнала ~ 75 Гц.

Результаты БПФ прямоугольного сигнала ~ 75 Гц

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

Последняя глава

FFT - очень удобный инструмент для обработки сигналов во многих областях применения. Библиотека arduinoFFT сделает всю тяжелую работу за вас. Используя Arduino, вы довольно ограничены в плане памяти и частоты дискретизации. Насколько мы понимаем, также часто используется фильтр нижних частот в сочетании с алгоритмом FFT, чего мы не сделали в нашем примере.

Мы рекомендуем использовать генератор сигналов при начале игры с алгоритмом FFT. Таким образом, вы можете легко изменить частоту, формы сигнала, смещение и амплитуду вашего сигнала.

Обновлено 12.02.18 - Пик на нуле объяснил (спасибо, Мэтт N)