Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[ARM] STM32 Getting ADC Data Speed Problem

nadd

Junior Member level 3
Junior Member level 3
Joined
Oct 3, 2022
Messages
28
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
272
Hello everyone,

I'm trying to get ADC(DMA) data on the NucleoF303RE STM32 board. The sampling speed is 1Msamples/s. When I apply a sinus wave I see data losses on ADC data. I tried to read data with a serial port and save it to an sd card. Both of them have the same problem.

While saving to the sd card, I stopped ADC after the buffer is filled to see what's is the problem. There is no data loss when ADC is stopped after filling the buffer. But, I need continuous conversion, so it is not a solution for me. I guess the ADC uses the same buffer immediately, and saving data commands are not fast enough before ADC fills the buffer again.

Do you have any suggestions? Where am I doing wrong? or maybe any other algorithms?

Codes to save to the sd card I use:
C:
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) {
   // HAL_ADC_Stop_DMA(&hadc1);
    for (int i = 0; i < ADC_BUF_LEN; i++) {
        fres = f_printf(&fil, "%d\n", adc_buf[i]);
        if (fres < 0) {
            myprintf("f_printf error (%i)\r\n", fres);
                while(1);
        }
    }
    f_close(&fil);
    f_mount(NULL, "", 0);
}

Codes to read from the serial port I use:
C:
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) {
    for (int i = 0; i < ADC_BUF_LEN; ) {
        myprintf("%i\r\n", adc_buf[i]);
        i++;
    }
}

I also tried to transfer data when the half buffer is filled, then transfer the second half when the full buffer is filled. But, It only uses the first half buffer with this code and keeps doing data losses.
C:
void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc) {
    for (int i = 0; i < ADC_BUF_LEN/2; ) {
        myprintf("%i\r\n", adc_buf[i]);
        i++;
    }
}
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) {
    for (int i = ADC_BUF_LEN/2; i < ADC_BUF_LEN; ) {
        myprintf("%i\r\n", adc_buf[i]);
        i++;
    }
}
 

KlausST

Super Moderator
Staff member
Advanced Member level 7
Joined
Apr 17, 2014
Messages
23,244
Helped
4,738
Reputation
9,497
Reaction score
5,125
Trophy points
1,393
Activity points
153,963
Hi,

I guess it's no ADC problem.
I guess the bottleneck is the data processing (sending, storing).

Sending data via UART.
Did you calculate the possible data rate via UART? (SD card). If not, then please do so.

Klaus
 

nadd

Junior Member level 3
Junior Member level 3
Joined
Oct 3, 2022
Messages
28
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
272
The serial port reading&plotting program gives some data rate information, would it provide the possible data rate correctly?

Regarding the program(right-bottom corner), the data rate is around 4524sps.
usartspeed.PNG


Also, does the buffer size affect the results? It's 12000 now, when I decrease it to around 5000, the wave seems very distorted.
 

KlausST

Super Moderator
Staff member
Advanced Member level 7
Joined
Apr 17, 2014
Messages
23,244
Helped
4,738
Reputation
9,497
Reaction score
5,125
Trophy points
1,393
Activity points
153,963
Hi,

The math is really simple ... and indeed should be expected to be solved by anybody.

Per sample you get a 16 bit number ....
So with 1 million samples you get 16 million bits per second. (Just raw bits)

But now you translate this into an ASCII string:
The range of each sample is 0...4095 (assuming a 12 bit ADC), thus up to 4 digits
Now you form this into an ASCII string (mysprintf) you get up to 4 ASCII bytes (digits) plus CR plus LF (your \r \n).
This makes up to 6 bytes per sample.
Each byte is transferred by 10 bits (1 START, 8 data , 1 STOP).
So 60 bits per sample.
Multiplied with 1 MSPS this gives a (UART) data rate of 60 Million bits per second. 60Mbits/s, 60MBaud (in optimal case)

But you use 256,000 Baud = 256 kBaud = 0.256MBaud

You are a factor of 240 too slow!

*****

Even if you are not able to do the math without or with a calculator..

Just guessing that 1,000,000 = 1 million "informations per second" (1MSPS)
transferred with a speed of 256,000 informations per second (ignoring the size of information)
could cause trouble ... was the least you could do.

Klaus
 

