Главная » Arduino
Призовой фонд
на июль 2019 г.
1. 1000 руб
Паяльник
2. Регулируемый паяльник 60 Вт
Паяльник
3. 100 руб.
От пользователей

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

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

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

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

Теги:

Колтыков А.В. Опубликована: 2012 г. 0 0
Я собрал 0 0
x

Оценить статью

  • Техническая грамотность
  • Актуальность материала
  • Изложение материала
  • Полезность устройства
  • Повторяемость устройства
  • Орфография
0

Средний балл статьи: 0 Проголосовало: 0 чел.

Комментарии (6) | Я собрал (0) | Подписаться

0
Nim #
Вопрос по коду:
val = analogRead(AUDIOPIN);
разве даёт частоту сигнала, а не его уровень (громкость) в конкретный момент снятия показаний? То есть матрица LED по-просту рисует дискретный уровень сигнала взятый в 128-и точках времени, а не его частотное разложение?
Ответить
0
Василий #
По идее, преобразование Фурье как раз решает эту задачу - на вход получает 128 последовательных уровней сигнала, на выход - массив из 64 значений, каждое из которых подразумевает множитель для своей частоты.
Это делается, судя по всему, тут
fix_fft(data,im,7,0);
Только непонятно, вот это зачем?
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
Я так понимаю, далее достаточно умножить массив im[] на константу (при наличии отрицательных чисел - взять по модулю)
Ответить
0
AN-Misha #
А как сделать, чтобы мельтешило помедленней? А то уж больно резко.
Ответить
0
Алексей #
По идее это не рабочая штуковина. Посмотрел видео, и как-то слишком много там низких частот на анализаторе, хотя в песне их не слышно. Кто-то реально собирал эту схему? Корректно работает?
Ответить
+1
Зокир #
Я собирал на МК такие штучки, честно получилось полная лажа, столбики прыгают как кузнечики. А вот аналоговый получился идеально. Каждый фильтр настраиваешь генератором и осцилом как надо и получаешь идеальный или почти идеальный результат.
https://youtu.be/keCJKKUaBrk
https://youtu.be/xJ1NpfPlric
Ответить
0
Maxim #
Здравствуйте! Как изменить диапазон частот, которые раскладываются в спектр? Сейчас, насколько я понял, диапазон 0..500Гц, раскладывается на 64 гармоники, т.е. гармоники с шагом 500/64 = 7,8125Гц. Как изменить диапазон на 0..250Гц или на 0..1000Гц, где в библиотеке расчитывается или указывается диапазон частот?
Ответить
Добавить комментарий
Имя:
E-mail:
не публикуется
Текст:
Защита от спама:
В чем измеряется электрическая мощность?
Файлы:
 
Для выбора нескольких файлов использйте CTRL

Arduino UNO
Arduino UNO
Паяльная станция Hakko 936 Тестер ESR, полупроводников, резисторов, индуктивностей
вверх