Spectrum Analyzer - new to hardware -

Hello, I want to make a spectrum analyzer, perhaps similar in display to this http://www.youtube.com/watch?v=RzGGa_fXA2g but maybe with a higher number of bands(higher resolution?). I've seen the example on this forum that used the MSGEQ7, and if all else fails I'll probably just follow that project verbatim. The final project I am attempting to create is a equalizer t-shirt ( the the Arduino + power supply would housed in a case that would clip on to my pants)

Questions I have so far.

-What board should I get? ( is the Uno capable of running a realtime spectrum analyzer outputting to a display or should I get something like the Mega)

-LED or LCD?

-I am new to hardware in general, where should I start reading?

-I've been reading up on FFT a bit, but am still a ways off from understanding it completely, or how to apply it practically in C

Thank you for your time.

Start here for FTT information http://www.arduinoos.com/2010/10/fast-fourier-transform-fft/

I wouldn't worry about the display of the data just yet. Start with just getting the FFT to work and spitting it out over serial. Also note that most of the articles that you read will be dealing with static data. Your project is going to be working with real time data.

So you'll need to play around with how you are going to deal with that. Method One: -Fill array with completely new data -Perform FFT on array -repeat

Method Two: -Push one new data point into your array an pop off the oldest data point -Perform FFT on the array

Note that most FFT algorithms need a data set that is a power of 2 in size.

There is an arduino FFT lib, which will make it thousands of times easier: http://neuroelec.com/2011/03/fft-library-for-arduino/

If you are planning on clothing based stuff, check out the various lilypad modules once you are out of prototype stage. I believe there is an Arduino lilypad board as well as other modules. Don't know if it would work for you, but thought I would throw the option out there for you.

Ok, so I read that whole thing you sent me, laadams85. I understand it more so than I did, still not 100%, but I’ll reread it again. Also I got the library that you linked, Steen. In the example that was provided, it says the A0 pin receives the analog input but I dont see A0 defined anywhere or referenced in the code, unless thats what #define  IR_AUDIO  0 is, which im fairly certain it is ( I’m new to all this though, could easily be wrong). The way this example is set up, it appears to me to be doing the first method you mentioned laadams85, wherein it fills an array, performs the FFT, then gets the new array. It also appears to spit it out over serial. I guess next on the list is how to hook a microphone up. Could anyone point me in the right direction?

Oh and Sembazuru, I had looked at the lilypad, but i ended up just getting the mega 2560, I want to do other projects after this one, and I dont know how powerful the lilypad is in comparison.

Here is the example that came with the library that I have been referencing.

/*
This Example acquire analog signal from A0 of Arduino, and Serial out to Processing application to visualize.
Tested with preamplified audio data. Take a look at http://www.youtube.com/watch?v=drYWullBWcI

Analog signal is captured at 9.6 KHz, 64 spectrum bands each 150Hz which can be change from adcInit()
Load the this file to Arduio, run Processing application.

Original Fixed point FFT library is from ELM Chan, http://elm-chan.org/works/akilcd/report_e.html
A way to port it to the Arduino library and most demo codes are from AMurchick http://arduino.cc/forum/index.php/topic,37751.0.html
Processing app is based on codes from boolscott http://boolscott.wordpress.com/2010/02/04/arduino-processing-analogue-bar-graph-2/
*/


#include <stdint.h>
#include <ffft.h>


#define  IR_AUDIO  0 // ADC channel to capture


volatile  byte  position = 0;
volatile  long  zero = 0;

int16_t capture[FFT_N];			/* Wave captureing buffer */
complex_t bfly_buff[FFT_N];		/* FFT buffer */
uint16_t spektrum[FFT_N/2];		/* Spectrum output buffer */

void setup()
{
  Serial.begin(57600);
  adcInit();
  adcCalb();
  establishContact();  // send a byte to establish contact until Processing respon
}

void loop()
{
  if (position == FFT_N)
  {
    fft_input(capture, bfly_buff);
    fft_execute(bfly_buff);
    fft_output(bfly_buff, spektrum);

    for (byte i = 0; i < 64; i++){
      Serial.write(spektrum[i]);
    }
   position = 0;
  }
}

void establishContact() {
 while (Serial.available() <= 0) {
      Serial.write('A');   // send a capital A
      delay(300);
  }
}