FvM

Super Moderator
Staff member
Advanced Member level 7
Joined
Jan 22, 2008
Messages
50,970
Helped
14,629
Reputation
29,534
Reaction score
13,733
Trophy points
1,393
Location
Bochum, Germany
Activity points
291,643
Sending decimal formatted 10 or 12 bit data with \n terminator, 5 characters or 50 bits. Maximal 5.1 k samples per second with 256 kBaud.
--- Updated ---

In a short, STM32F303 doesn't provide a peripheral interface that can continuously stream 1 or 2 MSPS ADC data to a PC or a storage device. I would go for a faster F4xx device with 100 MBit ethernet.
 
Last edited:

nadd

Junior Member level 3
Junior Member level 3
Joined
Oct 3, 2022
Messages
28
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
272
Hi,

The math is really simple ... and indeed should be expected to be solved by anybody.

Per sample you get a 16 bit number ....
So with 1 million samples you get 16 million bits per second. (Just raw bits)

But now you translate this into an ASCII string:
The range of each sample is 0...4095 (assuming a 12 bit ADC), thus up to 4 digits
Now you form this into an ASCII string (mysprintf) you get up to 4 ASCII bytes (digits) plus CR plus LF (your \r \n).
This makes up to 6 bytes per sample.
Each byte is transferred by 10 bits (1 START, 8 data , 1 STOP).
So 60 bits per sample.
Multiplied with 1 MSPS this gives a (UART) data rate of 60 Million bits per second. 60Mbits/s, 60MBaud (in optimal case)

But you use 256,000 Baud = 256 kBaud = 0.256MBaud



*****

Even if you are not able to do the math without or with a calculator..

Just guessing that 1,000,000 = 1 million "informations per second" (1MSPS)
transferred with a speed of 256,000 informations per second (ignoring the size of information)
could cause trouble ... was the least you could do.

Klaus
Hi Klaus,

Thank you so much for the explanation. I had almost no idea about how to do it, I tried to find out but there was no clear explanation like yours.

May I ask about "You are a factor of 240 too slow!", do you mean the factors of 240 are the numbers that are multiplied in pairs resulting in the original number 240?

I have the same problem to save to an sd card, I guess the reason is the same. I realized that I left the Clock prescaler at a low rate, it provides a 281.25KBit/s baud rate. At the minimum prescaler(2), it can provide 18MBit/s. Is the calculation the same?
savesdcard-org.PNG

The "Data Size" in STM32CubeIDE can be minimum of 4 bits. 6 bytes per sample * 6 bits (1 START, 4 data, 1 STOP) = 36MBits/s, which is still not fast enough. Is this calculation correct for saving to an sd card?

Sending decimal formatted 10 or 12 bit data with \n terminator, 5 characters or 50 bits. Maximal 5.1 k samples per second with 256 kBaud.
--- Updated ---

In a short, STM32F303 doesn't provide a peripheral interface that can continuously stream 1 or 2 MSPS ADC data to a PC or a storage device. I would go for a faster F4xx device with 100 MBit ethernet.
Hi FvM,

Thank you so much. I'm looking for another board that has a 12bits ADC, min 1 Msamples/s and an ethernet port. I wonder does an onboard memory card slot, would be fast enough?
 

KlausST

Super Moderator
Staff member
Advanced Member level 7
Joined
Apr 17, 2014
Messages
23,244
Helped
4,738
Reputation
9,497
Reaction score
5,125
Trophy points
1,393
Activity points
153,963
May I ask about "You are a factor of 240 too slow!", do you mean the factors of 240 are the numbers that are multiplied in pairs resulting in the original number 240?
Really? 250,000 (baud) x 240 (factor) = 60,000,000 (baud)
The "Data Size" in STM32CubeIDE can be minimum of 4 bits. 6 bytes per sample * 6 bits (1 START, 4 data, 1 STOP) = 36MBits/s, which is still not fast enough. Is this calculation correct for saving to an sd card?
You can't transmit 8 but data via UART (at least not with standard interfaces)

And 4 bits from an ADC? Really? 16 steps of resolution. Usually makes no sense.

SD card: you need to read SD card protocol, about file systems, data frames ....

Klaus
 

LaTeX Commands Quick-Menu:

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Top