I tried to calculate the FFT on the Nucleo board for this blog. I think it is somehow working but not very clean. I am not sure what is wrong or if something is wrong. Please let me know if you know what I am doing wrong.
CMSIS 5
I am using the CMSIS library to calculate the FFT. I had some difficulties to get the pre-compiled libraries and include them in my project.
They have not documented it very well on how to get the library. So these are the steps I needed to do to get the pre-compiled library for the Nucleo board on Ubuntu 18.04 and STM32CubeIDE:
- Download the latest release ".pack" file from github. The latest version, at the time of writing this blog, is called "ARM.CMSIS.5.7.0.pack".
- Rename the file to "ARM.CMSIS.5.7.0.zip" and then un-compress it by right clicking on it and clicking on "Exctract here".
- Now you need the following two files inside the uncompressed directory.
- "ARM.CMSIS.5.7.0/CMSIS/DSP/Include/arm_math.h"
- "ARM.CMSIS.5.7.0/CMSIS/DSP/Lib/GCC/libarm_cortexM4lf_math.a"
- The rest is the same as the following YouTube video on how to use these files. Just note that in the previous version of CMSIS, the library files were in the git repo (according to video) but now they only exist in the released ".pack" file
(This is not my video)
Code
The code can be found in my github here. The code does this:
- I am using Timer 3 to trigger the ADC at frequency of 10kHz
- At the end of each ADC conversion, DMA is triggered to write the result in adc_buf[4096] array in circular manner.
- The following YouTube video was very helpful to setup the TIMER, DMA and ADC in STM32CubeIDE.
- At the end of 4096th DMA operation, a callback is called to set a triggert of FFT calculation.
- At the trigger, first, I copy the adc_buf to a fft_in buffer array and also convert from 16-bit unsigned int to a float with unit of voltage.
- Then the FFT function from CMSIS is being called.
- Then the FFT complex numbers are converted to absolute values into freqs[2048] array.
- Finally I am using the STM32CubeMonitor to visualize some of the frequencies. The FFT would create values for 2048 frequencies. Unfortunately STM32CubeMonitor cannot show all of them, so I just plot few of them.
In order to map the FFT results to frequencies I am using the following logic (in Python)
def get_freq(freqs_idx): sampling_frequency = 10000 signal_length = 4096 frequency = freqs_idx * sampling_frequency / signal_length return frequency
So for example the 10th element of freqs array would represents the frequency of get_freq(10) which is 24.41 Hz.
Results
I recorded a video to show the results and also possible problems. Sorry for my bad English.
- I am first showing the code and how I setup Timer, ADC, DMA and FFT
- Then I compare the FFT calculation of signal on Oscilloscope with the Nucleo board results.
- The top left is showing the FFT, calculated by Oscilloscope
- The bottom bar chart shows the FFT calculation on Nucleo Borad. The chart is created with STM32CubeMonitor. I could guess that there could be some problems with the STM32CubeMonitor as well because they frequently stated that the application is not created for monitoring arrays.
I see the video is only playing on 720p resolution, So I uploaded it on Youtube for 1080p resolution as well: https://youtu.be/WFoQAf8ER3o
Related Links
Previous Blogs:
- Vibration Sensor and Exercising - Introduction - Blog #1
- Vibration Sensor and Exercising - Basic Experiments - Blog #2
- My Progress: Experimenting with Vibration Sensors
External Resources:
Top Comments