Эквалайзер на светодиодах.
- Войдите на сайт для отправки комментариев
Чт, 25/07/2013 - 18:34
Всем привет! Название темы наверняка поятное всем. Однако, вопрос у меня возник в неожиданном месте. А именно - как из библиотеки FFT добывать данные.
У меня собрана матрица из светодиодов, 6*6штук. В скетче на данный момент только алгоритм вывода на светодиоды из массива. Как теперь сделать, чтобы столбики массива заполнялись по частотам?
Или может быть есть другие вариаты такого эквалайзера?
#include <fix_fft.h>
#define AUDIOPIN 0
char im[128], data[128];
char data_avgs[6];
int i=0,val;
const int row[6]={2,3,4,5,6,7};//строки
const int col[18]={8,9,10,11,12,13};//столбцы
int v=100; //скорость прокрутки
int dms=200; //время свечения точки
boolean A[6][6] = //собственно массив
{1,1,1,1,1,1,// массив для эквалайзера
1,0,0,0,1,1,
1,0,1,0,1,1,
1,0,1,0,1,1,
1,0,0,0,1,1,
1,1,1,1,1,1,
};
void setup()
{
for (int i=0; i<6; i++)
{
pinMode(row[i],OUTPUT);
pinMode(col[i],OUTPUT);
}
for (int i=0; i<6; i++)
{
digitalWrite(row[i],HIGH);
}
}
void loop()
{
for (i=0; i < 128; i++){
val = analogRead(0);
im[i] = 0;
};
paint(A, v);
}
void paint(boolean screen[6][6], int v) //вывод на светодиоды
{
int i, j;
for (int c=0; c <v; c ++)
{
for (i=0; i<6; i++)
for (j=0; j<6; j++)
{
if (screen[i][j]==1)
{
digitalWrite(row[i], LOW);
digitalWrite(col[j], HIGH);
delayMicroseconds(dms);
digitalWrite(row[i], HIGH);
digitalWrite(col[j], LOW);
}
else
{
digitalWrite(row[i], HIGH);
digitalWrite(col[j], LOW);
delayMicroseconds(dms);
digitalWrite(row[i], HIGH);
digitalWrite(col[j], LOW);
}
}
}
}
Товарищи, сегодня испытвал библиотеку FFT с LOL шилдом и обнаружил несоответсвие разложения спектра. Стандартный пример анализатора спектра показывает полную фигню. Особенно хорошо видно если подавать точные частоты с генератора.
Кто ни будь работал вообще с библиотекой FFT?
Библиотека FFT, Атмега328, телевизор и точные частоты с генератора:
500HZ
1000Hz
2000Hz
3000Hz
4000Hz
5000Hz
6000Hz
7000Hz
8000Hz
9000Hz
10000Hz
11000Hz
ну и так далее...
То же самое происходит и с LOL шилдом и вообще во всех скетчах на эту тему, котрые мне удалось найти. До 4000Hz частоты определяются правильно а дальше полный шлак.
Есть у кого мысли, почему так происходит? Процессора не хватает или чего?
Сегодня подключил осциллограф прямо на ножку Ардуины, чтобы точно убедится, что подаю правильный сигнал. Итог - осцилл с функцией ФФТ абсолютно правильно определил все частоты с генератора, а Ардуина по прежнему отображает полную фигню.
Таким образом получается, что примеры представленые по этим ссылкам:
http://arduino.ru/projects/analizator-spektra-zvuka-na-arduino
http://pole.dyndns.info/?p=1260
http://mk90.blogspot.ru/2011/05/arduino-lol-shield.html
работают неправильно. То есть, с первого взгляда это можно и не заметить, но на самом деле частоты определяются в разнобой.
Вот пишу и думаю, неужели это никому не интересно, или это никто не проверял???
Вот пишу и думаю, неужели это никому не интересно, или это никто не проверял???
Мало у кого этот лолшилд есть, поэтому и отмалчиваются.
Ты пиши, пиши=)
Товарищи, тут не в ЛОЛ шилде дело. Выводить сигнал можно хоть куда - LCD дисплей, телевизор, светодиоды, шилды всякие, просто в память записывать.... Вопрос в самой библиотеке ФФТ. По неизвестным мне причинам она работает неправильно... И, что интересно, я так и не нашёл в инете рабочих примеров с этой библиотекой)))
Теперь обязательно нужно разобратся! Наверняка дело в какой ни будь переменной, которая сбивает правильную раскладку спектра. Одна единственная цифра, я думаю. Если б эта библиотека совсем не работала, давно бы уже обнаружили.
Товарищи, предлагайте свои варианты решении. Я попробую.
Я конечно по данной теме ни чего конкретного добавить не могу, но вот мне интересно:
А зачем Вам вот эта часть
39for(i=0; i < 128; i++){40val = analogRead(0);41im[i] = 0;42};если Вы этим ни где не пользуетесь?
Или это к данной проблеме ни как не относится?
Эти строки нужны для работы библиотеки собственно с входом. Опрашивается вход и данные отправляются в массив.
Мало того, что FFT работает неправильно, так теперь запретили про ЭТО даже читать! Сразу несколько закладок в которых я находил информацию про ФФТ забанили.
http://www.arduinoos.com/?p=1022
Ну как так то??? Совсем мозгов у них нету что ли...
А по теме обнаружил неожиданную вещь: в описании библиотеки точно помню, было указана работа только с Атмега328, т.к. у 168 памяти не хватает. Я сейчас нарочно проверил, 168ая работает точно также со всеми примерами кроме входа на телевизор.
Сам сайт не работал, я позже вам поправленную FFT выложу на dropbox, до компа доберусь только.
Omega13, серьёзно??? То есть у вас есть рабочая библиотека? А я уждумал, что никто не разбирался с ней.
С нетерпением жду)
https://dl.dropboxusercontent.com/u/49905397/FTT%20%281%29.tar.gz
Библиотеку правил pycckuumegbegb@gmail.com
И пример кода
#include <fix_fft.h> /* AnalogReadSerial Reads an analog input on pin 0, prints the result to the serial monitor This example code is in the public domain. */ int sensorValue = 0; int sensorValue2 = 0; int sensorValue4 = 0; char im[128]; char data[128]; int i=0; int j=0; void setup() { Serial.begin(9600); pinMode(2, OUTPUT); pinMode(3, OUTPUT); pinMode(4, OUTPUT); pinMode(5, OUTPUT); pinMode(6, OUTPUT); pinMode(7, OUTPUT); pinMode(8, OUTPUT); pinMode(9, OUTPUT); digitalWrite(2, LOW); digitalWrite(4, LOW); digitalWrite(7, LOW); digitalWrite(8, LOW); // pinMode(A3, OUTPUT); // digitalWrite(A3, HIGH); } void loop() { /* sensorValue = analogRead(A2); if(sensorValue != 1023) Serial.println(sensorValue); */ for (i=0; i < 128; i++){ // We don't go for clean timing here, it's data[i] = analogRead(A2); // Serial.print(data[i], HEX); // Serial.print(' '); // better to get somewhat dirty data fast im[i] = 0; // but too slow, for this application. }; // Serial.println(); fix_fft(data,im,7,0); for (i=0; i< 64;i++){ // Serial.print(data[i], HEX); // Serial.print(":"); // Serial.print(im[i], HEX); // Serial.print(" "); data[i] = sqrt(data[i] * data[i] + im[i] * im[i]); data[i] = map(data[i], 0, 30, 0, 32); // Serial.print(data[i], HEX); // Serial.print(' '); }; // Serial.println(); analogWrite(3, data[0] + data[1] + data[2] + data[3] + data[4]+ data[5] + data[6] + data[7] + data[8] + data[9] +data[10] + data[11] + data[12] + data[13] + data[14] + data[15]); analogWrite(5, data[16] + data[17] + data[18] + data[19] + data[20]+ data[21] + data[22] + data[23] + data[24] + data[25] +data[26] + data[27] + data[28] + data[29] + data[30] + data[31]); analogWrite(6, data[32] + data[33] + data[34] + data[35] + data[36]+ data[37] + data[38] + data[39] + data[40] + data[41] +data[42] + data[43] + data[44] + data[45] + data[46] + data[47]); analogWrite(9, data[48] + data[49] + data[50] + data[51] + data[52]+ data[53] + data[54] + data[55] + data[56] + data[57] +data[58] + data[59] + data[60] + data[61] + data[62] + data[63]); }Omega13, не хочу никого расстраивать, но дорабоатанная библиотека также неправильно разделяет частоты. Попробовал по разному подключать, частоты определяются вразнобой. Если просто выводим результат в сериал и подаём точные частоты, сразу заметно несоответствие.
Таким образом, вопрос по прежнему открыт.
я тоже думал, что в разнабой...
но видна закономерность, если подавать с 0 до 20кГц, то сначала с 0 до 4кГц - слева на право, потом возвращается в обратном порядке в диапазоне 5-7кГц, и снова слева на право от 8-16кГц. Так-что закономерность есть.
Я думаю дело в несоответствии шкал fft и той что реально отображает массив.
Когда-то вручную считал спектр, перемножал матрицы.... ну и намучались тогда )
Конечно возможно просто,что создатели библиотеки хомутнули что-то:
Written by: Tom Roberts 11/8/89
Made portable: Malcolm Slaney 12/15/94 malcolm@interval.com
пс Проверял на Лоле, сам спаял (на полпути -пожалел, не повторяйте эту ошибку), лучше купить готовый или набор..
https://dl.dropboxusercontent.com/u/49905397/FTT%20%281%29.tar.gz
Библиотеку правил pycckuumegbegb@gmail.com
там правки по сути никакой нет, просто изменено под новую версию компилятора
#include <Arduino.h> //было #include <WProgram.h>
я не программист, но 20сек гугление помогло без этих "правок".
явная ошибка в fix_fft.h и тут нужен инженер радиоэлектроннщик, программист и математик в одном лице.
Как-то не реально звучит, так-что по этому и глухо на форуме. ИМХО
есть ваиант без ардуино )))
http://radiokot.ru/circuit/audio/other/40/
есть ваиант без ардуино )))
ну сдрасте, технике прошлого века -бой
а если серьезно, то делал когда-то 5-ти полосный спектроанализатор, встраивал в самодельный усилитель.
это громоздко и вообще не по теме.
а теперь по теме:
Проблема - решена. А была она зарыта в банальном алиасинге.
И нужно было увеличить частоту семплирования.
Теперь проблема ушла и отображение вполне нормальное.
Вывод однозначный ошибки в реализации БПФ нет, так что дерзайте, все работает.
roos, что правда, всё заработало?? Можете подробней расссказать про частоту сеемплирования. В каком месте скетча нужно поменять. Ведь это не в самой библиотеке?
roos, что правда, всё заработало?? Можете подробней расссказать про частоту сеемплирования. В каком месте скетча нужно поменять. Ведь это не в самой библиотеке?
в воид сетапе вставь это:
ADCSRA = (1<<ADEN)|(1<<ADPS0)|(0<<ADPS1)|(1<<ADPS2); // sps=500k ~f=10k
это всё
В скором времени попробую эту корректировку. Вот только ЛОЛ шилд найду)
Провел испытания, действительно, теперь работает правильно!!! Правда, проверял только до 10кгц.
Привет, Форумчане!
Воспользовался вашей подсказкой ADCSRA = (1<<ADEN)|(1<<ADPS0)|(0<<ADPS1)|(1<<ADPS2); // sps=500k ~f=10k. Спасибо!
Сигнал подавал с генератора частоты. На частотах меньше 150 Гц, начинаются помехи от ардуины, её отключаешь на осцилографе получается нормальный сигнал
Как переписать скетч, чтобы получилась цветомузыка из 4 светодиодов, но работало правильное разделение частот?