# ADC doesn't start from 0V

I have a STM32L053-Disco eval board, and I'm building a capacitance meter. For it to work, I have to calculate the charge time on my capacitor. The approach that I'm taking is to set 1 GPIO pin to output and for ADC to read it and then calculate. The issue is my ADC doesn't measuring from zero, when my GPIO pin is reset, the values that I'm getting are around 0.05V and I can't get it to drop to 0.00V. Any ideas why that could be happening? This is my circuit:

And here is some code:

while (1)
{
// Get ADC value
//

HAL_ADC_Start(&hadc);
HAL_ADC_PollForConversion(&hadc, 1000);
HAL_ADCEx_Calibration_Start(&hadc,4096);
raw = HAL_ADC_GetValue(&hadc);

//  HAL_COMP_Start(&hcomp1);
real = (raw*3.3)/4096;
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);

//      status == HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);

if(real >= 0.117*0.632)
{
HAL_ADC_Stop(&hadc);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
time2 = HAL_GetTick();
}
if(real <= 0)

{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);

time1 = HAL_GetTick();
}

time3 = (time2 - time1)/1000;
c = time3/res;
// Convert to string and print
sprintf(TxBuffer,"%7.3f V\n", real);
HAL_UART_Transmit(&huart1, (uint8_t*)TxBuffer, strlen(TxBuffer), HAL_MAX_DELAY);

}

}


Also I think my ADC for some reason doesn't reset, because here are the values that I get:

When it reaches 62.3% it just stops there and doesn't reset, even if in the code I wrote HAL_ADC_STOP()

New contributor
Rexepo LT is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
• Welcome! Are you applying voltage straight to the ADC or do you have any opamp buffer or similar in between? May 10 at 14:53
• It would be helpful to have a schematic. See electronics.stackexchange.com/q/105136/2028 May 10 at 15:21
• I haven't read the other question for context and I'm not reading the code. The output just looks to me like standard analog offset that needs to be used for an offset calibration step. I can't explain the "when it reaches 62.3% it just stops there" part. But I can't say I exactly understand that comment. Why isn't this just offset? What am I missing in a short few seconds of scanning?
– jonk
May 10 at 17:10
• As indicated by JYelton, please add a proper schematic. A picture of the circuit is a so-so help. Also, explain what 62.3% mean. Percent of what? And your main while(1) loop starts ADC every time it's stopped. Because it starts it first and only then checks if it needs to stop. You may want to use a global variable as a flag to define if you need to start ADC at all (or find some better way without those pesky global variables)
– Ilya
May 10 at 17:15
• What value is that resistor? What happens if you short the ADC input directly to ground? Why do you care about the value not being exactly zero on reset? May 10 at 18:43

## 1 Answer

1M$$\\Omega\$$ is too high for the on-chip ADC source impedance (it depends on how you are using the ADC, and the information is in the MCU datasheet, I'm not going to evaluate how you are using it, that's your job), but regardless of how you use it more than 50k$$\\Omega\$$ source impedance is not recommended and often considerably less.

Try applying a voltage directly to the ADC input. Try applying a voltage with a series resistor. And try applying a voltage with a series resistor and capacitor to ground (10nF in your case).

Maybe you can use a CMOS-input rail-to-rail op-amp voltage follower/buffer and connect the op-amp output to the ADC input.

It's not realistic to expect the ADC to necessarily go right to 0V depending on how you are using it (especially with such a high source impedance, but even an op-amp buffer will have a bit of offset voltage and the output won't be able to go right to the rail exactly - and the ADC itself may not read exactly accurately).