Skip to main content
Graduate
January 20, 2025
Solved

Trouble with ADC accuracy

  • January 20, 2025
  • 3 replies
  • 7917 views

I am using the ADC on a Nucleo-L412KB board.   I am setting up the ADC for  single conversion once per second.

 

I am getting digital values which are off, as though the Vref is up around 3.4 V.  I have an LM385 voltage reference as a source and have tried a precision bench supply (Power Designs 2005) and with either input, working the math backwards, it is as though Vref is about 100 mV off.

 

I have read AN2834.  This is a simple "get acquainted" exercise, with the board right out of the box.

 

Is there sometihng I could be overlooking?  Am I required to set up Vref?  Or is this handled by default with the HAL initialization?

 

Clyde

    This topic has been closed for replies.
    Best answer by Carl_G

    Look here https://community.st.com/t5/stm32cubeide-mcus/what-can-cause-hal-adcex-calibration-start-to-fail/td-p/103017

    I think you need to include stm32l4xx_hal_adc_ex.h

    its a bit different on the l4 than on the g0 im used to...

    3 replies

    Graduate II
    January 21, 2025

    What is your setup physically? What is your vref source? Are you using the IDE to setup the ADC or are you setting it up yourself? Are you tried changing your vref value to verify that the ADC is using the vref that you think it is?

    Clyde_SAuthor
    Graduate
    January 21, 2025

    I am using CubeIDE to set up the ADC.  The analog input is fed by short jumper wires from my packaged Voltage Calibrator device.  Vref is connected as the board comes, straight to AVDD.

    I am attaching the initialization code:

     

    static void MX_ADC1_Init(void)
    {
    
     /* USER CODE BEGIN ADC1_Init 0 */
    
     /* USER CODE END ADC1_Init 0 */
    
     ADC_MultiModeTypeDef multimode = {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_DIV64;
     hadc1.Init.Resolution = ADC_RESOLUTION_12B;
     hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
     hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
     hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
     hadc1.Init.LowPowerAutoWait = DISABLE;
     hadc1.Init.ContinuousConvMode = DISABLE;
     hadc1.Init.NbrOfConversion = 1;
     hadc1.Init.DiscontinuousConvMode = DISABLE;
     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 the ADC multi-mode
     */
     multimode.Mode = ADC_MODE_INDEPENDENT;
     if (HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != HAL_OK)
     {
     Error_Handler();
     }

     

    Graduate II
    January 21, 2025

    What's your input impedance? What speed are you running your conversions at? Also, have you tried multiple conversions in a row and do they all come up with the same low value? Do you have any input filter since you do not seem to be doing any oversampling or averaging? 

    Also, are we talking about the raw number that the ADC captures? Or are you doing math on it first?

    Have you called

    HAL_ADCEx_Calibration_Start(hadcin);

    Prior to starting the sampling? 

    Clyde_SAuthor
    Graduate
    January 21, 2025

    I have tried two different input devices, the calibrator, which is a shunt regulator at 1.235 V, bypassed with 1 uF, IIRC. In reading other posts, it made me question the drive impedance, so I used the bench supply, adjustable to the 100 uV.  Either test input is about the same.

     

    The LSBs move around a bit, but if I do the math with 3.3 V as the value for Vref, it jumps around +1/-4 mV.  

     

    I think my input is very stable and quiet, so I don't think noise is the issue.  I also tried the Nucleo-L4A6ZG and the same code, with the same result. (That is why I tried the L412KB.)  I was convinced it was Vref, but I measured Vref=VADD=3.305 V.   This is why I asked if I was missing something in the configuration.  This should not be very hard to get correct, in my opinion.  Thanks.

     

    Oh, I cannot get the calibration function to compile.

    Carl_GAnswer
    Graduate II
    January 21, 2025

    Look here https://community.st.com/t5/stm32cubeide-mcus/what-can-cause-hal-adcex-calibration-start-to-fail/td-p/103017

    I think you need to include stm32l4xx_hal_adc_ex.h

    its a bit different on the l4 than on the g0 im used to...

    Clyde_SAuthor
    Graduate
    January 21, 2025

    Thank you.  I believe you are correct in the include file is needed.  I will give it  a shot today.

     

    Clyde