audiospectrumledgrid

A PCB and Software to convert an audio mono signal into a grid made of LEDs.
git clone git://archive.git.mtrnord.blog/MTRNord/audiospectrumledgrid.git
Log | Files | Refs | README | LICENSE

SpectrumAnalyzer.ino (4525B)


      1 /*
      2 Written by FischiMc and SupaStefe
      3 
      4 This sketch uses a 10x10 RGB LED-Matrix as a spectrum analyzer
      5 It uses a FTT Library to analyze an audio signal connected to the
      6 pin A7 of an Arduino nano. Everytime a column gets higher than
      7 10 pixels the color of each column changes.
      8 */
      9 
     10 #define LOG_OUT 0         //set output of FFT library to linear not logarithmical
     11 #define LIN_OUT 1
     12 #define FFT_N 256         //set to 256 point fft
     13 
     14 #include <FFT.h>          //include the FFT library
     15 #include <FastLED.h>      //include the FastLED Library
     16 #include <math.h>         //include library for mathematic funcions
     17 #define DATA_PIN 3        //DATA PIN WHERE YOUR LEDS ARE CONNECTED
     18 #define NUM_LEDS 100      //amount of LEDs in your matrix
     19 CRGB leds[NUM_LEDS];
     20 float faktoren[10] = {1, 1.1, 1.15, 1.25, 1.45, 1.55, 1.75, 1.8, 2, 3};       //factors to increase the height of each column
     21 unsigned char hs[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};                        //height of each column
     22 float hue = 0;                                                                //hue value of the colors
     23 
     24 void setBalken(unsigned char column, unsigned char height){                   //calculation of the height of each column
     25     unsigned char h = (unsigned char)map(height, 0, 255, 0, 10);
     26     h = (unsigned char)(h * faktoren[column]);
     27     if (h < hs[column]){
     28         hs[column]--;
     29     }
     30     else if (h > hs[column]){
     31         hs[column] = h;
     32     }
     33    if (height > 250){
     34       hue+=2;                     //CHANGE THIS VALUE IF YOU WANT THE DIFFERENCE BETWEEN THE COLORS TO BE BIGGER
     35       if(hue > 25) hue=0;
     36    }
     37 
     38     for(unsigned char y = 0; y < 10; y++){                          //set colors of pixels according to column and hue
     39        if(hs[column] > y){ 
     40         leds[y+(column*10)] = CHSV((hue*10)+(column*10), 255, 200);
     41        } else {
     42         leds[y+(column*10)] = CRGB::Black;
     43        }
     44     }
     45 }
     46 
     47 unsigned char grenzen[11] = {0,3,5,7,9,11,13,16,24,32,69};          //borders of the frequency areas
     48 
     49 void setup() {
     50   FastLED.addLeds<WS2812B, DATA_PIN, GRB> (leds, NUM_LEDS);
     51   Serial.begin(115200);                                             //use the serial port
     52   TIMSK0 = 0;                                                       //turn off timer0 for lower jitter
     53   ADCSRA = 0xe5;                                                    //set the adc to free running mode
     54   ADMUX = 0b01000111;                                               //use pin A7
     55   DIDR0 = 0x01;                                                     //turn off the digital input for 
     56   analogReference(EXTERNAL);                                        //set aref to external
     57 }
     58 
     59 void loop() {
     60   while(1) {                                                        //reduces jitter
     61     cli();                                                          //UDRE interrupt slows this way down on arduino1.0
     62     for (int i = 0 ; i < 512 ; i += 2) {                            //save 256 samples
     63       while(!(ADCSRA & 0x10));                                      //wait for adc to be ready
     64       ADCSRA = 0xf5;                                                //restart adc
     65       byte m = ADCL;                                                //fetch adc data
     66       byte j = ADCH;
     67       int k = (j << 8) | m;                                         //form into an int
     68       k -= 0x0200;                                                  //form into a signed int
     69       k <<= 6;                                                      //form into a 16b signed int
     70       fft_input[i] = k;                                             //put real data into even bins
     71     }
     72 
     73     fft_window();                                                   // window the data for better frequency response
     74     fft_reorder();                                                  // reorder the data before doing the fft
     75     fft_run();                                                      // process the data in the fft
     76     fft_mag_lin();                                                  // take the output of the fft
     77     sei();
     78 
     79     fft_lin_out[0] = 0;
     80     fft_lin_out[1] = 0;
     81 
     82     for(unsigned char i = 0; i < 11; i++){
     83       unsigned char maxW = 0;
     84         for(unsigned char x = grenzen[i]; x < grenzen[i+1];x++){
     85  
     86            if((unsigned char)fft_lin_out[x] > maxW){
     87             maxW = (unsigned char)fft_lin_out[x];
     88            }
     89         }
     90 
     91       setBalken(i, maxW);
     92       Serial.print(maxW);
     93       Serial.print(" ");
     94     }
     95     Serial.println("");
     96     TIMSK0 = 1;
     97     FastLED.show();
     98     TIMSK0 = 0;
     99   }
    100 }