Use FFT to handle MEMS microphone data

Hi Nordic,

The proposed approach involves capturing ambient sound from the surroundings to achieve different LED display effects. The current plan is to use an Analog-to-Digital (AD) converter to collect output from MEMS microphones. Subsequently, Fast Fourier Transform (FFT) will be applied to analyze the frequency components of the sound, enabling the implementation of distinct LED display effects based on the frequency variations.

I am not entirely certain whether the ADC of the nRF52832 can achieve this effect. Also, is this approach feasible?

Parents
  • Hi 

    The SAADC module in the nRF52832 does not come with built in FFT capabilities, but the MCU can run FFT algorithms on the ADC data after it has been stored in RAM. 

    The nRF52832 includes the standard ARM Cortex M4 DSP extension, which can be used to accelerate FFT operations. 

    I am not entirely certain whether the ADC of the nRF52832 can achieve this effect. Also, is this approach feasible?

    It's hard to answer this definitely without knowing what kind of effects you are trying to achieve. For instance what kind of FFT resolution would you need, and how often do you need to get a new FFT reading, will affect the CPU performance required. Have you tried to prototype the application on a more high end system, like a PC, to see if the idea is sound? 

    Which SDK are you planning to use for your development? 

    Best regards
    Torbjørn

  • Hi Ovrebekk,

    Thanks for your reply!

    The SAADC module in the nRF52832 does not come with built in FFT capabilities, but the MCU can run FFT algorithms on the ADC data after it has been stored in RAM. 

    This is exactly what I want to do!

    It's hard to answer this definitely without knowing what kind of effects you are trying to achieve. For instance what kind of FFT resolution would you need, and how often do you need to get a new FFT reading, will affect the CPU performance required.

    Due to the relatively low frequency of light visible to the human eye, I intend to use a one-millisecond timer to read ADC data. After obtaining 20 data points (within a period of 20 milliseconds or longer), I plan to use the Fast Fourier Transform (FFT) to determine the corresponding frequencies for each ADC value. Different frequencies within this time frame will correspond to different display effects on LEDs. The specific display effects on the LEDs can be achieved by mapping different frequency magnitudes to varying brightness levels.

    Which SDK are you planning to use for your development? 

    I have been developing using SDK version 17.1.0, so I intend to continue using it.

  • Hi 

    You mean you want to run the FFT calculations every millisecond? 

    I assume the sampling frequency is higher since you are sampling sound? 

    In the nRF5 SDK there is an FFT example available in the examples/periphepheral/fpu_fft folder. You can have a look at that for reference. 

    Best regards
    Torbjørn

Reply Children
  • ou mean you want to run the FFT calculations every millisecond? 

    My goal is to obtain the magnitude of environmental sound. The method I can think of is to convert the analog signal collected by the microphone into specific amplitudes using FFT (Fast Fourier Transform). If there are other methods, please recommend them to me. After referring to the FFT example in the SDK, I found that I need to input 128 float32 type data into the fft_process() function. Does this mean that I need to obtain 128 data points through ADC before performing FFT transformation to obtain the corresponding magnitude?

  • Hi 

    I am guessing there are simpler ways to get the magnitude of sound than FFT, but it makes sense that you would use FFT to be able to pick out specific frequency ranges when analyzing the amplitude. 

    For instance, it is quite common to get low frequency sounds with high magnitude that aren't perceived as very loud by the ear, because of the low frequency (wind noise for instance). 

    Taylor said:
    Does this mean that I need to obtain 128 data points through ADC before performing FFT transformation to obtain the corresponding magnitude?

    Yes, if you want to use a samples size of 128 then you need to collect 128 ADC samples before running the FFT operation. 

    You can change the sample size if you want, in the example this is set by the FFT_TEST_COMP_SAMPLES_LEN define at the top of main.c

    Essentially you should scale this setting based on the frequency ranges you are interested in, and how often you want to get a new FFT reading. Using a larger sample size allows you to capture lower frequencies, but you will get less updates per second. 

    If I remember correctly the sample length should be a power of 2 value (32, 64, 128, 256 etc), so keep this in mind. 

    Best regards
    Torbjørn

  • Essentially you should scale this setting based on the frequency ranges you are interested in, and how often you want to get a new FFT reading. Using a larger sample size allows you to capture lower frequencies, but you will get less updates per second. 

    My previous statement may have had some misunderstandings regarding FFT processing. In the FFT example in the SDK, it requires filling in 128 data points to obtain 64 data points. If I want to process an audio signal with a maximum frequency of 5 kHz, then the sampling rate needs to be at least 10 kHz. This means that at a frequency of 10 kHz, 128 ADC samples need to be obtained every 0.1 ms for the FFT to produce correct results. I have two questions to address: one is how do I create a timer for 0.1 ms? Additionally, can 128 data points be collected by the ADC within 0.1 ms?

  • Hi 

    I think the most natural way to implement this is to run the ADC at 10kHz, and simply set an ADC buffer size of 128 samples. Once one buffer is full you hand it over to the FFT processing function, and provide a second 128 sample buffer to the ADC. 

    Then you will get a new 128 byte buffer for processing every 12.8ms (1 sec / 10.000Hz * 128 samples)

    This means you will get a new FFT result at a rate of 78Hz, which would probably be enough to provide smooth feedback for the LED display algorithms? 

    Best regards
    Torbjørn

  • I think the most natural way to implement this is to run the ADC at 10kHz, and simply set an ADC buffer size of 128 samples. Once one buffer is full you hand it over to the FFT processing function, and provide a second 128 sample buffer to the ADC.

    So, you mean that collecting ADC data once every 0.1ms is sufficient to obtain processing results through FFT? I thought it was necessary to collect 128 data points continuously within 0.1ms. In that case, how should I use a 0.1ms timer? The minimum time for timers in the SDK is 1ms.

Related