Skip to main content
aamirali641989
Associate III
June 20, 2013
Question

ADC, sampled values shows large changes if sampled continuously

  • June 20, 2013
  • 12 replies
  • 1695 views
Posted on June 20, 2013 at 13:24

I am using PB0 - ADC2-IN8, as analog input with 10K source impdence. I have configured the pin and sampled continuosly. Values shown shows gradual decrease if delay not added b/w two samples. I am using software control/single conversion method.

below is my code:

main()

{

    GPIO_InitTypeDef        GPIO_InitStruct;

    ADC_CommonInitTypeDef   ADC_CommonInitStruct;    

    ADC_InitTypeDef         ADC_InitStruct;

    

/* Configure ADC2 for keypad adc, PB0 (IN8) */    

    /* Enable clock to ADC2 */     

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE);           

    /*Enable  the AHB1 peripheral clock for portB & configure for ADC */

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);

GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;

GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AN;

GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;

GPIO_Init(GPIOB, &GPIO_InitStruct);    

    

/* configure global parameters */    

    ADC_CommonInitStruct.ADC_Mode              =  ADC_Mode_Independent;         /* ADC1,ADC2,ADC3 operate independently */

    ADC_CommonInitStruct.ADC_Prescaler         =  ADC_Prescaler_Div2;           /* ADC freq = 30Mhz                     */

    ADC_CommonInitStruct.ADC_DMAAccessMode     =  ADC_DMAAccessMode_Disabled;   /* No DMA access                        */

    ADC_CommonInitStruct.ADC_TwoSamplingDelay  =  ADC_TwoSamplingDelay_5Cycles; /* time b/w two conversion, not used    */

    ADC_CommonInit(&ADC_CommonInitStruct);

/* ADC2 Init */

    ADC_InitStruct.ADC_Resolution           = ADC_Resolution_12b;           /* 12 bit resolution                                  */

    ADC_InitStruct.ADC_ScanConvMode         = DISABLE;                      /* Disable the scan conversion so we do one at a time */

    ADC_InitStruct.ADC_ContinuousConvMode   = DISABLE;                      /* Single conversion                                  */

    ADC_InitStruct.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;/* No external conversion                             */

    ADC_InitStruct.ADC_ExternalTrigConv     = ADC_ExternalTrigConv_T1_CC1;  /* Assign value, but not used                         */

    ADC_InitStruct.ADC_DataAlign            = ADC_DataAlign_Right;          /* data align right                                   */

    ADC_InitStruct.ADC_NbrOfConversion      = 1;                            /* Number of channled to scan = 1                     */ 

    ADC_Init(ADC2, &ADC_InitStruct);                                        /* Init the ADC                                       */

  

    ADC_RegularChannelConfig(ADC2 , 8 , 1, ADC_SampleTime_15Cycles);    

/* Enable ADC2 */

  ADC_Cmd(ADC2, ENABLE);    

    

    cnt = 0;

    while(1)

    {

        ADC_SoftwareStartConv(ADC2);

        while(ADC_GetFlagStatus(ADC2, ADC_FLAG_EOC) == RESET);

        adc_val = ADC_GetConversionValue(ADC2);

        my_arr_1[cnt++] = adc_val;

        configure_tim3_wait(1000);    /* Delay added here */

               

        if( cnt == 4800 )

        {

            __NOP(); 

            while(1);

        }    

    } 

}

Case 1:

Without using delay, when I sampled 4800 values, I saw gradual decrease from 4095(full scale) to 4000(approx) at last values.

I am writing every 500th values for reference:

my_arr_1[0]       = 4089

my_arr_1[500]   = 4029

my_arr_1[1000] = 4019

my_arr_1[1500] = 4027

my_arr_1[2000] = 4013

my_arr_1[2500] = 4063

my_arr_1[3500] = 3997

my_arr_1[4799] = 4021

case 2:

If delay is added as I marked , then values don't vary like this

 
    This topic has been closed for replies.

    12 replies

    aamirali641989
    Associate III
    June 20, 2013
    Posted on June 20, 2013 at 13:26

    delay added is in microsecond, i.e 1000us

    & CPU is running at 120mhz , ADC = 30Mhz

    John F.
    Associate III
    June 20, 2013
    Posted on June 20, 2013 at 15:20

    It sounds the ADC acquisition is disturbing the output of whatever you're measuring. The output then does not have time to settle. Try a longer ADC_SampleTime_<n>Cycles value. Have someone look at the dynamic behaviour of the output you're measuring. Can you look at it with an oscilloscope? Maybe you need to buffer it?

    Amel NASRI
    Technical Moderator
    June 20, 2013
    Posted on June 20, 2013 at 16:27

    You have to consider the total time needed for conversion including the sampling time. That is why a delay may be required.

    In F30x, there is the  ''auto-delayed conversion'' feature that provides automatic control.

    -Mayla-
    To give better visibility on the answered topics, please click on "Best Answer" on the reply which solved your issue or answered your question.
    raptorhal2
    Lead
    June 20, 2013
    Posted on June 20, 2013 at 16:42

    With a 10K input impedance, the ADC channel  sample and hold capacitor doesn't have enough time to charge up to the input voltage. You may not see this effect well on an oscilloscope. John F's solution is correct, increase the ADC sampling time from 15 cycles to some larger amount that produces acceptable accuracy, and discard the software delay.

     John F's other solution is another correct one. A buffer amplifier will reduce the source impedance to near zero.

    Cheers, Hal

    aamirali641989
    Associate III
    June 20, 2013
    Posted on June 20, 2013 at 16:58

    I am using STM32F205, I have calculated formula by datasheet & 15 cycles is fine for it. ADC cap will charge in that time. I will also try by 28 cycles or more & will see the results.

    But how can adding delay time give right results.  ADC will be sampled for same time irrespective of delay introduced.

    John F.
    Associate III
    June 20, 2013
    Posted on June 20, 2013 at 17:56

    ''I have calculated formula by datasheet & 15 cycles is fine''. Good. I was also concerned if the output of the device you're measuring was capable of driving the ADC input quickly and repeatedly. Sometimes the

    dynamic

    performance of devices is not obvious. Maybe you have some other problem ...

    Amel NASRI
    Technical Moderator
    June 20, 2013
    Posted on June 20, 2013 at 18:15

    I agree with Hal and John suggestion (Increase ADC sampling time) and invite you to have a look to

    http://www.st.com/st-web-ui/static/active/en/resource/technical/document/application_note/DM00050879.pdf

     giving other proposals on how to improve ADC accuracy.

    -Mayla-

    To give better visibility on the answered topics, please click on "Best Answer" on the reply which solved your issue or answered your question.
    aamirali641989
    Associate III
    June 21, 2013
    Posted on June 21, 2013 at 11:11

    I tried by 28 cycles, but same results were obtained. 

    aamirali641989
    Associate III
    June 21, 2013
    Posted on June 21, 2013 at 11:13

    I tried by 28 cycles, but same results were obtained. 

    frankmeyer9
    Associate III
    June 21, 2013
    Posted on June 21, 2013 at 11:31

    I tried by 28 cycles, but same results were obtained. 

     

    That is not much of a difference, better try >100 cycles instead.

    From the first post, it seems the variation is not very large, roughly +-40LSB.

    Can you confirm that the input voltage source is really stable ?

    Does your statement of ''10k impedance'' include the output impedance of the source ?

    Could it be an EMI problem ?