[SOLVED] The fastest ADC (analogRead) – how ?

acronis
Sun Oct 01, 2017 9:03 am
Hello.
Using a library – STM32GENERIC
Board – STM32F746G-DISCO 

I need to quickly read an analog signal (ADC).
I wrote a program , but the speed is slow 25 µs .
How to do the same , but as quickly as possible.

https://github.com/danieleff/STM32GENERIC

int IntArray[10000];
pinMode(A3, INPUT);

for (int a = 0; a < 10000; a++)
{
IntArray[a] = analogRead(A3); // slow 25 µs
}


ahull
Sun Oct 01, 2017 9:51 am
You are correct, analogread is not optimised for speed, however using DMA, and dual channel mode, you can get around 1 million samples per second.

Read through the Pig-o-scope thread below to get an idea of how this was achieved.

http://stm32duino.com/viewtopic.php?f=19&t=107

The code base is here -> https://github.com/pingumacpenguin/STM32-O-Scope/wiki

There are a lot of enhancements detailed in the first thread I linked, but the github code is tried and tested, so you could use that as a basis for what you are trying to do.


acronis
Sun Oct 01, 2017 10:07 am
just starting to learn ADC , and I find it difficult to understand.
Could you fix my code for maximum performance ?
I would be very grateful

RogerClark
Sun Oct 01, 2017 11:13 am
One reason Analog read is slow is that there are no dedicated Analog pins, so think the call first sets the pin mode.

Probably the best thing to do is to look in the core for the Analog read function and see what internal LibMaple call it makes to actually read from the ADC

Or like any Andy says…. Read using DMA

Look at Andy’s Pig-O-Scope code


dannyf
Sun Oct 01, 2017 11:42 am
but the speed is slow 25 µs .

the biggest driver is the prescalers. go to the datasheet and pick the shortest possible prescalers for your clock and code as such.

I think i did some benchmarking here when I wrote the armduino (http://stm32duino.com/viewtopic.php?f=42&t=2131, with links to the actual code so you can see the implementation) and the adc is in terms of us.

After that, it is how you access the data. fastest adc comes from free-running the module but the rest of your code has to be there.


mrburnette
Sun Oct 01, 2017 2:26 pm
[acronis – Sun Oct 01, 2017 10:07 am] –
just starting to learn ADC , and I find it difficult to understand.
Could you fix my code for maximum performance ?
I would be very grateful

Surely you jest?

Forums are to assist you toward creating your own solution and thereby help you to understand and develop confidence. Were you handed working code, there would be no learning… just incorporation of someone else’s solution.

Ray


alexandros
Mon Oct 02, 2017 7:52 pm
Congrats for the O scope project its fantastic.

I manage to get ADC readings from an analog in pin with 100times more frames than classic analog read.

Is there any other example of 2 Analog Dual-Simultaneous ADC readings??


arpruss
Thu Oct 12, 2017 5:31 pm
[ahull – Sun Oct 01, 2017 9:51 am] –
You are correct, analogread is not optimised for speed, however using DMA, and dual channel mode, you can get around 1 million samples per second.

Right, but I want to note that you don’t actually need to use DMA. If you use dual-channel interleaved mode, the regular CPU is fast enough to pull data at maximum speed without DMA, namely 0.584 microseconds per sample. After all, 0.584 microseconds is 123 clock cycles at 72 MHz, which is plenty of time to pull a reading, increment an index, etc.

Granted, DMA is cool, and has the advantage that interrupts won’t be an issue, but just using the CPU has a lower learning curve.

For simple CPU driven code, see: https://github.com/arpruss/stm32scope-e … /scope.ino


acronis
Fri Oct 13, 2017 2:01 pm
Hello.
Can I use this code on the Board STM32F4* – F7* library https://github.com/danieleff/STM32GENERIC ?

acronis
Sat Oct 14, 2017 2:19 am
adc_set_sample_rate(ADC1, ADC_SMPR_1_5); // ADC_SMPR_13_5, ADC_SMPR_1_5

On-Board STM32F103 it all compiles fine

On-Board STM32F407 error

error: cannot convert ‘const adc_dev’ to ‘const adc_dev*’ for argument ‘1’ to ‘void adc_set_sample_rate(const adc_dev*, adc_smp_rate)’

adc_set_sample_rate(ADC1, ADC_SMPR_1_5); // ADC_SMPR_13_5, ADC_SMPR_1_5

Please tell me how to do it properly on the Board STM32F4


arpruss
Wed Oct 18, 2017 7:30 pm
Maybe just put an ampersand before ADC1?

acronis
Mon Oct 23, 2017 3:03 pm
Code https://github.com/arpruss/stm32scope-e … /scope.ino works on F4 BLACK !

A huge thank you stevestrong for assistance in adapting this example to F407VET6 !

viewtopic.php?f=39&p=36083#p35918


ChrisMicro
Mon Oct 23, 2017 3:37 pm
Hi arconis,
thanks that you made your code open source.
Probably it would be a good idea if you add in a README which Arduino framework you have used and a little picture of the setup.

Leave a Reply

Your email address will not be published. Required fields are marked *