I want to read two voltages of different ranges with an ATmega328P ADC with the highest resolution possible:

  1. The 1st signal varies from 0 to 1V. It's the output of an LM35DZ Temperature Sensor. I wanted to use the internal 1V analog reference to get the highest ADC resolution possible.

  2. The 2nd signal is the battery voltage, that varies from 0 to 5V. I feed it to this Over-Discharge Protection circuit that Russell McMahon proposed and based on that reading, it will turn off the circuit if battery levels are too low. To read this signal, I have to use the ADC 5V voltage reference.

My questions are:

  1. Is it ok if I keep changing the ADC voltage reference from the internal 1V to the 5V reference to make one read then the other?

  2. When I switch to 1V internal reference, will the other 5V signal damage the other analog input? I got the impression that the 1V reference would be a limit for the ADC and the 5V on the other input would somehow violate this.

  3. I actually tried to switch between 1V and 5V reference, but when I do it, the reading of the 1st signal (with 0 to 1V range) starts fluctuating. Why is that? I tried giving the ADC time to settle (10 to 50 ms), but that didn't work. How do I get a stable reading after switching the analog reference?


3 Answers 3

  1. No problem at all.
  2. No.
  3. Take multiple readings and average them. Also, the internal voltage reference isn't wonderfully stable. Better to use an external voltage reference chip. I often use an MCP4821 / MCP4822 DAC chip so I can program a precise voltage reference down to 500µV resolution.

Another option is to build a simple resistive divider for the higher voltage input to divide it down to the ADC range. This way, even if the voltage is higher than the supply voltage for the part (say, sourced from before the voltage regulator) you can still get a good read on the voltage. The downside to this is that you may have to worry about the resistor tolerances and temperature coefficients if you need extreme precision. This method also allows you to read all of the input signals with the same (possibly very high precision) reference.


From the data sheet:

AVCC or an internal 1.1V reference voltage may be connected to the AREF pin by writing to the REFSn bits in the ADMUX Register. The internal voltage reference may thus be decoupled by an external capacitor at the AREF pin to improve noise immunity.

Also make sure you follow this:

By default, the successive approximation circuitry requires an input clock frequency between 50kHz and 200kHz to get maximum resolution.

And this:

When the bandgap reference voltage is used as input to the ADC, it will take a certain time for the voltage to stabilize. If not stabilized, the first value read after the first conversion may be wrong.

Just to elaborate a bit of the last quote from the datasheet... As you can see Atmel do not give you an exact figure for how long this "certain time" is. The simple reason for this is that it depends on your voltage, what cap you used to decouple AREF and probably system temp. along with other factors. What I did at the time was to take several readings and when the absolute difference between 10 consecutive reading was below a certain delta I decided the reference was stabilized. Of course this was using a constant DC input, otherwise it wouldn't make much sense. Another, simpler approach is to take a scope and sample the AREF pin. You should be able to trigger the scope on another pin at the moment you swap the voltage references and then measure how long does it take for the signal to stabilize. After you have this figured out you can set a delay in your code right after reference switching.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.