cancel
Showing results for 
Search instead for 
Did you mean: 

High speed ADC conversion and data transmission via virtual com port

RYe.2
Associate II

Microcontroller newbie here. I currently use an STM32F411 MCU.

For every cycle of 500μs, I need to: 1-perform ADC conversion for 200μs at a high sampling rate (obtaining at least 300-400 samples in that timeframe); and 2-Transfer the ADC data to a computer using the virtual com port.

What would be the most reliable approach to accomplish this?

Up until now, I am able to: 1-use DMA to store ADC data with a sampling rate of 4MSamples/s; 2-use the "CDC_Transmit_FS" function to send random stuff through the com port.

Thank you for your reply!

8 REPLIES 8
S.Ma
Principal

The other way would be cube monitor loading data throught swd link. Learning curve for the sw tool required, so estimate its ROI (is it worth it)

TDK
Guru

So 400 uint16_t values every 500us. That's 12.8 Mbps.

Too much for USB FS by quite a bit, but potentially doable with USB HS if you can code things well.

Create a large, flexible buffer for the data that is resilient against hiccups in USB, send it out ASAP when the peripheral is free. Send out large chunks in multiples of the packet size (64 or 512) for highest efficiency and use DMA to do so.

Note that the VCP will need to be direct and not via UART, as the baud rates are not nearly enough to support that bandwidth.

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

Seems you are newbie in math too.

400x16 maybe reduced 400x12bit ADC = 4800b every 0,5 ms = 9,6Mbps

Virtual COM maybe 10x slower (980k) then your repeat time can be 5ms ...

RYe.2
Associate II

Thank you for your super prompt reply! I will look into it.

RYe.2
Associate II

Thank you TDK for your very thorough answer!

I read that USB FS has a rate of 12 Mbit/s (?), that's why I thought it might be possible to transmit the data fast enough.

Yes! It would seem so haha!

Thank you very much for the info!

It has a clock rate of 12 MHz, yes. That is not the data transfer rate. Overhead and latency in handling communications cuts into it quite a bit.
If you feel a post has answered your question, please click "Accept as Solution".
RYe.2
Associate II

I’m super grateful for all your insightful answers!

Before I had the chance to try your suggestions, I quickly attempted the following in my main.c file:

/* USER CODE BEGIN PV */

uint16_t adc_buf[400];

/* USER CODE END PV */

/* USER CODE BEGIN 0 */

extern uint8_t CDC_Transmit_FS(uint16_t* Buf, uint16_t Len);

/* USER CODE END 0 */

int main(void)

{

 /* USER CODE BEGIN 2 */

 HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adc_buf, 400);

 /* USER CODE END 2 */

}

… // (near the end of my main.c file)

/* USER CODE BEGIN 4 */

// Called when buffer is full

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) {

      HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);

      CDC_Transmit_FS(adc_buf,sizeof(adc_buf));

      HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);

}

/* USER CODE END 4 */

This is the signal from my GPIO pin C13 via a probe (see figure below, I had peaks around every 100us):

0693W00000KbqSGQAZ.jpgHowever, I see a constant flow of gibberish from my COM port, something like: “D@=EC>EE;@F=;HD9AG;<IB:DEGE99CEFNH9<A>�?

When I connect my ADC pin to ground, the flow of gibberish stops (meaning it is transmitting zeros?).

And when I connect my ADC pin to 3.3V, I get a constant flow of this symbol (denoting max voltage?): ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒

Nevertheless, when I pause my script in CubeIDE, I do see my buffer with ADC values:

0693W00000KbqT9QAJ.pngWould you say that I’m getting closer to my objective? I’m not exactly sure what is wrong with my code.

Thank you so much!