analogRead slow with ST libraries

Post here first, or if you can't find a relevant section!
Post Reply
ELaw
Posts: 2
Joined: Sat Mar 13, 2021 5:14 pm

analogRead slow with ST libraries

Post by ELaw »

Hello!

This is a question I originally asked on the Arduino forums but folks thought I might have better luck here - so here I am!

My question is simple though I suspect it might have a complex answer. I'm doing a project with an STM32F103 "blue pill" board and need fast sampling to read some characteristics of a 60 Hz waveform (this is for a generator monitor).

I have both "blue pill" board definitions installed... the STMicroelectronics ones and the "stm32duino" ones. But I'm stuck using the former because the parallel LCD I'm using seems to require the "MCUFRIEND_kbv" library and that library doesn't place nice with the stm32duino board def (it gives compiler errors).

Anyhow here's the problem... analogRead() is WAY slower with the ST board definition than the other one. I wrote this very basic sketch to test the speed with each:

Code: Select all

void setup() {
	// put your setup code here, to run once:
	Serial.begin(115200);
	delay(2500);
}

void loop() {
	// put your main code here, to run repeatedly:
	int temp;
	
	unsigned long time_start = micros();
	for (int i = 0; i < 100; i++){
		temp = analogRead(PA0);
	}
	unsigned long time_end = micros();

	Serial.println(time_end - time_start);
	delay(1000);
}
Using the ST board definitions, t takes about 5645 microseconds to do the 100 conversions, so 56.45 uSec per conversion (including the loop instructions but those only take about 1 uSec, I checked). Using the stm32duino board definitions, it only takes 698 microseconds... almost 10 times faster!

Does anyone know anything that can be done about that? I know there are other more complex ways to access the A/D like interleaving and DMA but I'd prefer to keep things simple. And it just doesn't make sense that the exact same function would be almost 10 times faster with one board definition than another.
mlundin
Posts: 94
Joined: Wed Nov 04, 2020 1:20 pm
Answers: 6
Location: Sweden

Re: analogRead slow with ST libraries

Post by mlundin »

analogRead() is a very nice and handy function, but so general, setup for all boards and all analog pins, there is a huge overhead.
You can increase speed by using the HAL layer for ADC, this is a bit fiddly and requires different settings for different boards, the HAL is not totally identical. I am working on how to make a nice interface but at present that is for STM32L476.

A good read is https://visualgdb.com/tutorials/arm/stm32/adc/ its for a F4 board but shows the steps included.

I thought stm32duino were the official ST board definitions, so I am not sure what core and board settings you refer to when comparing.
mrburnette
Posts: 633
Joined: Thu Dec 19, 2019 1:23 am
Answers: 7

Re: analogRead slow with ST libraries

Post by mrburnette »

mlundin wrote: Sat Mar 13, 2021 10:12 pm ...
I thought stm32duino were the official ST board definitions, so I am not sure what core and board settings you refer to when comparing.
Best to use "Official" / Libmaple (often called Roger's)

Official: https://github.com/stm32duino/Arduino_Core_STM32

Roger's: https://github.com/rogerclarkmelbourne/Arduino_STM32

Frederic and Roger discussed some issues with AnalogRead():
https://stm32duinoforum.com/forum/viewt ... _2234.html

This read may be insightful: viewtopic.php?t=138
Additionally, Rick's Pig-O-Scope code may be useful for LibMaple.

Image
ag123
Posts: 1655
Joined: Thu Dec 19, 2019 5:30 am
Answers: 24

Re: analogRead slow with ST libraries

Post by ag123 »

reviewing the codes in the core, hal and in particular the manual e.g. rm0008 would lead the way to fast adc on stm32f103. it can reach some 1.7 msps on stm32f103 when the full hardware features are used dual interleaved and using dma.
for anything in between the 'slowest' is analog read, then between that you could directly call adc functions e.g. hal, or if you prefer bare metal you could hit the registers directly. but that is still single reads. and if timing is important, you could use a hardware timer to call back and you can trigger adc sampling from the hw timer irq (that's normally good for about up to around 500 ksps). to push the limits it typically takes continuous adc mode (i.e. let the adc run the sampling on its own) dual interleaved mode and on dma. that will be around like 1.7 msps or whatever is the advertised limits

back in the 'old forum' days these limits are explored, and i've kind of made a usb oscilloscope out of it, but this is for libmaple (roger's) core
https://github.com/ag88/GirinoSTM32F103duino
there are more if you'd search around the web e.g.
https://github.com/pingumacpenguin/STM32-O-Scope/wiki
ELaw
Posts: 2
Joined: Sat Mar 13, 2021 5:14 pm

Re: analogRead slow with ST libraries

Post by ELaw »

Aaargh... this board/library-naming thing is driving me nuts! Maybe someone can help unconfuse me?

In boards manager, there seem to be two sources of board defs for the STM32F103. This first one I've been calling "stm32duino" because that's who the boards manager says they're "by":
stm32duino.PNG
stm32duino.PNG (8.51 KiB) Viewed 5217 times
Earlier today (yes I'm new to using these boards!) I got the impression those were by Roger Clark but after looking around a little more just now I realized the Roger Clark stuff is something different.

This is the entry for what I thought were the "official" ST board definitions:
stm32cores.PNG
stm32cores.PNG (20.13 KiB) Viewed 5217 times
I'm not using any board-specific libraries either in the "real" program I'm trying to write or the test program I posted above. Should I be?

The "real" program uses an LCD that requires use of the "mcufriend_kbv" library, and that library does not work when I use the first board definition shown above (it throws compiler errors). So I'm stuck using the ST board def, but with that one the ADC is slow.

I've also done a ton of Googling on the slow-A/D issue and read lots of pages talking about various related things, including some of the oscilloscope projects. A lot of them seem to reference a function called "adc_set_sample_rate", but when I put that into my code the compiler says it's undefined, and I can't find it in any of the libraries I have installed. I've seen a few references here and there to a "Maple" library but don't see anything by that name in library manager. So I'm stuck on that one.

BTW if anyone's interested I'm happy to post the "real" program I'm working on but this board doesn't allow ".ino" attachments. How do you get around that? I know I could rename it ".txt" or something but on some forums changing file extensions is considered bad form.
fredbox
Posts: 125
Joined: Thu Dec 19, 2019 3:05 am
Answers: 2

Re: analogRead slow with ST libraries

Post by fredbox »

Add your .ino to a zip file and you should be able to attach it.

STM32 Cores 1.9.0 is the "official" core.
The other is libmaple that someone created to make it easier to install.

Long before there was an official core, this forum was stm32duino and Roger's libmaple core was the only Arduino solution available.

I converted my source code to the "official" core a couple of years ago and use it for all projects going forward.
User avatar
fpiSTM
Posts: 1738
Joined: Wed Dec 11, 2019 7:11 pm
Answers: 91
Location: Le Mans
Contact:

Re: analogRead slow with ST libraries

Post by fpiSTM »

Here an example of how use HAL for ADC:
viewtopic.php?f=41&t=110
Post Reply

Return to “General discussion”