cancel
Showing results for 
Search instead for 
Did you mean: 

Fastest way to use UART - sprintf takes up too much time

Aquaman
Associate II

Hi

I have to send a large amount of data as a formatted ASCII over UART. The data is read through some terminal software on a PC.

I only have 1 wire to do this so it has to be UART.

I have a F042K6 STM32 Nucleo and running it at 1500000 baud. Works fine. However I cannot get the data to send fast enough.

It is taking about 2.2ms to format the data and send via UART. My sampling rate needs to be between 1khz to 1.5khz

The problem I think is the sprintf which I have to use to get the format for the UART to send.

Is there a way I can speed this up?

Or should I just buy a different chip. I am using 32pin package because I dont have space for anything larger.

This application btw works reasonably well on an LPC1768 made using ARM mbed 2 arduino type compiler, so maybe I should just buy the beefiest 32pin STM32 available?

Am running at 48mhz, have tried lower clock speeds with same BAUD UART and the transfer just gets slower, so pretty sure it is to do with the sprintf

uart_buf_len = sprintf(uart_buf, "%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%i\r\n", v1, v2, v3, v4, v5, v6, v7, v8, timer_val);
	    HAL_UART_Transmit(&huart1, (uint8_t *)uart_buf, uart_buf_len, 100);

13 REPLIES 13
KnarfB
Principal III

Did you set SYSCLK to 48 MHz (default is 8)?

F0 (Cortex-M0) has no floating point unit which makes printing floats slow(er). A pin-compatible Cortex-M4 should do better.

Aquaman
Associate II

Yes I set it to 48 Mhz

Also tried multiple other lower frequencies just to see the impact

KnarfB
Principal III

one more idea: as you print only up to 1 decimal place: multiply the vi by 10.0f and cast the results to int, print ints, divide by 10 on the other side.

I've given it a go with INTs and it still isn't really fast enough

I think I will buy one of these STM32G4 chips at 170Mhz - although looks like it only goes to 144Mhz from stmcube app

TDK
Guru

> It is taking about 2.2ms to format the data and send via UART.

Can you measure the time taken by sprintf separately than the time taken by HAL_UART_Transmit? I would expect sprintf to be much quicker.

You could improve things up by sending out via DMA. That way the CPU is free to do other stuff while UART is transmitting.

Could also look at the line to see if HAL_UART_Transmit is fast enough to send without and idle time between bytes.

If you feel a post has answered your question, please click "Accept as Solution".

The sprintf line seems to be taking about 1.6ms

It seems about right if you calculate 921600 baud = 115200 bytes/s

Each line is say 50 ASCI = 50bytes = approx. 430us transmission not counting for the start up and stop bits and overhead in the HAL stuff etc

Total adds up to about 2.2ms

Where do those values come from (read: do they need to be float at all?), what's their range, how are the vX variables declared?

The difference between 'G4 and 'F0 is much more than raw clock.

JW

From an external ADC

For now there is no opportunity to do processing on the other side. The data has to be streamed and viewable in real time straight from the MCU

Seems like sending raw data instead of converted text would solve the problem. You’d need to add processing on the receiving end to parse the data.
If you feel a post has answered your question, please click "Accept as Solution".