0

Using the Arduino Mini Pro 3.3V I just stumbled over a problem when switching between the "INTERNAL" and "DEFAULT" voltage reference for the ADC. I want to measure the output of a voltage divider [GND - 110kOhm - A2 - 500kOhm - VCC] for calculating VCC. VCC has been measured as 3.3V. It is provided by a voltage regulator.

In the loop I firstly measure the voltage divider output with the internal reference and afterwards with the default voltage reference. I saw code examples where people recommend to wait some milliseconds before reading the next value and the (analogReference() documentation) recommends to ignore the first readings after calling analogReference(). I follow these guidlines.

I'll provide a minimum example sketch:

// the setup function runs once when you press reset or power the board
void setup()
{
  pinMode(A2, INPUT);    // ADC pin
  Serial.begin(9600);
  Serial.println("----------------");
}

void burn8Readings(int pin)
{
  for (int i = 0; i < 8; i++)
  {
    analogRead(pin);
  }
}

// the loop function runs over and over again forever
void loop()
{
  uint16_t nResult1, nResult2;

  analogReference(INTERNAL);    // set the ADC reference to 1.1V
  delay(10);                    // idle some time
  burn8Readings(A2);            // make 8 readings but don't use them to ensure good reading after ADC reference change

  nResult1 = analogRead(A2);    // read actual value

  analogReference(DEFAULT);     // set the ADC reference back to internal for other measurements
  delay(10);                    // idle again
  burn8Readings(A2);            // make 8 readings but don't use them to ensure good reading after ADC reference change

  nResult2 = analogRead(A2);    // do other measurements

// print result to serial interface..
  Serial.print("1: ");  
  Serial.print(nResult1);
  Serial.print(" - 2: ");
  Serial.println(nResult2);

  delay(2000);
}

The first pair of ADC results seems correct (553 / 184), but in the following iterations the first value is faulty without changing the actual voltage on the ADC pin. (240 / 183) The ADC result of the DEFAULT reference is always fine.

For a 2.56V reference the value of 240 would be feasible. I know that some ATmegas use a 2.56V reference voltage, but the ATmega328 should have 1.1V only. Strangely the (ATmega328/P datasheet) mentions a 2.56V reference in an ADC example in chapter 28.7, so I'm confused.

Is there a possibility there is a 2.56V ADC reference in a certain ATmega328p version?

12
  • 1
    Just one comment: why do you have to change the voltage reference during execution? I think that if your application requires a precise reference then you have to set it to internal for all your measures (and so set the reference in the setup and never change it) Commented Dec 19, 2016 at 16:28
  • In my minimum example sketch I just measured VCC twice. There I have to admit I don't know a reason why to switch the reference voltage. In my actual application I want to read out other sensors which act as a voltage divider between GND and VCC. Using the same VCC as reference voltage of the ADC allows me to interpret the measurements independently of the actual VCC. Commented Dec 27, 2016 at 20:00
  • and then you also have to measure something with a more stable reference.. That is totally reasonable. Thank you Commented Dec 27, 2016 at 21:05
  • Yes, the measurement with the more stable reference actually indeed is the battery VCC. I want to monitor the battery voltage as it drops. Commented Jan 2, 2017 at 9:29
  • Then can't you use the Vcc as reference voltage and measure the "stable" reference? You will get the inverse of the voltage, but with a simple mathematical operation you will get the voltage without the need of a resistor divider to get a fraction of the battery voltage Commented Jan 2, 2017 at 9:52

1 Answer 1

0

It turns out the similarity to the 2.56V was a coincidence and probably an error in the datasheet (or in my understanding). The problem was that after the analogReference(INTERNAL) call the ADC value has to be read immediately! Not after some milliseconds as I did it. (Source)

Still it is important to also wait some milliseconds after doing the dummy readout. For me one readout and delay(5) was just enough, but I guess that depends on the charge left in the capacitor of the ADC: So I'd recommend higher delays.

The correct sequence is:

  analogReference(INTERNAL);    // set the ADC reference to 1.1V
  burn8Readings(A2);            // make 8 readings but don't use them
  delay(10);                    // idle some time
  nResult1 = analogRead(A2);    // read actual value

and

  analogReference(DEFAULT);     // set the ADC reference back to internal
  burn8Readings(A2);            // make 8 readings but don't use them
  delay(10);                    // idle again
  nResult2 = analogRead(A2);    // read actual value

Changing the reference back to DEFAULT seems to be less prone...but at least one readout still was necessary for precise results.

I hope no one has to spend time on this one anymore...

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.