Best way to sample ADC at 48kHz for buffer manipulations (FFT, etc)?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-10-16 9:02 AM
I'm trying to make a guitar pedal using the ADC on my F767ZI. I want to be able to perform an FFT and other functions on a buffer of data sampled at 48kHz.
I wanted to use the ADC DMAs and use the equation Tconv = 12.5cycles + SampleTime, but I have not been able to generate an exact PCLK rate in CubeMX to get the ADC sample rate at 48kHz precisely.
Am I better of using a 48kHz timer interrupt to read a sample from the DMA(?) and using some sort of global FIFO buffer? I worry that that might be overkill but at least I would know the sample rate is accurate.
- Labels:
-
ADC
-
Audio
-
DMA
-
STM32CubeMX
-
STM32F7 Series
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-10-16 10:21 AM
When you not send or store , then 48k isnt critical. DMA is way to store , timer is trigger for sample, this two thinks is independent.
You setup DMA buffer size and on half complete interrupts start calculate FFT for half ready buffer data...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-10-16 10:23 AM
Use timer triggered ADC conversion with circular DMA output similar to https://www.bartslinger.com/stm32/stm32-cubemx-timer-adc-dma-configuration
or here for a USB Scope: https://www.st.com/content/st_com/en/support/learning/stm32-education/stm32-moocs/stm32f7-hands-on-workshop.html
hth
KnarfB
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-10-16 10:56 AM
So basically HAL_ADC_ConvCpltCallback would get called every 10 Hz in that example?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-10-16 11:26 AM
I see, so when I'm calculating FFT, instead of using fs=48kHz, I would just use whatever sample rate the ADC/DMA is using?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-10-16 11:34 AM
The example is not really for audio. If you set the timer trigger event to 48 kHz and convert 1 ADC channel at each event, setup a larger buffer of say 20ms duration which are 9600 samples. Activate both, HAL_ADC_ConvHalfCpltCallback and HAL_ADC_ConvCpltCallback. This gives you 10ms time for (CPU) processing the half of the buffer just completed while the circular DMA writes new data to the other half. You may adjust the buffer size to your needs, e.g. doing a 4096 point FFT etc.
hth
KnarfB
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-10-16 11:39 AM
here is a nice video on the topic: https://youtu.be/acJ_kSEU0V0
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-10-16 11:40 AM
That makes sense - thank you for the help!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-10-16 12:12 PM
in part 2 of the video @22:06 you see glitches in the yellow output waveform. This is because he is calling processDSP() continuously in the main loop. This is wrong. See also the video comments. You better call it excatly once for every (half)buffer. This can be acomplished by setting inbufPtr = NULL; at the end of processDSP() and poll in the main loop for inbufPtr != NULL. This is a crude form of synchronisation by using a global volatile variable. Depending on how complex your overall code is (GUI?,...) you might even use FreeRTOS for multitasking and queues for synchronization...
hth
KnarfB
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-10-17 2:55 AM
Hi, KnarfB ,
> This is a crude form of synchronisation by using a global volatile variable.
How would you make it neat and elegant?
JW
@KnarfB​
