arduino uno , FFT-спектральный анализатор .
- Войдите на сайт для отправки комментариев
Вс, 02/04/2017 - 15:46
Добрый день .
Как реализовать вывод максимальных пиков частоты на промежутке от 20 до 120Гц , на lcd 16x02.
Сигнал будет подаваться на ацп .
Допустим играет музыка , раз максимальная амплитуда 77Гц потом второй пик 35Гц и так далее . Вот эти показания мне и надо в цифрах и выводить на lcd .
Если Вы хотите сделать это сами, то, судя по названию темы, мыслите в верном направлении. Осталось только выложить скетч и схему.
Если же хотите, чтобы кто-то сделал за Вас, то ошиблись разделом.
Может есть у кого библиотека fft ?
Может есть у кого библиотека fft ?
Библиотек по бпф для ардуино на просторах инете не мало .... другое дело, понять это и прикрутить конкретно к железу
В том то и дело что понять проблематично , возможно кто то разжуёт .
В том то и дело что понять проблематично , возможно кто то разжуёт .
Как только я сам пойму, я вам набросаю алгоритм .... а вообще, может попросить у самых умных на форуме, чтобы без заумных слов на пальцах объяснили ...
Пока я знаю только одно - с помощью ацп входной сигнал преобразуем в последовательность (двоичных) цифр ... затем над ней нужно поколдовать и на выходе мы получим другую последовательность цифр, которую нужно уже отобразить на индикаторе ... сейчас застрял на вопросах колдовства, вспоминаю, что есть комплексное число ... и ламповый синус удалось разложить в ряд фурье
Правильно рассуждаете. Берете либу БПФ. В ней написано по скольким точкам оно работает. Набираете нужное количество отсчетов в массив в массив и вызываете соответствующую функцию из либы. После выполнения получаете разложение входного сигнала по частотам в виде массива чисел. Оно как правило комплексное, берет корень квадратный от суммы квадратов мнимой и действительной части для каждой частоты. Это и будет амплитуда сигнала соответствующей частоты.
Дето так (насколько помню оно работало когдато).
01
#include <fix_fft.h>
02
#define AUDIOPIN A2
03
04
char
im[128], data[128];
05
int
i=0, val;
06
int
outlow = 0;
07
int
outmid = 0;
08
int
outhi = 0;
09
10
int
redPin = 5;
// pins that the LED are attached to
11
int
greenPin = 6;
12
int
bluePin = 3;
13
14
void
setup
() {
15
Serial
.begin(19200);
16
}
17
18
void
loop
() {
19
for
(i=0; i < 128; i++){
20
val = analogRead(AUDIOPIN);
21
delayMicroseconds(200);
22
data[i] = val/4 -128;
23
im[i] = 0;
24
}
25
26
fix_fft(data,im,7,0);
27
28
29
30
for
(i=0; i<10;i++)
31
{
32
Serial
.print((
byte
)(sqrt(data[i] * data[i]+im[i]*im[i])));
33
Serial
.print(
"\t"
);
34
35
}
36
Serial
.println();
37
38
}
ПС. Нафига оно вам нада, весна на улице, пивка лучше бахните.
ПС. Нафига оно вам нада, весна на улице, пивка лучше бахните.
ИДЕ ругается на библиотеку fft ... нет пока времени разбираться, нужно ардуин-метеостанцию доделать
Наверно на её отсутствие ругается.
Наверно на её отсутствие ругается.
:) Ценю ваш юмор ...
C:\Users\ulis\Documents\Arduino\libraries\FFT/fix_fft.h:6:22: fatal error: WProgram.h: No such file or directory
Инет рекомендует WProgram.h заменить на Arduino.h ... не помогает, замена дает еще целый букет ошибок
Открыл fix_fft.h, таки да WProgram.h инклудит. Но у меня не ругается с ИДЕ 1.0.6. Остерегайтесь слишком нового софта.
Вобще первое чего бы я сделал - как раз и заменил на Arduino.h.... А чего пишет то? Либке там вобще мало что надо..
ИДЕ конечно у меня почти самая последняя - 1.8.1 Если WProgram.h заменить на Arduino.h - имеем:
In file included from C:\Users\ulis\Documents\Arduino\libraries\FFT\fix_fft.cpp:1:0:
C:\Users\ulis\Documents\Arduino\libraries\FFT\fix_fft.cpp: In function 'int fix_fft(char*, char*, int, int)':
C:\Users\ulis\Documents\Arduino\libraries\FFT\fix_fft.cpp:199:37: error: 'Sinewave' was not declared in this scope
wr = pgm_read_word_near(Sinewave + j+N_WAVE/4);
^
C:\Users\ulis\Documents\Arduino\libraries\FFT\fix_fft.cpp:209:37: error: 'Sinewave' was not declared in this scope
wi = -pgm_read_word_near(Sinewave + j);
хммм.. а Sinewave как
const prog_int8_t Sinewave[N_WAVE-N_WAVE/4] PROGMEM = {
либо мутный тип prog_int8_t либо PROGMEM. Или указатель не может привести
Ну попробуйте
const uint8_t Sinewave[N_WAVE-N_WAVE/4] PROGMEM = {
или
const char Sinewave[N_WAVE-N_WAVE/4] PROGMEM = {
или без const (он итак PROGMEM)
а ведь действительно, что за тип prog_int8_t, заменил на uint8_t, компиляция прошла без ошибок ... спасибо, буду дальше разбираться ....
Поделитесь со мною чтоль библиотекой буду тоже мучать может совместными усилиями что нибудь и получиться .
Та ненадо никого мучить. Я тот скетч заливал, палец к выводу подносил и наблюдал разложение пальца в спектр )) С гармониками кратными 50Гц. А дальше уже творите чего знаете, но помните что все совсем не так просто как кажется. Все не идеально и чтоб получить что хочется прийдется думать и одним БПФ как правило не обходится.
но помните что все совсем не так просто как кажется
Мы знаем, что жизнь не так проста :)
Собрал простейшую схемку:
На вход подал сигнал со звуковой карты ... получил такую "картину"
Осталось понять, ну а вывод на подходящий экранчик - дело техники
но помните что все совсем не так просто как кажется
Мы знаем, что жизнь не так проста :)
Это Вам только кажется )) учитывая что сигнал со звуковой карты двуполярный, а вход АЦП - нет, то вы очень многого не знаете ;)
Это Вам только кажется )) учитывая что сигнал со звуковой карты двуполярный, а вход АЦП - нет, то вы очень многого не знаете ;)
:) Наверно, вы имеете в виду, что сигнал с карты имеет постоянную составляющую? Нет повода для волнения, все будет учтено в лучших традициях аналоговой техники
Это Вам только кажется )) учитывая что сигнал со звуковой карты двуполярный, а вход АЦП - нет, то вы очень многого не знаете ;)
:) Наверно, вы имеете в виду, что сигнал с карты имеет постоянную составляющую? Нет повода для волнения, все будет учтено в лучших традициях аналоговой техники
учитывая что сигнал со звуковой карты двуполярный, а вход АЦП - нет
Что вы имеете в виду? Относительно земли сигнал "гуляет" в плюс и минус или что-то еще? Мне никто не мешает податьсмещение на аналоговоый вход ардуины ... ладно, мне пора на горшок и спать :)
Никто не мешает подать, но подано небыло. Да оно нужно, иначе "гуляния в минус" не только будут не оцифрованы, но и искажены защитными диодами - ограничены, это приведет к смещению нуля в - (из за тех самых кондеров на выходе звуковухи) что скажется на оцифрованых значениях и результатах БПФ. Так что жизнь таки еще сложней )))
ПС. кстати этот эффект уже виден в результатах, элемент 0 в выходном массиве БПФ - это постоянная составляющая, она есть! А поидее с выхода звуковухи ей быть недолжно.
Вот библиотека, которая работает у меня на иде 1.8.1 (это для gmaxi)
https://yadi.sk/d/Li0lnTwM3Ghcvn
Спасибо большое за код
все отлично, но есть пару вопросов, как с помощью вашего скетча узнать текущую частоту?
как датчик переменного напряжения использую вот такую схему на ОУ http://redblot.ru/archives/406
у меня идет смещение нуля на 2,5 вольта, соответственно для анализа есть полная синусоида звука.
Спасибо большое за код
все отлично, но есть пару вопросов, как с помощью вашего скетча узнать текущую частоту?
как датчик переменного напряжения использую вот такую схему на ОУ http://redblot.ru/archives/406
у меня идет смещение нуля на 2,5 вольта, соответственно для анализа есть полная синусоида звука.
Т.е. я так понимаю, что вы на вход подаете не сложный сигнал, типа музычки, а чистую синусоиду?
да, для примера, вот 50 герц

