cancel
Showing results for 
Search instead for 
Did you mean: 

Measuring battery level by ADC, but level is changing by other adc channel

Min-Kyoung Kim
Associate III

I'm using ADC1 of STM32L452CC.

Multi ADCs are connected to 2 Potentiometers and battery level port on ADC1.

2 Potentialmeters are connected to channel 5(PA0) and 6(PA1). (pin10, pin 11)

And battery is connected to channel 16(PB1) like below.(pin 19)

0693W00000UFHorQAH.png

However the battery level ADC value is changed continuously when other ADC value is changing.

Like below, (other adc value is flow : x , battery value is battery : x)

shutoff : 0   flow : 1   battery : 2076   

shutoff : 0   flow : 1   battery : 2067   

shutoff : 0   flow : 1   battery : 2069   

shutoff : 0   flow : 1   battery : 2069   

shutoff : 0   flow : 0   battery : 2068   

shutoff : 0   flow : 1497   battery : 2148   

shutoff : 0   flow : 2234   battery : 2271   

shutoff : 0   flow : 2568   battery : 2285   

shutoff : 0   flow : 2812   battery : 2294   

shutoff : 0   flow : 3058   battery : 2301   

shutoff : 0   flow : 3146   battery : 2307   

shutoff : 0   flow : 3148   battery : 2308   

shutoff : 0   flow : 3145   battery : 2308   

I attached the source.

static void MX_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
  */
  hadc1.Instance = ADC1;
  hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV4;
  hadc1.Init.Resolution = ADC_RESOLUTION_12B;
  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
  hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  hadc1.Init.LowPowerAutoWait = DISABLE;
  hadc1.Init.ContinuousConvMode = DISABLE;
  hadc1.Init.NbrOfConversion = 3;
  hadc1.Init.DiscontinuousConvMode = ENABLE;
  hadc1.Init.NbrOfDiscConversion = 3;
  hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc1.Init.DMAContinuousRequests = DISABLE;
  hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
  hadc1.Init.OversamplingMode = DISABLE;
  if (HAL_ADC_Init(&hadc1) != HAL_OK)
  {
    Error_Handler();
  }
 
  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_5;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLETIME_47CYCLES_5;
  sConfig.SingleDiff = ADC_SINGLE_ENDED;
  sConfig.OffsetNumber = ADC_OFFSET_NONE;
  sConfig.Offset = 0;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
 
  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_6;
  sConfig.Rank = ADC_REGULAR_RANK_2;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
 
  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_16;
  sConfig.Rank = ADC_REGULAR_RANK_3;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN ADC1_Init 2 */
 
  /* USER CODE END ADC1_Init 2 */
 
}
 
 
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
	static uint8_t adcIndex = 0;
	static uint32_t adc_temp[3];
 
	adc_temp[adcIndex] = HAL_ADC_GetValue(&hadc1);
 
	if(adcIndex == 2)
	{
		adc_value[adc_SHUTOFF] = adc_temp[0];
		adc_value[adc_FLOW] = adc_temp[1];
		adc_value[adc_BATTERY] = adc_temp[2];
	}
 
	adcIndex++;
	if(adcIndex > 2)
	{
		adcIndex = 0;
	}
 
	HAL_ADC_Start_IT(&hadc1);
}

3 REPLIES 3
Peter BENSCH
ST Employee

Well, you have connected the ADC input to a voltage divider with two resistors of 1Mohms, which is definitely too high impedance and greatly facilitates interference. The data sheet of the STM32L452 mentions the maximum input impedance for RAIN = 50kohms.

If you really need to measure at high impedance, it is best to use an opamp as a voltage follower to drive the ADC input.

Regards

/Peter

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
QSHAO.1
ST Employee

Normally, the ADC value is based on both input and Vref. so I think you may check if any impact from Vref. in another side, the output voltage of battery may be changed if the load was changed (from potentiometer) on your board. ​

I could solve the problem changing two resistors.

Next, I should use an opamp. thank you ​