Оглавление:

QuickFFT: высокоскоростной БПФ для Arduino: 3 шага
QuickFFT: высокоскоростной БПФ для Arduino: 3 шага

Видео: QuickFFT: высокоскоростной БПФ для Arduino: 3 шага

Видео: QuickFFT: высокоскоростной БПФ для Arduino: 3 шага
Видео: Быстрые ноги, Упражнения для QB, QB DRILLS Quick Fit #русскийбол 2024, Июнь
Anonim
QuickFFT: высокоскоростной БПФ для Arduino
QuickFFT: высокоскоростной БПФ для Arduino

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

В одном из своих инструкций я подготовил код для БПФ, который можно найти здесь: EasyFFT

Этот код смог выполнить БПФ до 128 выборок на Arduino nano. Более высокое число отсчетов невозможно из-за ограниченной памяти Arduino. Я немного изменил функцию, чтобы повысить скорость и уменьшить потребление памяти. Эта модификация позволяет Arduino выполнять БПФ в пять раз быстрее и потребляет почти половину памяти. Это руководство не охватывает работу с БПФ, ссылки на него можно найти на EasyFFT.

Шаг 1. Работа

Работающий
Работающий
Работающий
Работающий
Работающий
Работающий
Работающий
Работающий

Типичная функция БПФ изменена для повышения скорости с меньшей точностью. Как показано на изображении, тестовый сигнал необходимо умножить на синусоидальный или косинусоидальный сигнал. Эти значения могут быть от 0 до 1, поэтому выполнение умножения с плавающей запятой является обязательным. в Arduino умножение с плавающей запятой выполняется медленно по сравнению с целочисленными операциями.

В этой функции синусоидальная / косинусоидальная волна заменяется прямоугольной волной. Поскольку мы должны умножить тестовый сигнал на прямоугольную волну, которая может иметь значение 0, 1 или -1. Благодаря этому мы можем заменить умножение с плавающей запятой на простое сложение или вычитание целых чисел. Для Arduino сложение или вычитание целых чисел происходит примерно в 5 раз быстрее. Это ускоряет решение примерно в 5 раз.

Благодаря этой модификации теперь значения частотного бина могут быть сохранены в виде целого числа (которое раньше было плавающим), и мы получаем еще одно преимущество - меньшее потребление памяти. В Arduino Nano int потребляет 2 байта памяти, а float - 4 байта памяти. Благодаря этому преимуществу в новом коде мы можем выполнять БПФ почти для 256 отсчетов (ранее 128 отсчетов).

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

Реализация:

Реализовать эту функцию просто. Мы можем просто скопировать функцию в начале кода. Эта функция может быть выполнена с помощью следующей команды:

float f = Q_FFT (data, 256, 100); В функции Q_FFT, данные: этот термин представляет собой массив, содержащий значения сигналов, рекомендуемый размер выборки - 2, 4, 8, 32, 64, 128, 256, 512,… и далее. если размер выборки не принадлежит этим значениям, он будет обрезан до ближайшей нижней части значений. например, если размер выборки равен 75, то БПФ будет выполняться для 64 номеров выборок. Максимальный размер выборки ограничен доступной оперативной памятью на Arduino.

Второй член определяет количество выборок в массиве, а последний член - это частота выборки в Гц.

Шаг 2: Код

В этом разделе объясняются изменения, внесенные в код EasyFFT, которые необходимо учитывать при внесении изменений в код.

1. Как объяснялось ранее, здесь для БПФ используются целые числа. Int в Arduino - это 16-битное число, которое может содержать значения от -32768 до 32768. Всякий раз, когда значение этого int превышает этот диапазон, возникает проблема. чтобы устранить эту проблему после любого расчета уровня. если какое-либо значение превышает 15000, полные массивы будут разделены на 100. это предотвратит переполнение int.

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

3. В этом коде нет модуля для обнаружения множественных пиков. Он просто выберет значение с максимальной амплитудой (исключая первое число, которое является смещением постоянного тока). Если вам нужно несколько пиков, вы можете обратиться к коду EasyFFT и внести необходимые изменения здесь. В этом случае некоторый массив / переменная также должна быть объявлена как глобальная переменная.

4. Функция содержит следующую строку:

беззнаковое int Pow2 [13] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048};

объявление вышеуказанных переменных в качестве глобальной переменной (вставка ее в начало кода) сэкономит где-то 1 миллисекунду при каждом выполнении.

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

float f = Q_FFT (данные, 256, 100);

6. Обнаружение пика: как только частота с максимальной амплитудой найдена, эта функция использует амплитуду частоты непосредственно перед и после нее для вычисления точных результатов. Амплитуда, используемая в этом расчете, также является суммой модулей (а не квадратным корнем из суммы квадратов).

если Fn - частота с максимальной амплитудой, тогда частота может быть рассчитана по формуле ниже.

Фактическое F = (A n-1 * Fn-1 + An-1 * Fn-1 + An-1 * Fn-1) / (An-1 + An + An + 1)

где An - амплитуда n частоты, а Fn-1 - значение частоты.

Шаг 3: Результаты:

Полученные результаты
Полученные результаты
Полученные результаты
Полученные результаты

Время решения показано на приведенном выше сравнении изображения с EasyFFT. Скорость этого показана при сравнении.

Для выборочных данных показаны 3 синусоидальные волны с разными частотами. Результат QuickFFT сравнивается с выводом Scilab'а. Как мы видим на изображении, 3 пика с максимальной амплитудой совпадают с выходными данными Scilab'а. Однако на выходе много шума, который может вводить в заблуждение для некоторых приложений. Поэтому рекомендуется правильно проверить код перед тем, как подавать заявку в ваше приложение.

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

Рекомендуемые: