cancel
Showing results for 
Search instead for 
Did you mean: 

STM32WB Multi-channel ADC with DMA, buffer sequence issue

Hello geeks..

Hope all are doing well

I'm using multi channel ADC with STM32WB having DMA activated

My issue is, every time when i perform the power ON reset, at the same time the channel sequence getting change!

It means, the conversion buffer in HAL_ADC_ConvCpltCallback function sequence is getting change

I have verified the same thing manually by connecting the 3.3V & GND at the particular channels

For example, when i connect the 3.3v at PC4 then the allocated buffer variable shows 4096 samples. However when i do the power on reset then some different buffer shows the value 4096

I have activated the 6 channels here with DMA

I have shared ADC initialization code snippet here

Can any one help me here ?

All suggestions & comments welcome

Thanks

0693W00000FD0mfQAD.png 

/**
 * @brief ADC1 Initialization Function
 * @param None
 * @retval None
 */
int32_t BSP_ADC1_Init(void) {
 
	/* USER CODE BEGIN ADC1_Init 0 */
 
	/* USER CODE END ADC1_Init 0 */
 
	ADC_ChannelConfTypeDef sConfig = { 0 };
 
	/* USER CODE BEGIN ADC1_Init 1 */
 
	/* USER CODE END ADC1_Init 1 */
	/** Common config
	 */
	hgasadc1.Instance = ADC1;
	hgasadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV6;
	hgasadc1.Init.Resolution = ADC_RESOLUTION_12B;
	hgasadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
	hgasadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
	hgasadc1.Init.EOCSelection = ADC_EOC_SEQ_CONV;
	hgasadc1.Init.LowPowerAutoWait = DISABLE;
	hgasadc1.Init.ContinuousConvMode = ENABLE;
	hgasadc1.Init.NbrOfConversion = 6;
	hgasadc1.Init.DiscontinuousConvMode = DISABLE;
	hgasadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
	hgasadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
	hgasadc1.Init.DMAContinuousRequests = ENABLE;
	hgasadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
	hgasadc1.Init.OversamplingMode = DISABLE;
	if (HAL_ADC_Init(&hgasadc1) != HAL_OK) {
		Error_Handler();
	}
	/** Configure Regular Channel
	 */
	sConfig.Channel = ADC_CHANNEL_10;
	sConfig.Rank = ADC_REGULAR_RANK_1;
	sConfig.SamplingTime = ADC_SAMPLETIME_2CYCLES_5;
	sConfig.SingleDiff = ADC_SINGLE_ENDED;
	sConfig.OffsetNumber = ADC_OFFSET_NONE;
	sConfig.Offset = 0;
	if (HAL_ADC_ConfigChannel(&hgasadc1, &sConfig) != HAL_OK) {
		Error_Handler();
	}
	/** Configure Regular Channel
	 */
	sConfig.Channel = ADC_CHANNEL_13;
	sConfig.Rank = ADC_REGULAR_RANK_2;
	if (HAL_ADC_ConfigChannel(&hgasadc1, &sConfig) != HAL_OK) {
		Error_Handler();
	}
	/** Configure Regular Channel
	 */
	sConfig.Channel = ADC_CHANNEL_14;
	sConfig.Rank = ADC_REGULAR_RANK_3;
	if (HAL_ADC_ConfigChannel(&hgasadc1, &sConfig) != HAL_OK) {
		Error_Handler();
	}
	/** Configure Regular Channel
	 */
	sConfig.Channel = ADC_CHANNEL_15;
	sConfig.Rank = ADC_REGULAR_RANK_4;
	if (HAL_ADC_ConfigChannel(&hgasadc1, &sConfig) != HAL_OK) {
		Error_Handler();
	}
	/** Configure Regular Channel
	 */
	sConfig.Channel = ADC_CHANNEL_9;
	sConfig.Rank = ADC_REGULAR_RANK_5;
	if (HAL_ADC_ConfigChannel(&hgasadc1, &sConfig) != HAL_OK) {
		Error_Handler();
	}
	/** Configure Regular Channel
	 */
	sConfig.Channel = ADC_CHANNEL_16;
	sConfig.Rank = ADC_REGULAR_RANK_6;
	if (HAL_ADC_ConfigChannel(&hgasadc1, &sConfig) != HAL_OK) {
		Error_Handler();
	}
	/* USER CODE BEGIN ADC1_Init 2 */
 
	/* USER CODE END ADC1_Init 2 */
 
}

/**
 * @brief  Conversion complete callback in non-blocking mode.
 * @param hadc ADC handle
 * @retval None
 */
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc) {
	if (hadc->Instance == ADC1) {
		adc_0 = AdcRawSamples[0]; /*  -> PC4 -> BSP_GM_402B_CHANNEL */
		adc_1 = AdcRawSamples[1]; /*  -> PC5 -> BSP_GM_512B_CHANNEL */
		adc_2 = AdcRawSamples[2]; /*  -> PA8 -> BSP_GM_702B_CHANNEL */
		adc_3 = AdcRawSamples[3]; /*  -> PA9 -> BSP_TGS8100_CHANNEL */
		adc_4 = AdcRawSamples[4]; /*  -> PA4 -> BSP_GM_802B_CHANNEL */
		adc_5 = AdcRawSamples[5]; /*  -> PA5 -> BSP_GM_502B_CHANNEL */
	}
}

1 ACCEPTED SOLUTION

Accepted Solutions
TDK
Guru

> All the channels are floating expect the channel that I'm testing with 3.3V

> However by connecting the GND to very next channels shows the batter result

Measuring the voltage of an infinite impedance source (open circuit) is not useful. If you want it to be 0V when open, you'll need a pulldown resistor.

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

View solution in original post

6 REPLIES 6
TDK
Guru

I don't think there's an issue in the code you've shown. I would imagine there's a bug somewhere else, perhaps in how you're calling HAL_ADC_Start*.

Note that 6 samples don't fit evenly into a buffer of 4096.

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

Hi.. @TDK​ 

Thanks for your feedback

You're right!

Actually, I'm using the BLE Stack to send the Analog sensors data to android app with custom GATT services

I was triggering the DMA of the ADC when user start the services from the app and stopping it when user stop the services

The issue with the stop api that i was using previously

Instead of the stopping the DMA, i was stopping the ADC by calling HAL_ADC_Stop

So, when again user trigger the GATT services from smart phone then,, HAL_ADC_Start_DMA calling which was failing as the ADC engine went off from the previous cycle

Adding the HAL_ADC_Stop_DMA api to stop the adc has been solved the issue

However, one strange thing that i have Noticed here,

When i changing the ADC voltage of the one channel then, it's also affecting the very next channel !!

Normally, the very next channel show 340 samples at open circuit condition, however when i touch to the 3.3V to the previous channel at whom i need to sense, it's affecting the next channels from 340 to above 1000 !

Any advice ?

Thanks

TDK
Guru

> When i changing the ADC voltage of the one channel then, it's also affecting the very next channel !!

> Normally, the very next channel show 340 samples at open circuit condition, however when i touch to the 3.3V to the previous channel at whom i need to sense, it's affecting the next channels from 340 to above 1000 !

You shouldn't see that much variation. Is the channel floating or at a very high impedance? What happens if you directly ground it?

The ADC has a single sampling capacitor. For higher impedance sources, increasing the sampling time can help.

https://www.st.com/resource/en/application_note/cd00211314-how-to-get-the-best-adc-accuracy-in-stm32-microcontrollers-stmicroelectronics.pdf

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

Hi.. @TDK​ 

All the channels are floating expect the channel that I'm testing with 3.3V

However by connecting the GND to very next channels shows the batter result

The near by channel floating between 0-1 samples

I got your point

Thanks for the Reference pdf

For now, all the issues have been solved

TDK
Guru

> All the channels are floating expect the channel that I'm testing with 3.3V

> However by connecting the GND to very next channels shows the batter result

Measuring the voltage of an infinite impedance source (open circuit) is not useful. If you want it to be 0V when open, you'll need a pulldown resistor.

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

sure.. Thanks