Анализатор спектра звука

Для данного проекта потребуется LOL Shield. Приобрести его можно в Sparkfun, но можно сделать и самому. Печатная плата и схема в свободном доступе лежит здесь. LOLShield представляет из себя светодиодную матрицу размерностью 14 x 9, сделанную как шилд к Arduino. В LOL Shield применяется довольно оригинальный метод управления светодиодами, так называемый Charlieplexing. Данный шилд был разработан Джимми Роджерсом.

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

Итак, мы купили или собрали LOL Shield, далее припаиваем 3.5мм мини джэк (или другой разьем, который нужен вам для вашей аудиосистемы)

В LOL шилде свободны 2 пина: это аналоговые 4 и 5. Для входа аудиосигнала я использовал 5-ый пин. Общий от миниджека подключаем к пину GND.

Программная часть

Для скетча нам потребуется 2 библиотеки:
библиотека FFT
библиотека Charlieplexing для LoL шилда

Алгоритм FFT разбивает звуковой диапазон на 64 частотных диапазона. Но наш LOL Shield содержит матрицу 14 x 9 LED. Потому нам надо вывести среднее и переназначить 64 частотных диапазона в 14 (проще говоря сделать remap). Уровень мы также приводим к диапазону от 0 до 9.

Код программы:

/*
FFT for LoL Shield v0.9
by Andy Doro
http://andydoro.com/

based on FFT library and code from the Arduino forums and
the Charlieplexing library for the LoL Shield.
*/

#include Charliplexing.h
#include fix_fft.h

#define AUDIOPIN 5 // Аудиовход

char im[128], data[128];
char data_avgs[14];
int i=0,val;

void setup() {
LedSign::Init(); //Инициализация LoL Shield
}

void loop() {

for (i=0; i < 128; i++){
val = analogRead(AUDIOPIN);
data[i] = val;
im[i] = 0;
};

fix_fft(data,im,7,0);

for (i=0; i< 64;i++){
data[i] = sqrt(data[i] * data[i] + im[i] * im[i]); // this gets the absolute value of the values in the array, so we’re only dealing with positive numbers
};

// average bars together
for (i=0; i<14; i++) {
data_avgs[i] = data[i*4] + data[i*4 + 1] + data[i*4 + 2] + data[i*4 + 3]; // вычисляем среднее
data_avgs[i] = map(data_avgs[i], 0, 30, 0, 9); // делаем remap для LoL
}

// set LoLShield

for (int x=0; x < 14; x++) {
for (int y=0; y < 9; y++) {
if (y < data_avgs[13-x]) { // 13-x reverses the bars so low to high frequences are represented from left to right.
LedSign::Set(x,y,1); // включаем LED
} else {
LedSign::Set(x,y,0); // выключаем LED
}
}
}
}

Видео работы

Скетч, библиотеки и Eagle-файл PCB вы можете скачать внизу

Оригинал статьи

Прикрепленные файлы:

Добавить комментарий

Ваш адрес email не будет опубликован.