I'd like to venture into the FFT world with Arduino and am trying to figure out what's needed. It seems fix_fft is the best option to get what I need on the software side. On the hardware side though, do I need the raw audio input from an electret mic with an opamp, or can I use the breakout electret mic that SparkFun has (SparkFun Electret Microphone Breakout - BOB-12758 - SparkFun Electronics)?
Just use the board's audio output into an analog pin and have fix_fft process?
DC offset? WHat I'd like to do is create a board that accepts two methods of input, either the on board electret mic, or have a 3.5mm jack. If the jack is used, the mic should be turned off (which I believe one can do when you plug something in the jack as it breaks the connection with one of its pins, I think.)
If I use the SparkFun breakout board, I don't need anything else right, just connect 5V+ and GND, and take the AUD pin to an analog input, yes? How do I augment that to add a 3.5mm jack to the circuit as well?
I'm reasonably new to all this so dont take my work as law but I looked into this recently.
In regards to DC offset: The Arduino ADC (Analog to Digital Convertor) can only read positive voltages i.e +0V. This is an issue when trying to read audio as a sound waves oscillate between positive and negative voltages. To overcome this you supply a DC offset to raise the signal between 0 and 5V so the Arduino can read it. Since the Arduino can read 0-5V range a +2.5V DC offset is a good idea however the circuit below uses a potentiometer to set the value.
The circuit around Analogue input 1 in that diagram will work fine for a 3.5mm input.
The sparkfun mic breakout board applies a DC offset for you so just plug it in and away you go.
As for fix_fft dont try to understand it...its mathematic magic. From memory you fill an array with samples and it returns an array of frequencies. I dont understand how it can tell when an Arduino samples so slow but apparently it works. Someone else will have to help you with this one.
The circuit around Analogue input 1 in that diagram will work fine for a 3.5mm input.
Cool, thanks.
fireman_sam6986:
As for fix_fft dont try to understand it...its mathematic magic. From memory you fill an array with samples and it returns an array of frequencies. I dont understand how it can tell when an Arduino samples so slow but apparently it works. Someone else will have to help you with this one.
Not so much trying to dissect it, but more what's in the arrays, or specifically, the data array. Is it decimal values between a specific range? Or is it all hex values? Somewhere, somehow one must be getting something to work with that people are using to control LEDs and what not.
Is it decimal values between a specific range? Or is it all hex values?
There is no difference between these two statements. All data is stored in binary bit patterns, how you represent the number in the code is up to you it all ends up as the same bit pattern.
For example defining something as 0x10 or as decimal 16 the same bit pattern is stored.
Yes, I realized that after I hit Post, and with the forums taking upwards of a minute or 2 to perform a task (that's when it doesn't simply timeout), I didn't bother to come back and fix my reply. Still doesn't answer my question of what is in the data array. What are those values? Frequency values? Values between 0 and 1023? I need to know what they are. The last time I tried that code and tried sending the data values to Serial.print(), all I got were odd characters such as '?', '.', '<' being displayed (and only the first 3 to 5 bins would output something.) But that may simply be because I don't know what they are to begin with. If they're stored as decimal values, then something's wrong. If they're stored as 0xFF then I need to print as HEX. Either way, I have no clue WHAT they are to begin with.
The last time I tried that code and tried sending the data values to Serial.print(), all I got were odd characters such as '?', '.', '<' being displayed
They are numbers representing the energy in the different frequency bands, why would they correspond to anything other than odd characters?
Maybe because I was expecting to see an actual numerical value of sorts when I passed them to Serial.print(). If they are representing the energy, how are people translating that to something used to drive LEDs through PWM?
In replay #1 I post a link , there is an arduino sketch you can download. You may use it as starting point, sketch include a code to print data via serial link and controls a bunch of leds.
Data in the output array are magnitudes of specific sine frequencies in the input analog waveform
All right, I'm using your code Magician and dumping all 64 bins to Serial. So I see a bunch of numbers .. great, it works. Using a tone generator I can see which bins get affected and all of that. Great. Technically, if I have 64 LEDs, corresponding to each bin, I should be able to control that LED with PWM, yes? What's the min and max value that could be in the bin (so I can map it properly to 0-1024 for PWM)?
And I'm starting to realize this won't work for what I'd like to do in the future, so I'll be looking for something else. But in the mean time ... it's still fun to play with.
32? That's odd. After the "Calculation of the magnitude" (this is in your code), I dump bins 0 to 63, and they all show data in them. I do see that further down you're only using bins 1 to 32 for the LEDs (1-11, 11-21, and 21-32). So where is the data I'm seeing coming from?
When I tap the mic, I see some negative values and some rather high positives as well:
Ok, so I ignore anything past bin 31 ... Fair 'nuf. Now, go back to my output posted earlier. How come I see some rather high values, as well as negative ones? All I did was gently tap the mic.
I am not sure about the negative values in general they represent a magnitude so they should all be positive, so maybe there is some overflow going on in the arithmetic. As it is not my code I can't say, and I don't have the next two days free to try and work it out.
How come I see some rather high values
You will do because you:-
All I did was gently tap the mic
This is an impulse and that Fourier series goes up to infinity. So you should see the higher frequency bins high.
Just a random question are you plugging the mic/stereo line directly into the arduino? I wanted to try doing this is a future project and was wondering if the fft will work by using a mic breakout straight into an Arduino analog pin or do you need to use an external fast ADC.