Так тогда зачем вам вообще БПФ?
это отдельный софт, кторый просто считывает показания с аналогово пина.
для меня нужно знать такие звуковые параметры:
частоту в герцах
есть ли "клип"
и рисовать график в своем написаном софте....
это отдельный софт, кторый просто считывает показания с аналогово пина.
для меня нужно знать такие звуковые параметры:
частоту в герцах
есть ли "клип"
и рисовать график в своем написаном софте....
В таком случае, я вообще не понял, что вы хотите и причем здесь ваше ПО
мне нужно узанть частоту синусоиды с помощью ардуино
а по-уже буду писать дальше)
Узнать частоту - множество вариантов, особенно, если частота не высока. Например, померить длительность периода и взять обратную величину, даже оцифровывать не нужно. Посмотрите, например: http://arduino.ru/forum/programmirovanie/kak-schityvat-chastotu-posredstvom-arduino
частота от 10 до 200 герц
проблема в том, что на входе может быть частота и выше
входной сигнал-аудио звук, тоесть любая песня, от которой нужно отсеить низкие частоты, и измерять их
частота от 10 до 200 герц
проблема в том, что на входе может быть частота и выше
входной сигнал-аудио звук, тоесть любая песня, от которой нужно отсеить низкие частоты, и измерять их
Вы сами себе противоречите, в #25 вы пишите, что на входе чистая синусоида, теперь оказывается, что все таки - случайный сигнал. Тогда, конечно, вам нужно БПФ
тесты провожу на синусоидах
но в дальнейшем, нужно будет использовать и с аудио сигналом
аудиосигнал будет подаватся примерно таким образом
Ставьте на вход аналоговый фильтр нижних частот нечетного порядка (3 или 5), с частотой среза 200 Гц и уж потом с помощью дуни получайте спектр. Конкретную реализацию БПФ для вашего случая пока не знаю как реализовать .... может кто подскажет
фильтрация частот будет происходить на самом УНЧ, а вот с FFT сейчас разбираюсь
Узнать частоту по результату БПФ в общем то просто, он как раз выдает в каждом выходном коэффициенте величину сигнала на некоторой частоте, но дявол кроется в мелочах. А именно в точности. Ответ на вопрос квк узнать частоту - не буду излагать все, просто процитирую.
Самый первый элемент с индексом 0 показывает постоянную составляющую сигнала, то есть, насколько он в среднем "приподнят" над осью времени. Остальные элементы представляют гармоники видаA cos(2πνt + φ), где ν - это частота, которая для гармоники с индексом k будет равна:
ν = k / T
Часто бывает дано не суммарное время сигнала T, а частота дискретизации: сколько отсчетов приходится на одну секунду. Обозначим ее S. Тогда частота для гармоники с индексом k будет равна:
ν = S k / N
. Т.е. каждый коэффициент в результатах БПФ отвечает за наличие сигнала на некоторой частоте. Если входной сигнал дискретизирован с частотой 8000Гц и мы обработали по 128 отсчетам то первый коэффициент - уровень сигнала на частоте 8000*1/128, второй на частоте 8000*2/128 и т.д. Т.е. частоты уже получены, но...
Это очень важно понимать: FFT раскладывает функцию не на её гармоники, а насвои гармоники. Допустим, в исходной функции была лишь частота точно 100 Гц, а мы с помощью FFT раскладываем функцию в частоты 96, 99, 102, 105 Гц - как вы думаете, что получится в результате? :) ......... полученный нами спектральный состав будет бестолковым:
(амплитуда)
(амплитуда)
Как видно, удачный FFT, который полностью 'попал' в искомую частоту, дал хороший, правильный, с нашей точки зрения, спектр. Неудачный же - нехороший спектр. Мы можем только догадываться, что в исходном сигнале была сильная частота в примерно 100 Гц.
Сомнительную часть я заменил многоточием. Вот и видим уже проблему в определении частоты. А если вспомнить что в реальной жизни точное совпадение частот невозможно, то понятно что дело прийдется иметь только с неудачным БПФ, в той или иной степени выражености.
ПС. В сомнительной части, которую я не цитировал утверждалось о возможности восстановления по неудачному БПФ исходного сигнала. "полностью точно восстановить". Почему это сомнительно. Да потому что даже после дискретизации есть потеря информации и восстановление всего спектра невозможно, а по результатам БПФ еще и с конечной точностью - тем более. И хочется спросить, а что будет если на входе БПФ окажется не синус 100Гц, а сумма сигнала с частотами и амплитудами 91Гц и 0,04 + 93Гц и 0,11+ т.д. по таблице? Что восстановится из результатов разложения такого сигнала, 100Гц или сумма ;)?
Спасибо, за инфу ... осталось только выяснить, согласно желанию ТС, как задать параметры бииблиотеки, чтобы она раскладывала в свой спектр в диапазоне до 200 Гц?
Спасибо за инфу

но все равно не очень ясно)
на выходе после FFT имею матрици, к примеру:
вот частотат 40 герц:
вот 20 герц:

Визуально видно как меняется показания, и можно "угадать" какая частота, но как програмно вычислить?
https://www.arduino.cc/en/Tutorial/SimpleAudioFrequencyMeter
по топику еще, есть идеально подходящая мне библиотека, но она не работает с даной версией ардуно(
используется ардуино нано, с возмоностью подальшого переноса проэкта на stm32