Fast Fourier Transform (FFT) (Part 8)

I received some questions related to the use of the FFT library. This example illustrate how to interface the FFT function to an acquisition engine, such as the optimized one from the PlainADC library.

Note: The huge popularity of PlainDSP (merge of PlainFFT and PlainADC libraries) and the numerous requests for help drove me to think about a convenient solution for all designers, artists, students, professors, R&D people, prototypists who need to understand, experiment, create applications featuring advanced Digital Signal Processing on Arduino. The result of intense thoughts, design and writing is the collection PlainDSP kits, starting with the audio kit.

Hello, im new to the arduino and having some trouble. I am putting a sin wave varying between 100-500 Hz into my analog input channel 0 and trying to run a FFT on it. I have uploaded the PlainDac and PlainFFT libraries and need to find the fundamental frequency of my original sin wave. I want to take the highest magnitude of the FFT and assume that is my fundamental. When I run this example code and view the serial monitor, im getting the highest magnitude at zero. Am i doing something wrong? Whats the easiest way to determine the fundamental from this code? Any help greatly appreciated. -Thanks

There are a few precautions to take prior to running both libs. In their current state, the PlainDAC lib generates unsigned 8 bits data, while the PlainFFT lib requires doubles. I am currently working on both libs in order to ease their integration.
Would you post your code in order to get a better idea of your problem? You should also check the process step by step, printing intermediate results (vectors actually)

I realized that I wasn’t grounding the arduino. After doing it, everything started to work good. After getting everything running perfectly, I tried to get the maximum value of the values that I was getting from the FFT. For this case, I tried to run the max() function and then serial.print my result but I am getting either errors or results that do not make sense. I guess that my question is: What’s the best way to find the maximum frequency, utilizing your code? Any help will be greatly appreciated.

This is indeed a very interesting library for the nice little Arduino. I preffered using a software based FFT processing algorithm as long as I am not doing any process intensive work on the Arduino. For process intensive applications I was considering using a MSGEQ7, a 7 frequency audio spectrum analyser. It’s a one channel chip so you would need 2 of these to be able to process stereo audio.

Indeed, the MSGEQ7 is a very clever chip. Or let’s put it right: the chip benefits from a clever design! However, its principle of operation (www.mix-sig.com/datasheets/MSGEQ7.pdf) is based on analog filtering and cuts the full bandwith in seven frequencies. Far enough for visual effects! You may save 5$ using FFT and some coding in order to select the 63 Hz, 160 Hz, 400 Hz, 1 kHz, 2.5 kHz, 6.25 kHz and 16 kHz bands.

I’m planing on using the Arduino with this chip and a chain of LEDs controlled by LED drivers with PWM using shift registry.
As an addition I might be adding an LCD display and a rotary encoder to it. My basic idea was to have it work as a standalone machine or have it communicate via DMX.

I want to use PlainFFT library to calculate the harmonics of a intensity wave (50Hz in Spain), the idea is to calculate the Irms of the captured wave.

I have a question: My wave hasn´t got negative values because i´ve added an offset before the capture (remember that arduino´s ADCs can´t capture negative values). It may be a problem? Sould I take away this offset by sofware before the FFT? (i asked this because, if i understand well, library works wtih symmetries).

PlainSCAN has been replaced by PlainADC which allows single shot or scanned measurements. As for PlainSCAN, PlainADC outputs unsigned 16 bits data because in order to save memory. On the other hand, PlainFFT inputs doubles in order to perform any type of transform. So that, in between, you need to convert data in such a way (Pseudo code):

Hello,
thanks for your great work. I have a little problem with the code you posted.
The problem is that, when I verify the code, the error “PlainADC has no member named ‘setAcquisitionParameters’” appears. I read into the library PlainADC to search AcquisitionParameters and AcquireData but I don’ t find it.
Can you help me to solve the problem?
Thank you very much.

Please place a request for the latest versions which are (should be… ;-)) fully compatible! Sorry for the trouble that you faced.
Again, one reason why I do not place the code for download is that I care a lot for compatibility of versions (I developed something like 30 libraries among which a dozen are available on request)

I would first like to say that i greatly appreciate your efforts in providing us with this know how. I am an electrical engineering student and would like to download your libraries for use in a digital guitar tuner that I am making for a final project.

Thanks for your kind comment. I know that many students read these posts, and many already got their PlaiNDSP Audio kit (http://goo.gl/GkRZOk) which features almost all the necessary means for exercising building awesome applications featuring DSP (http://goo.gl/iNZFjI).

Hello,
I would like to know the meaning of this scale type: FFT_SCL_TYP_MAGNITUDE,FFT_SCL_TYP_AMPLITUDE, FFT_SCL_TYP_RMS and if the results are in decibel or other units of measurement. Thank you very much.

If you are looking for dB scale, you must compute individual un-normalized dB values:
result = 10 * (Math.Log((ImagValue * ImagValue) + (RealValue * RealValue )) / Math.Log(10.0))
record the maximum value from each result, and normalize each value on completion of the previous stage doing something like
For each value result -= MaxValue