Эквалайзер на светодиодах.

Vitaly
Offline
Зарегистрирован: 12.09.2011

Всем привет! Название темы наверняка поятное всем. Однако, вопрос у меня возник в неожиданном месте. А именно - как из библиотеки 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);
            } 
        } 
    }
}

 

Vitaly
Offline
Зарегистрирован: 12.09.2011

Товарищи, сегодня испытвал библиотеку FFT с LOL шилдом и обнаружил несоответсвие разложения спектра. Стандартный пример анализатора спектра показывает полную фигню. Особенно хорошо видно если подавать точные частоты с генератора.

Кто ни будь работал вообще с библиотекой FFT? 

Vitaly
Offline
Зарегистрирован: 12.09.2011

Библиотека FFT, Атмега328, телевизор и точные частоты с генератора:

500HZ

 

1000Hz

 

2000Hz

 

3000Hz

4000Hz

 

5000Hz

 

6000Hz

 

7000Hz

 

8000Hz

 

9000Hz

 

10000Hz

11000Hz

ну и так далее...

То же самое происходит и с LOL шилдом и вообще во всех скетчах на эту тему, котрые мне удалось найти. До 4000Hz частоты определяются правильно а дальше полный шлак. 

Есть у кого мысли, почему так происходит? Процессора не хватает или чего?

 

Vitaly
Offline
Зарегистрирован: 12.09.2011

Сегодня подключил осциллограф прямо на ножку Ардуины, чтобы точно убедится, что подаю правильный сигнал. Итог - осцилл с функцией ФФТ абсолютно правильно определил все частоты с генератора, а Ардуина по прежнему отображает полную фигню.

Таким образом получается, что примеры представленые по этим ссылкам:

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

работают неправильно. То есть,  с первого взгляда это можно и не заметить, но на самом деле частоты определяются в разнобой.

Вот пишу и думаю, неужели это никому не интересно, или это никто не проверял???

Клапауций
Offline
Зарегистрирован: 10.02.2013

Vitaly пишет:

Вот пишу и думаю, неужели это никому не интересно, или это никто не проверял???

Мало у кого этот лолшилд есть, поэтому и отмалчиваются.

Апрайсин
Апрайсин аватар
Offline
Зарегистрирован: 05.08.2013

Ты пиши, пиши=) 

Vitaly
Offline
Зарегистрирован: 12.09.2011

Товарищи, тут не в ЛОЛ шилде дело. Выводить сигнал можно хоть куда  - LCD дисплей, телевизор, светодиоды, шилды всякие, просто в память записывать.... Вопрос в самой библиотеке ФФТ. По неизвестным мне причинам  она работает неправильно... И, что интересно, я так и не нашёл в инете рабочих примеров  с этой библиотекой)))

Теперь обязательно нужно разобратся! Наверняка дело в какой ни будь переменной, которая сбивает правильную раскладку спектра. Одна единственная цифра, я думаю. Если б  эта библиотека совсем не работала, давно бы уже обнаружили.

Товарищи, предлагайте свои варианты решении. Я попробую.

ich
Offline
Зарегистрирован: 10.06.2012

Я конечно по данной теме ни чего конкретного добавить не могу, но вот мне интересно:

А зачем Вам вот эта часть

39 for (i=0; i < 128; i++){                                    
40       val = analogRead(0);                                    
41       im[i] = 0;                                                 
42 };
   

если Вы этим ни где не пользуетесь?

Или это к данной проблеме ни как не относится?

Vitaly
Offline
Зарегистрирован: 12.09.2011

Эти строки нужны для работы библиотеки собственно с входом. Опрашивается вход и данные отправляются в массив.

 

Vitaly
Offline
Зарегистрирован: 12.09.2011

Мало того, что FFT работает  неправильно, так теперь запретили про ЭТО даже читать! Сразу несколько закладок в которых я находил информацию про ФФТ забанили. 

 http://www.arduinoos.com/?p=1022

Ну как так то??? Совсем мозгов у них нету что ли...

 

А по теме обнаружил неожиданную вещь: в описании библиотеки точно помню, было указана работа только с Атмега328, т.к. у 168 памяти не хватает. Я сейчас нарочно проверил, 168ая работает точно также со всеми примерами кроме входа на телевизор. 

Omega13
Offline
Зарегистрирован: 01.07.2013

Сам сайт не работал, я позже вам поправленную FFT выложу на dropbox, до компа доберусь только.

Vitaly
Offline
Зарегистрирован: 12.09.2011

Omega13, серьёзно??? То есть у вас есть рабочая библиотека? А я уждумал, что никто не разбирался с ней.

С нетерпением жду)

Omega13
Offline
Зарегистрирован: 01.07.2013

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]);
  
  
  
  
  
  
}

 

Vitaly
Offline
Зарегистрирован: 12.09.2011

Omega13, не хочу никого расстраивать, но дорабоатанная библиотека также неправильно разделяет частоты. Попробовал по разному подключать, частоты определяются вразнобой. Если просто выводим результат в сериал и подаём точные частоты, сразу заметно несоответствие.

Таким образом, вопрос по прежнему открыт.

roos
Offline
Зарегистрирован: 10.02.2014

я тоже думал, что в разнабой...

но видна закономерность, если подавать с 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

Enhanced:  Dimitrios P. Bouras  14 Jun 2006 dbouras@ieee.org
 
Modified for 8bit values David Keller  10.10.2010

пс Проверял на Лоле, сам спаял (на полпути -пожалел, не повторяйте эту ошибку), лучше купить готовый или набор..

roos
Offline
Зарегистрирован: 10.02.2014

там правки по сути никакой нет, просто изменено под новую версию компилятора

#include <Arduino.h> //было #include <WProgram.h>

я не программист, но 20сек гугление помогло без этих "правок".

явная ошибка в fix_fft.h и тут нужен инженер радиоэлектроннщик, программист и математик в одном лице.

Как-то не реально звучит, так-что по этому и глухо на форуме. ИМХО

axill
Offline
Зарегистрирован: 05.09.2011

есть ваиант без ардуино )))

http://radiokot.ru/circuit/audio/other/40/

roos
Offline
Зарегистрирован: 10.02.2014

axill пишет:

есть ваиант без ардуино )))

ну сдрасте, технике прошлого века -бой

а если серьезно, то делал когда-то 5-ти полосный спектроанализатор, встраивал в самодельный усилитель.

это громоздко и вообще не по теме.

а теперь по теме:

Проблема - решена. А была она зарыта в банальном алиасинге.

И нужно было увеличить частоту семплирования.

Теперь проблема ушла и отображение вполне нормальное.

Вывод однозначный ошибки в реализации БПФ нет, так что дерзайте, все работает.

Vitaly
Offline
Зарегистрирован: 12.09.2011

roos, что правда, всё заработало?? Можете подробней расссказать про частоту сеемплирования. В каком месте скетча нужно поменять. Ведь это не в самой библиотеке?

roos
Offline
Зарегистрирован: 10.02.2014

Vitaly пишет:

roos, что правда, всё заработало?? Можете подробней расссказать про частоту сеемплирования. В каком месте скетча нужно поменять. Ведь это не в самой библиотеке?

в воид сетапе вставь это:

   ADCSRA = (1<<ADEN)|(1<<ADPS0)|(0<<ADPS1)|(1<<ADPS2); // sps=500k ~f=10k

это всё

Vitaly
Offline
Зарегистрирован: 12.09.2011

В скором времени попробую эту корректировку. Вот только ЛОЛ шилд найду)

 

Vitaly
Offline
Зарегистрирован: 12.09.2011

Провел испытания, действительно, теперь работает правильно!!!  Правда, проверял только до 10кгц.

 

arte-marty
Offline
Зарегистрирован: 23.01.2014

Привет, Форумчане!

Воспользовался вашей подсказкой  ADCSRA = (1<<ADEN)|(1<<ADPS0)|(0<<ADPS1)|(1<<ADPS2); // sps=500k ~f=10k. Спасибо!

Сигнал подавал с генератора частоты. На частотах меньше 150 Гц, начинаются помехи от ардуины, её отключаешь на осцилографе получается нормальный сигнал

RomulRS
Offline
Зарегистрирован: 21.02.2016

Как переписать скетч, чтобы получилась цветомузыка из 4 светодиодов, но работало правильное разделение частот?