# Usefulness of measuring 0v using ADC

I'm looking at the datasheet of the ATMega328, and I see the different channels you can select for AD conversion. ADC0..7, ADC8 (temperature), 1.1V (VBG), and lastly 0V (GND).

• What would be the use of measuring 0V?
• Would it ever result in a reading other than `0`? I find it very intriguing.

AVR126 seems to give a hint:

configure 0V (GND) in ADC by setting Mux bitfield (MUX3:0) equal to 1111. This is done to discharge the capacitor of ADC.

Though I find the document rather strange (incomplete, lacking certain info, running the ADC at 500kHz while the datasheet says to not exceed 200kHz).

Is it to protect the ADC from to high a voltage in the ADC capacitor, when changing to a different (lower) reference voltage? Rather odd you need software to protect the IC, and it's not even mentioned in the datasheet. Also I've never seen anyone do this (e.g. when measuring the internal temperature of the ATMega).

That quote you mention says it all really. It's purpose is to discharge the Sample And Hold capacitor.

That capacitor is used (as I'm sure you are aware) to store the incoming voltage while it's being sampled by the ADC. The ADC operated in two main phases:

1. Acquisition
2. Sampling

During acquisition the capacitor is connected to the incoming voltage. During sampling it is disconnected from the incoming voltage and the voltage it stores is read into the internal registers.

It takes a certain amount of time for the voltage in the capacitor to equal that of the incoming voltage. If you try reading at higher speeds then what voltage was in the capacitor from the previous sample can affect the new reading. However, if you do each sample always from a known voltage in the capacitor (0V) then you get much more stable results.

Another good use for it is when using the ADC as a Charge Time Measurement Unit. This is the proper way of performing capacitative sensing. You apply a constant (tiny) current to an external capacitor (the sensing plates) for a specific period of time. When that time is up you disconnect the constant current source and measure the voltage that has developed across that capacitance. The capacitances and currents are small, and if there is a charge in your S&H capacitor at the time you do the sampling that will be back-fed into the touch sensor capacitative plates changing the voltage. By ensuring that the S&H capacitor is at 0V before you sample the plates you won't be adversely affecting the voltage on the plates with successive readings (well, you will, but it will be consistently in the same way every time so it won't affect your overall results).

• About S&H: unless one is really desperate, shouldn't the acquisition phase be such that it allows the capacitor to charge to whatever is considered precise enough for the maximum variation? Iow, taking for example Ta=5*R*C, where R is the parasitic resistance and C the capacitance, don't they pretty much set the max frequency? I'd think that if one is really desperate to the point of forcing such constraint, it would be faster to not discharge the capacitor at all, assuming that there is somewhat a correlation between successive readings. Especially if performed at high frequency. – Igor Stoppa Aug 11 '15 at 15:47
• Forcing the initial voltage on the capacitor to be 0V means that one has to always allow enough time to reach Vmax. By limiting the maximum Voltage variation, it is possible to measure at increased speed, accepting that there might be a possibly large error, depending on how much the assumption on the max DeltaV is violated. – Igor Stoppa Aug 11 '15 at 15:51
• So consistency. That makes sense. Though with the speed example, you would lose half the rate, cause you do a 0v read between every regular read. Also, if the speed speeds are high, is the sample period long enough to fully discharge the cap? – Gerben Aug 11 '15 at 15:53

Though I find the document rather strange (incomplete, lacking certain info, running the ADC at 500kHz while the datasheet says to not exceed 200kHz).

The document actually says:

The ADC can prescale the system clock to provide an ADC clock that is between 50kHz and 200kHz to get maximum resolution.

(My emphasis)

It goes on to say:

If ADC resolution of less than 10 bits required, then the ADC clock frequency can be higher than 200kHz. At 1MHz it is possible to achieve eight bits of resolution maximum.

I did some testing on this page with different prescalers. The results showed that reasonable results could be obtained even with a 1 MHz ADC clock:

``````Prescaler 2

Analog port = 0, average result = 1023
Analog port = 1, average result = 1023
Analog port = 2, average result = 1023
Analog port = 3, average result = 1022
Time taken = 26220

Prescaler 4

Analog port = 0, average result = 673
Analog port = 1, average result = 718
Analog port = 2, average result = 512
Analog port = 3, average result = 193
Time taken = 32780

Prescaler 8

Analog port = 0, average result = 842
Analog port = 1, average result = 677
Analog port = 2, average result = 509
Analog port = 3, average result = 34
Time taken = 46040

Prescaler 16

Analog port = 0, average result = 1022
Analog port = 1, average result = 672
Analog port = 2, average result = 509
Analog port = 3, average result = 0
Time taken = 73164

Prescaler 32

Analog port = 0, average result = 1022
Analog port = 1, average result = 672
Analog port = 2, average result = 508
Analog port = 3, average result = 0
Time taken = 128040

Prescaler 64

Analog port = 0, average result = 1022
Analog port = 1, average result = 672
Analog port = 2, average result = 508
Analog port = 3, average result = 0
Time taken = 240972

Prescaler 128

Analog port = 0, average result = 1022
Analog port = 1, average result = 672
Analog port = 2, average result = 508
Analog port = 3, average result = 0
Time taken = 448108
``````

The four test voltages were, and their results should have been:

• 5V (should return 1023)
• 3.3V (should return 674)
• 2.5V (should return 511)
• 0V (should return 0)

The tests were done in rapid succession, no allowing for the ADC to recharge or anything:

`````` unsigned long startTime = micros ();
for (int i = 0; i < ITERATIONS; i++)
{
for (int whichPort = lowPort; whichPort <= highPort; whichPort++)
{