cancel
Showing results for 
Search instead for 
Did you mean: 

NUCLEO-H743ZI2, Sampling low frequency signal with high ADC sampling rate causes gaps, glitches.

JJ.5
Associate III

Hello,

I'm currently using the ADC on the NUCLEO-H743ZI2 board to sample a low frequency sine wave signal.

The ADC is configured to DMA, circular buffer, continuous sampling mode and oversampling ratio of 4 with 2 bits shift.

When I set the ADC sampling rate to 250KHz and the sine wave signal is 100Hz.

Here is the sampled signal I got:

JJ5_0-1687644290255.png

 

When I reduced the ADC sampling rate to 125KHz, the sampled data is correct:

JJ5_1-1687644471198.png

Does anyone know what's causing this?

Do I have to reduce the sampling rate?

 

1 ACCEPTED SOLUTION

Accepted Solutions

 

CDC_Transmit_FS((uint8_t*)&adc_buf[BUF_LEN_HALF], BUF_LEN_HALF*2);

 

You are probably hitting the USB FS transfer capability limit.

JW

View solution in original post

13 REPLIES 13

Looks like an error in the method how you read out the DMA buffer.

Try sawtooth signal instead of sine.

JW

JJ.5
Associate III

 

 

Thanks for the reply.

I can't generate a sawtooth signal.

But I have verified the data in the DMA buffer is glitched instead of the read method.

Here is the graph by reading the u16_t value directly from the DMA buffer.

The input sine wave is 2KHz and the sampling rate is 350KHz

JJ5_0-1687730979343.png

I'm not sure it's the issue of high sampling rate, it's only taking 175 samples per period of input signal.

I also checked the input signal is a normal 2KHz sine wave using oscilloscope.

MasterT
Lead

What is  Priority of the DMA channel?

To debug, I always do set-reset IO pin  inside half/ full/ complete dma interrupt, than oscilloscope shows if sampling frequency is correct.

void DMA1_Stream1_IRQHandler(void)
{
  HAL_GPIO_WritePin(GPIOD, GPIO_PIN_15, GPIO_PIN_SET);  
  //  HAL_DMA_IRQHandler(&hdma_adc1);  
  HAL_DMA_IRQHandler(hadc3.DMA_Handle);  
  HAL_GPIO_WritePin(GPIOD, GPIO_PIN_15, GPIO_PIN_RESET);  
}

void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc)
{
  flag_adcv = 1;
  //  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_SET);  

//  SCB_InvalidateDCache_by_Addr((uint32_t *) &inp[       0], 2*SIZE_FFT);
  //  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_RESET);  
}

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
  flag_adcv = 2;
  //  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, GPIO_PIN_SET);  
  
//  SCB_InvalidateDCache_by_Addr((uint32_t *) &inp[SIZE_FFT], 2*SIZE_FFT);
  //  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, GPIO_PIN_RESET);  
}

 

Thanks for the suggestion.

Both DMA priority are set to low.

I am using DMA 1 Stream 0 for ADC and DMA 2 Stream 0 for DAC.

Right now, DAC is producing the sine wave signal gets feed to the ADC input. 

I also did use the HAL_GPIO_WritePin() in half callback and complete callback to check the sampling frequency is correct.

--------------------------------------------------------------------------------

I just found that when I reduce the functions inside the half and complete callback.

The ADC is less likely to produce the glitch. Below is the code and graph.


 

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
	CDC_Transmit_FS((uint8_t*)&adc_buf[BUF_LEN_HALF], BUF_LEN_HALF*2);
	adc_buf_counter++;

	for(int i=0; i<BUF_LEN_HALF; i++)
	{
		float val = (float)adc_buf[i+BUF_LEN_HALF];
		DSP_buf1[i] = val;
	}
	arm_scale_f32(...);
	arm_biquad_cascade_df1_f32(...);
	arm_biquad_cascade_df1_f32(...);
	arm_mult_f32(...);
	arm_mult_f32(...);
	arm_add_f32(...);
	arm_scale_f32(...);
	arm_mean_f32(...);
	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_RESET);
}

 

JJ5_0-1687742693333.png

 

 

 

 

 

With less functions:

 

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
	CDC_Transmit_FS((uint8_t*)&adc_buf[BUF_LEN_HALF], BUF_LEN_HALF*2);
	adc_buf_counter++;

	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_RESET);
}

 

Glitches are less likely to occur, but they are still there.

 

LCE
Principal

It looks like you are doing a little bit too much in the callbacks, so that the buffers are filled while you are still working with them.

Try to increase DMA buffer size, reduce calculations, maybe even try to use DMA's double buffer mode.

 

CDC_Transmit_FS((uint8_t*)&adc_buf[BUF_LEN_HALF], BUF_LEN_HALF*2);

 

You are probably hitting the USB FS transfer capability limit.

JW

I am using USB2.0 cable and USB2.0 port. The transfer speed should reach 12Mbits/s. 

And I'm only sending 32bits in roughly 200Ksamples/s to 300Ksamples/s, which shouldn't exceed 12Mbits/s.

I will double check the transfer.

Thank you.

victagayun
Senior III

Is this board with STlinkV3? IT can reach 15Mbps thru UART.