cancel
Showing results for 
Search instead for 
Did you mean: 

Error on the ADC Values of a Multichannel ADC

BoboyeOkeya
Associate III

Hi All,

I am presently measuring the two signals below through a multichannel adc that is triggered by the rising edge of a PWM signal on TIM1 CH4.

a. Inverter return line current on channel 3

b. Speed reference value from a potentiometer.

I am quite sure, I am reading the right adc channel, but the problem is that the adc value for the current seems to be corrupted and it jitters too much from the correct value.

Below is the configuration code for the ADC

static void MX_ADC_Init(void)
{
 
  /* USER CODE BEGIN ADC_Init 0 */
 
  /* USER CODE END ADC_Init 0 */
 
  ADC_ChannelConfTypeDef sConfig = {0};
 
  /* USER CODE BEGIN ADC_Init 1 */
 
  /* USER CODE END ADC_Init 1 */
  /** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) 
  */
  hadc.Instance = ADC1;
  hadc.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
  hadc.Init.Resolution = ADC_RESOLUTION_12B;
  hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;
  hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  hadc.Init.LowPowerAutoWait = DISABLE;
  hadc.Init.LowPowerAutoPowerOff = DISABLE;
  hadc.Init.ContinuousConvMode = DISABLE;
  hadc.Init.DiscontinuousConvMode = DISABLE;
  hadc.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_TRGO;
  hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
  hadc.Init.DMAContinuousRequests = DISABLE;
  hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED;
  if (HAL_ADC_Init(&hadc) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure for the selected ADC regular channel to be converted. 
  */
  sConfig.Channel = ADC_CHANNEL_5;
  sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
  sConfig.SamplingTime = ADC_SAMPLETIME_13CYCLES_5;
  if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure for the selected ADC regular channel to be converted. 
  */
  sConfig.Channel = ADC_CHANNEL_3;
  if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
//  /** Configure for the selected ADC regular channel to be converted. 
//  */
//  sConfig.Channel = ADC_CHANNEL_8;
//  if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
//  {
//    Error_Handler();
//  }
//  /** Configure for the selected ADC regular channel to be converted. 
//  */
//  sConfig.Channel = ADC_CHANNEL_9;
//  if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
//  {
//    Error_Handler();
//  }
//  /** Configure for the selected ADC regular channel to be converted. 
//  */
//  sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;
//  if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
//  {
//    Error_Handler();
//  }
//  /** Configure for the selected ADC regular channel to be converted. 
//  */
//  sConfig.Channel = ADC_CHANNEL_VREFINT;
//  if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
//  {
//    Error_Handler();
//  }
  /* USER CODE BEGIN ADC_Init 2 */
 
  /* USER CODE END ADC_Init 2 */
 
}

Also, since the application -- a bldc trapezoidal current and speed control -- I am running is kinda complex. The ADC is calibrated and started at other parts of the code.

But the main problem i think is the fact that the adc values get corrupted. I wrote another code the see the right ADC value that matches the inverter DC line current and it was totally different from what I get when I run my bldc control application.

What could possible be wrong?

4 REPLIES 4
cedric H
ST Employee

Hello @BoboyeOkeya​ 

Could you describe your setup.

What MCU, and boards do you use ?

Excepting cubeMX init code, do you use Motor control library coming from ST ?

Thanks

Cedric

BoboyeOkeya
Associate III

Hi cedric, The mcu is STM32F031x6x7 which is embedded in STSPIN32F0251 a three-phase controller. And I am using the evaluation board EVSPIN32F0251S1.

I used some of the functions from the particular software stsw-spin32f0251 . However, I repurposed some of the functions to suit my application especially the removal of the part that uses the output of the comparator that compares the current reference and current feedback to clear the gate PWM timers.

I think I might be missing something in the adc configuration I guess. I checked online already and maybe I need to insert a delay function somewhere to prevent the adc values from being corrupted but it ended up not reading any value at all? or is there any other possible solution?

cedric H
ST Employee

Hi,

The ADC of the STM32F0 contains regular channels only. So the read of two different channels in a Raw must be done with the support of the DMA otherwise the second conversion will erase the first one. I do not know if this is something you took into account.

Unfortunately, the ST motor control team will not be able to help you more, debugging custom code is beyond what we can do.

I hope the community will be able to help you.

Regards

Cedric

Hi,

Okay now I have a lot of questions, pardon me, my background is in Power electronics not embedded systems.

First, what is a regular channel? And why would the second conversion erase the first one?

I dont think it does though because I get two seperate adc values, just that the first one seems to be incorrect as shown in this picture below

0693W00000FBNqCQAX.png 

Will it still be possible to trigger the ADC to start converting by using a PWM signal from another timer if I use the DMA method? I am asking because my application requires me to sample the current value only in the middle of the gate PWM signal ON-time. And the DMA method seems to continously sample at all times?