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 }