2025-11-13 10:01 PM
Hello,
I am trying to configure my STM32H723ZG to be able to read the value of a few current sensors. My main concern at the moment is the speed at which I need to read these. I'm hoping to be reading upwards of rate of 20kHz.
My questions are about which method might be best, the standard way of reading the ADCs seems insufficient, I've seen online some methods are DMA and injected conversions. If anyone could provide some insight into what might be best and how to go about implementing them that would be great.
Additionally, I wanted to ask how to determine an appropriate sampling time of the ADC.
Thank you in advance for your help!
2025-11-14 12:50 AM
Hi @evanpol,
Here's a detailed explanation and solution to help you achieve fast and efficient ADC readings on your STM32H723ZG, targeting a sampling rate of around 20 kHz for multiple current sensors.
How to Implement DMA + Timer Trigger ADC Sampling on STM32H7
Configure ADC:
Configure Timer:
Configure DMA:
Start timer and ADC:
Data Processing:
The ADC sampling time is the time the ADC input is connected to the sampling capacitor before conversion starts. It affects:
Check sensor output impedance:
Calculate total conversion time:
Tconv = Tsampling+12.5×TADCclock
Since you want 20 kHz per channel, even with multiple channels, this is achievable with ample margin.
Good luck,
Aime
2025-11-14 1:05 AM
Hello @evanpol ,
You can check the example for using the ADC peripheral to perform a single conversion on the internal temperature sensor and calculate the temperature in degrees Celsius at this link:
This example uses the polling method and shows basic ADC configuration and reading. You can follow its structure as a starting point for your own application.
You can also check our other examples demonstrating ADC with different programming models such as DMA and interrupt-based methods in this link below :
STM32CubeWB/Projects/P-NUCLEO-WB55.Nucleo/Examples_LL/ADC at master · STMicroelectronics/STM32CubeWB · GitHub
Br
2025-11-15 3:07 AM - edited 2025-11-15 3:09 AM
Hi @evanpol ,
You have a very good answer from @Aime , just to add a little detail to their recommended method (timer trigger + DMA). I'm assuming that you're using FreeRTOS, and if not then the following would need to be adapted, but the general approach is still applicable.
Let's say that you want to capture 5 channels each at 20kHz and that you want your software to process received data in chunks of 1024 samples at a time. In that case each chunk of samples will arrive at intervals of 1024 (samples) ÷ [5 (chan) x 20000 (samp/sec/chan)] = 10.24 ms.
You then need to assign an ADC buffer to capture the data, and the length of this should be double the length of each chunk: 2 x 1024 = 2048 samples.
Then implement the half-complete ADC interrupt handler. This should be very simple. A simple semaphore is given each time the interrupt fires.
Meanwhile, you have a task sitting in an endless loop (which it enters after creating the semaphore, initialising the timer and starting the ADC etc..). This task takes the semaphore, which will block the task until each half complete ISR fires. The task then has up to about 10ms (ideally taking much less time) in which to do whatever you need to do with the 1024 ADC samples.
On each firing of the ISR and processing of 1024 samples, you need to use the first and second half of the allocated ADC buffer in an alternating way: start with the first half, then the second half, then the first again etc - hence double buffering.
I hope this is helpful and apologies if I'm telling you stuff that you already know!
2025-11-20 10:16 PM
Thank you very much for your help. Today I was able to successfully decrease the computation time of my control loop significantly, thanks to the ADCs running much faster!
I was wondering if any of you had ideas regarding how I can get data out of the STM without compromising performance? I was originally sending data through to a serial monitor using printf however this is very intensive and slows things down a lot and won't be viable.
Any thoughts are welcome, thank you for your help.
2025-11-20 11:33 PM - edited 2025-11-21 2:39 AM
Hi @evanpol ,
It really depends on where you want the data to go. For example, if you have some kind of external data logger, then presumably you have a defined hardware interface to it?
I wonder, do you actually need to output data, rather than capturing it to SD-Card on your STM32? Or maybe you can do whatever your external system needs to do with the data on the STM32 target, then reduce the required data rate for final output, rather than perhaps outputting to a PC (or something) for data analysis?
I'm speculating because I don't understand your system very well. If you can clarify your fundamental objective, and whatever constraints you need to work to, then I'm sure people will have better suggestions for you.
2025-11-24 9:50 PM
Hi @bramble , thank you for your advice and sorry for the slow reply!
Whilst it would be nice I don't necessarily need access to the data live, what's more important to me is overhead of the process. I am running a control look at 20kHz, currently the full loop takes ~40us to run leaving a max of 10us for any data logging.
Today I explored using a J-Link, i quickly found out I needed to convert floats to strings to use them in RTT viewer and that the overhead for it was substantial. I also tried RTT logger and saving the data as a raw binary file. Whilst this was good computation-wise the post processing of the binary file proved to be quite difficult and I wasn't able to get any useful data.
I was hoping to get some advice on what you think the next move should be? What's the overhead like on reading to an SD card, what hardware do I need to make that work, and what's the best way to implement it?
I'd also be curious to see if you know of a better way to read data with J-Link, as that it a route I'd prefer to go down.
Thanks again for your help!
2025-11-27 2:15 PM