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

Для цього проекту знадобиться 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 перевертає стовпці, щоб низькі частоти відображалися зліва направо.
      LedSign::Set(x,y,1);        // вмикаємо LED
     } else {
       LedSign::Set(x,y,0);       // вимикаємо LED
     }
   } 
  }
}

Відео роботи

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

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

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