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

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

LOL Shield

Для анализа аудио-сигнала используется метод 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 вы можете скачать внизу