// free running ADC fills capture buffer
ISR(ADC_vect)
{
  if (position >= FFT_N)
    return;
  
  capture[position] = ADC + zero;
  if (capture[position] == -1 || capture[position] == 1)
    capture[position] = 0;

  position++;
}
void adcInit(){
  /*  REFS0 : VCC use as a ref, IR_AUDIO : channel selection, ADEN : ADC Enable, ADSC : ADC Start, ADATE : ADC Auto Trigger Enable, ADIE : ADC Interrupt Enable,  ADPS : ADC Prescaler  */
  // free running ADC mode, f = ( 16MHz / prescaler ) / 13 cycles per conversion 
  ADMUX = _BV(REFS0) | IR_AUDIO; // | _BV(ADLAR); 
//  ADCSRA = _BV(ADSC) | _BV(ADEN) | _BV(ADATE) | _BV(ADIE) | _BV(ADPS2) | _BV(ADPS1) //prescaler 64 : 19231 Hz - 300Hz per 64 divisions
  ADCSRA = _BV(ADSC) | _BV(ADEN) | _BV(ADATE) | _BV(ADIE) | _BV(ADPS2) | _BV(ADPS1) | _BV(ADPS0); // prescaler 128 : 9615 Hz - 150 Hz per 64 divisions, better for most music
  sei();
}
void adcCalb(){
  Serial.println("Start to calc zero");
  long midl = 0;
  // get 2 meashurment at 2 sec
  // on ADC input must be NO SIGNAL!!!
  for (byte i = 0; i < 2; i++)
  {
    position = 0;
    delay(100);
    midl += capture[0];
    delay(900);
  }
  zero = -midl/2;
  Serial.println("Done.");
}

Again, thank you for your time.

Well, I got really busy there for a bit. Anyway, I got one of these https://www.sparkfun.com/products/9964, so all that's left is the output to a display. Again I don't really know what I'm doing with hardware yet, so I don't know whether to go for LED or LCD. I watched a few videos on multiplexing LEDs so if I went that rout I think I could do something like an 9x8 with the MEGA 2560's 13 pwm pins (not that I know how to wire that all up very well). Does anyone have any suggestions for me at this stage?

Try this: http://coolarduino.wordpress.com/2011/02/10/color-organ-spectrum-analyzer-on-arduino/

Have you hooked up the microphone and looked at the output of the FFT on your serial monitor?

Caution, that the Arduino is not powerful at all. For some audio/FFT work, it will be very very slow. I'd rather consider a Due or a Teensy3 for that kind of job. Both can be used with the Arduino IDE. (Teensy3 requires the Teensyduino add on).

Trying to use an 8-bit microcontroller with 2K of RAM to do real-time FFT and drive an array of LEDs is asking quite a bit.

You are far better off to use dedicated hardware, like the MSGEQ7, to do the filtering/analyzing while using the Arduino to drive the LEDs.

Oh, thats unfortunate that the arduino I got isn't powerful enough, oh well. Would it work to go from the electet breakout board to the input of the MSGEQ7? Or would I have to get something like this http://www.bliptronics.com/item.aspx?ItemID=116? Or do both the MSGEQ7 and electet breakout board fulfill the same role? The goal is to get sound from nearby, not from a direct line out of an ipod/computer/etc. Thanks for all the replies so far everyone, and thank you for your time.

Also, if im using the MSGEQ7, I am ok to use the 13 pwm pins multiplex a 7x6 LED grid?

Ok here's where I am now. I have a setup based on schematic that j skoba made http://nuewire.com/info-archive/msgeq7-by-j-skoba/ (the only modification to the code was to change the strobe and reset pins to 30 and 31) but it doesn't seem to work, the value for all of the bands just sits around 1023, so I assume I hooked something up incorrectly. Here are some pictures of how I wired everything. Anyone see what I did wrong? http://i.imgur.com/RI83CQL.jpg http://i.imgur.com/YNxZ2dF.jpg http://i.imgur.com/N2bAXjt.jpg http://i.imgur.com/tTqXvV2.jpg

Using the same color wire that overlaps makes it almost impossible to see what is connected where. Also, you are missing the Arduino connections.

Reverse engineer your own circuit. Draw a schematic based on what you have wired up now (without looking at the reference). That will help show thr differences.

The MSEQ is expecting line level voltages. That miceophone's per-amp may be over driving the input. Put a 470ohm resistor in series from the mic to the MSE's input to see if it changes anything.

Here a schematic I drew http://i.imgur.com/TATk5sP.png

I redid the wiring a bit since I last posted, not entirely sure what was wrong with it last time but now with no resistor between the mic and the MSEQ input the values float around 931 765 833 867 579 598 170 and max out with fairly quite noise. If I set up 450 Ohms ( I dont have a 470, but three 150s in series fill the same purpose right?) the values sit around 373 571 718 555 533 280 160 but still max out easily. With 1kOhms I get similar results to the 450 Ohms, and with 200k Ohms I get similar results to there being no resistor. The best results I have been able to get are were when I hooked the electet up to 3.3V and then used a 1k resistor, when I do that I get results around 57 72 67 69 70 65 64 and it doesn't seem to max as fast. But its still too fast, any thoughts.

Thanks for your time.

The official MSEQ7 application schematic uses 22K ohm resistors and a 0.01uF blocking cap. Probably intended to limit the input going into the chip. Which looks like as you increase resistance there, you're getting results closer to what you expect.

http://www.flickr.com/photos/9849051@N04/6651601457/