FFT-спектральный анализатор низких частот
- Войдите на сайт для отправки комментариев
Решил реализовать анализ звукого сигнала, особенно низких частот. За основу взял вот эту статью
http://wiki.amperka.ru/slot-box:light-show?utm_source=proj&utm_campaign=...
переписал код таким образом:
// включаем функцию для логарифмического формата #define LOG_OUT 1 // задаем количество выходных отсчетов #define FFT_N 384 // подключаем библиотеку FFT — быстрое преобразование Фурье #include <FFT.h> // номер пина датчика микрофона #define MIC_PIN A0 long previousMillis = 0; void setup() { // открываем последовательный порт Serial.begin(115200); // назначаем пины светодиодов в режим выхода } void loop() { // считываем заданное количество отсчётов for (int i = 0 ; i < FFT_N; i++) { // считываем показания микрофона и вычитаем отрицательную полу-волну int sample = analogRead(MIC_PIN) - 511;//153 // игнорируем помехи АЦП if (sample < 5 && sample > -5) { sample = 0; } // сохраняем действительные значения в четные отсчеты fft_input[i++] = sample; // задаем нечетным отсчетам значение «0» fft_input[i] = 0; } // функция-окно, повышающая частотное разрешение fft_window(); // реорганизовываем данные перед запуском FFT fft_reorder(); // обрабатываем данные в FFT fft_run(); // извлекаем данные, обработанные FFT fft_mag_log(); // выводим значения преобразования Фурье // Serial.print("<"); // Serial.print(FFT_N / 2); // Serial.print(":"); int max = 1; int curr = 0; for (int curBin = 0; curBin < FFT_N / 2; ++curBin) { if (curBin > 0) { //Serial.print(","); } if (fft_log_out[curBin] > max) { max = fft_log_out[curBin]; curr = curBin; } // Serial.print(fft_log_out[curBin]); } // Serial.println(">"); if (millis() - previousMillis > 800) { Serial.println(curr*35.7142); } }
Микрофон использую Sound Detection Sensor KY-037 и ардуино НАНО(328). Частоты выше 100 герц-находит почти замечательно(погрешность +-10 герц, нужно доделать усреднение просто, примен на 1000 герцах показывает 989,1002,1012,995 и т д.)
но вот ниже-не меряет частоту
проблема не в мирофоне!
отображал синусоиду на график на компе, с помощью SerialPortPlotter. Микрофон понимает до 40 герц.
из кода, Serial.println(curr*35.7142); константа 35,7142 была найдена експерементальным путем, и умножая curr на нее, можно находить частоту.
помогите советом, как переделать даный код, что бы он наоборот начал понимать низкие частоты, а средние-и верхние-нет.
сделал ошибку в коде,
4 строчка правильная:
#define FFT_N 256
В общем-то, и 40 Гц для этого микрофона - это уже довольно удивительно.
https://www.google.com/search?q=частотная+характеристика+электретного+микрофона&newwindow=1&source=lnms&tbm=isch&sa=X
пробывал пускать синусоду через схему на лм258
сигнал навыходе синусоида со смещеним 0 на +2,5в
по сути тот же сигнал что и с микрофона
но все равно ниже 40 герцов не меряет
Возможно две проблемы, первая - вы не правильно цифруете вход, нужно синхронное сэмплирование. Если просто аналогРеад в лупе то будет джиттер, и он как раз на низких частотах проявляется сильнее всего. Перепишите код для запуска АЦП от таймера 1 канал Б.
Тут пример для меги2560, вкладка АЦП.
Вторая причина в самом коде БПФ, но до устранения проблемы 1 это подтвердить нельзя.
Спасибо, будем изучать
да, сейчас в кода аналогРеад
int
sample = analogRead(MIC_PIN) - 511;
//153
это актуально для встроенного ацп
а если буду использовать внешний ацп?
это актуально для встроенного ацп
а если буду использовать внешний ацп?
Мне вот пришли MCP3002/3202/3304, неплохие ацп-эшки, но пришлось напрягать мозги пока я смог их в синхрон загнать. А так ЕНОБ никак не мерялся. Даже SPI не вариант, эта шина тоже без синхронизации старт-стоп.
ну я использовал ads1115 и есть еще такой же в наличии, он і2с
просто в любом случаи нужно будет внешний ацп, встроенного от ардуино будет мало...
ну я использовал ads1115 и есть еще такой же в наличии, он і2с
просто в любом случаи нужно будет внешний ацп, встроенного от ардуино будет мало...
У меня сложилось впечатление, что у ардуино и других микро-цпу всё пропорционально грамотно подобрано. А именно АЦП->размер памяти->частота процессора. Там очень редко требуется другой АЦП - > тогда проц и считать не успевает, и округляет на 8-битах так что ацп-10 ему как раз. Тем более если ацп исползуется для БПФ
мало для точности, решил использовать внешний цпу, так как там больше бит, соответсвенно можно будет изерить с десятіми, и сотыми. нужно в дальнейшем мерить не только частоту(для частоты достаточно и и родного ацп), а мощность подаваемого сиграла, вот тут нужно будет несколько знаков после запятой,а встроенный АЦП такого не может позволить....
Биты для точности не очень нужны. Почитайте теорию БПФ. Для разрешения низких частот нужно что бы длина выборки была больше периода оцифровки. Тут всё завязано. Количество точек выборки. Частота оцифровки. Всё влияет на разрешение по частоте. При чем при расчёте БПФ подпрограммам нужны буферы для хранения промежуточных результатов. Плохо себе представляю как это всё можно засунуть внутрь ардуины, что бы получить приемлемое разрешение по частоте. Особенно на нижних частотах, где время оцифровки должно быть около секунды. Только в этом случае в результате расчётов будут получаться низкие частоты.
ацп нужен для большей точности замера мощности сигнала
для частоты сигнала-можно и встроенный АЦП ардуино
тут я так понимаю на нано и на про мини не сделать
нужно брать полноценную 2560....