Pages: [1] 2   Go Down
Author Topic: Playing with FFT  (Read 7642 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Edison Member
*
Karma: 49
Posts: 1666
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I've been playing around with the FFT code that was posted here: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1286718155
I wrote a sketch which generates various signals and then prints out their FFT and I've written some info about the output of the sketch and posted it to a web page. Have a peek if you're interested. http://members.shaw.ca/el.supremo/Arduino/fft/ffttest.htm

Pete
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 63
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I've been playing around with the FFT code that was posted here: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1286718155
I wrote a sketch which generates various signals and then prints out their FFT and I've written some info about the output of the sketch and posted it to a web page. Have a peek if you're interested. http://members.shaw.ca/el.supremo/Arduino/fft/ffttest.htm

Pete
thanks pete, it's very usefull
Logged

Offline Offline
Edison Member
*
Karma: 49
Posts: 1666
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thank you.

Pete
Logged

Gijon - Spain
Offline Offline
Newbie
*
Karma: 0
Posts: 23
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Looks great, thanks smiley
Logged

Offline Offline
Edison Member
*
Karma: 49
Posts: 1666
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You're welcome.

Pete
Logged

California
Offline Offline
Newbie
*
Karma: 0
Posts: 12
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

If you are interested in using FFT for a real world application, have a look at the ATmega328Accuracy project, at http://sourceforge.net/projects/lxardoscope/files/accuracyInvestigation/ . In this project, FFT was used with sinewaves for characterization of the ATmega328 ADC. Results include Signal-to-Noise Ratio and Effective Number of Bits.
Logged

NYC
Offline Offline
Full Member
***
Karma: 0
Posts: 129
The singularity is near!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Is this for making an FM transmitter? What is FFT used for?
Logged

Offline Offline
Edison Member
*
Karma: 49
Posts: 1666
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The Fast Fourier Transform is a mathematical technique to analyze the frequency components of a signal.

Pete
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 28
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi, peter, thank you for linking me to your post. (http://forum.arduino.cc/index.php?topic=175679.15)

I still don't understand why the way I generate sine wave data is not correct.
Can you explain how you generate useful data to test fft please?

I was using "k = 127*sin(2*3.14 * 100 * t )" to generate the data, 100 = wave frequency, but someone asked me what my simulated sampling frequency is, I have no idea what it is, or how to set it.
I wanted to simulate it as if I'm take the data out of A0 from an oscilloscope at a sampling rate of 38.5 khz . I don't have access to an socilloscope right now, but even if I do, I think it's better to simulate it with pure data first.

Thank you
Logged

Offline Offline
Edison Member
*
Karma: 49
Posts: 1666
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
k = 127*sin(2*3.14 * 100 * t )
The problem is with the values of t that you use. The basic formula is, as you have it there, A*sin(2*3.14 * f * t)
where A is amplitude, f is the frequency in Hertz, and t is in seconds.
But in your loop the values of t are 0, 1, 2, 3 etc. So your code is "sampling" the 100Hz sine wave once every second - i.e. at t=0 seconds, then t=1 second, etc.
To sample the sine wave at, say, 1000Hz you would need to generate samples for t = 0, .001, .002, .003 etc. which would require that t be a floating point value and increment it by .001 each time through the loop.
For a simulated sampling rate of 38.5kHz you would need to increment t by .000025974.
With 256 samples you will be generating the equivalent of 6.65ms.

BTW, I don't know how sensitive the FFT will be to numerical errors but I would suggest that you use a more precise value for pi. use 127*sin(2*PI*100*t)

Pete
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 28
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
k = 127*sin(2*3.14 * 100 * t )
The problem is with the values of t that you use. The basic formula is, as you have it there, A*sin(2*3.14 * f * t)
where A is amplitude, f is the frequency in Hertz, and t is in seconds.
But in your loop the values of t are 0, 1, 2, 3 etc. So your code is "sampling" the 100Hz sine wave once every second - i.e. at t=0 seconds, then t=1 second, etc.
To sample the sine wave at, say, 1000Hz you would need to generate samples for t = 0, .001, .002, .003 etc. which would require that t be a floating point value and increment it by .001 each time through the loop.
For a simulated sampling rate of 38.5kHz you would need to increment t by .000025974.
With 256 samples you will be generating the equivalent of 6.65ms.

BTW, I don't know how sensitive the FFT will be to numerical errors but I would suggest that you use a more precise value for pi. use 127*sin(2*PI*100*t)

Pete

Hey, Pete:
Great explanation! Thank you so much.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 28
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi, pete,

It worked! Thank you.

When I tried to to have A =1 from "k = A*sin(2*3.14159 * 100 * t / 400 )", every bin is zero. When I used large A,I was able to see much larger numbers in the bins where the frequency closest to. I still have a lot of other numbers in other bins. Is that normal to FFT?
I can set a limit and filter out these numbers, but I wanna make sure I'm using FFT correctly.
Logged

Offline Offline
Edison Member
*
Karma: 49
Posts: 1666
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The sine function has values between plus one and minus one so if you set A=1, all your samples will be small values. With a clean signal you should still be able to pick out the tone but it is a lot easier when the amplitude is larger.

Quote
I still have a lot of other numbers in other bins. Is that normal to FFT?
You have exhausted what I know about the FFT :-) You can get noise in the resulting signal but it should be significantly lower than the tone you're looking for. I also get strange results with some signals and I haven't been able to figure out why it happens.

Pete
Logged

Offline Offline
Edison Member
*
Karma: 49
Posts: 1666
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
if you set A=1, all your samples will be small values
More to the point, if you are using the same library as I am, the samples are all 8-bit integers so if A=1 the only values you would be giving the FFT would be -1, 0 and +1 which would result in a very noisy signal!

Pete
Logged

Rapa Nui
Offline Offline
Edison Member
*
Karma: 60
Posts: 2086
Pukao hats cleaning services
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

When you use integer values, for example 0..1023 with 512 points fft you may use:
Code:
f=20; //frequency
for (i=0; i<512; i++) {
  k[i] = 1023*sin(2*pi*f*i/511);
}
As the result you shall see a frequency in the bin n. 20 with an amplitude  of aprox 511 (where in bin n. 0 is DC).
You will see of course some data in other bins as well. That is normal. When sampling real data you have to be aware of aliasing, and you need to apply a "windowing" function before doing the fft (Hamming, Hann(ing), Blackman, and 20 others - in order to eliminate the effect of the sampling window).
By using the windowing function the "shape" of the spectral lines (ie your n.20) changes - you will see less noise around the particular spectral line.

http://en.wikipedia.org/wiki/Window_function

PS: Corrected
« Last Edit: July 09, 2013, 03:45:20 pm by pito » Logged

Pages: [1] 2   Go Up
Jump to: