AREF not working?

I wanted to add an external analog reference to provide a precision voltage reference for my application. I noticed that when I am plugged into USB, my analog value read is very accurate when checked against a volt-meter. However, when I un-plug usb and use an external power supply, the analog reading is way off.

Ive confirmed the following:
(a) My analog reference is in fact 5 volts constantly (through external volt meter)
(b) My analog signal Im reading is in fact 4.84 voltage (through external volt meter)
(c) I get this same behavior on two different mega 2560 boards

Aruino Read Voltage:
With USB plugged in: 4.84 Volts
Wihtout USB plugged in: 1.48-1.54 Voltage (floating)

Since I can confirm that the voltages are correct using my volt meter, Im assuming theres something wrong in by code? Anyone seen something similiar?

#include <LiquidCrystal_I2C.h>

#define En_pin  2
#define Rw_pin  1
#define Rs_pin  0
#define D4_pin  4
#define D5_pin  5
#define D6_pin  6
#define D7_pin  7
#define LCD_BACKLIGHT_PIN     3
#define I2C_ADDR    0x27 

LiquidCrystal_I2C MAIN_LCD( I2C_ADDR, En_pin, Rw_pin, Rs_pin, D4_pin, D5_pin, D6_pin, D7_pin);

void setup() {
  //Setup the LCD
  MAIN_LCD.setBacklightPin(LCD_BACKLIGHT_PIN,POSITIVE);
  MAIN_LCD.setBacklight(HIGH);
  MAIN_LCD.begin (20,4);
  MAIN_LCD.clear();
  
  // Setup External Reference
  analogReference(EXTERNAL);
}

float analogValue;
unsigned long lastprint = 0;
void loop() {
  if((millis()-lastprint)>1000){
    lastprint = millis();

    MAIN_LCD.clear();
    MAIN_LCD.setCursor(0,0);
    MAIN_LCD.print("Sensed Voltage:");
  
    // put your main code here, to run repeatedly:
    analogValue = 5.0 * ((float)analogRead(A0) / 1023.0);
    
    MAIN_LCD.setCursor(0,1);
    MAIN_LCD.print(analogValue);
  }
}

When powering externally, how are you doing this? What is the voltage of the Arduino 5V pin
when powered this way?

Are you ensuring the AREF pin is never pulled higher than the Arduino 5V at any time (this
will fry the pin) - normally you would derive AREF from a voltage reference powered from
5V rail, so this can never happen. You seem to have some external source of 5V reference maybe not
derived from the Arduino 5V, which is why I wonder about this.

All the pins on any logic chip must always be kept within the supply rails at all times (unless the
datasheet says different), this applies to AREF as much as any other signal pin.

What is the external PS voltage and how is it connected to the MEGA?
If you are using an external voltage reference, how is it connected?

Using an external Aref can be unhealthy for your Arduino.
Make sure it always stays within the voltage range of the MCU supply.
That means the Arduino can't be off while there is voltage on Aref.

Why don't you use the inbuild bandgap reference voltage.
The Mega has two.
A 1.1volt Aref and a 2.56volt Aref.
Safe, and very stable.

Perfect to make e.g. a voltmeter.
Leo..

Thanks for the quick responses. I tried using the band-gap method but found that my reading was about 0.1-0.2 off which is more than I wanted. I tried the function used here: http://provideyourown.com/2012/secret-arduino-voltmeter-measure-battery-voltage/

I have a 5.0V precision voltage reference im using for my external reference. Its rock steady at 5.0V so I dont think its the reference.

When not usng USB, im connecting my power to the arduino via Vin. I notice that the Arduino's 5V drops to 4V when I disconnect the USB so I think thats a red flag. Am I connecting power incorrectly perhaps?

I have a custom built shield and I didnt plan on using the power jack unless I have to.

When not usng USB, im connecting my power to the arduino via Vin.

What voltage to Vin - you don't say.

If the Arduino's 5V is actually 4V and you put 5V into AREF you fry AREF, simple as that.

Ahh good call.... I was using +5V to power the arduino over Vin. I have to use my 12V source. Once I did that I got the same reading on both USB and External power, and my External reference is working correctly.

Thanks for you help, your questions pointed me in the correct direction.

Be aware that you may have stressed the AREF pin already, since you were probably powering the entire
Arduino via its anti-static protection diode.

The secret volmeter you linked to is using 1.1volt Aref.
That is rock solid, but not factory trimmed.
It could be as low as 1volt, and as high as 1.2volt.
So you have to calibrate the readout by changing the voltage in the maths line to the actual voltage of Aref.
Try this sketch. I already changed it for a Mega.
Leo..

/*
0 - ~16volt voltmeter for 3.3volt and 5volt Arduinos
uses the stable internal 1.1volt reference
6k8 resistor from A0 to ground, and 100k resistor from A0 to +batt
100n capacitor from A0 to ground for stable readings
(100k + 6k8) / 6k8 = 15.70588 | used in formula
*/
float Aref = 1.075; // ***calibrate here*** | change this to the actual Aref voltage of ---YOUR--- Arduino
unsigned int total; // holds 64 readings
float voltage; // converted to volt

void setup()
{
  analogReference(INTERNAL1V1); // use the internal ~1.1volt reference  | change (INTERNAL) to (INTERNAL1V1) for a Mega
  Serial.begin(9600); // set serial monitor to this value
}

void loop()
{
  for (int x = 0; x < 64; x++) // multiple analogue readings for averaging
  {
    total = total + analogRead(A0); // add each value to a total
  }
  voltage = (total / 64) * 15.70588 * Aref / 1024 ; // convert readings to volt

  // print to serial monitor
  if (total == (1023 * 64))
  {
    Serial.print("voltage too high"); // if overflow
  }
  else
  {
    Serial.print("The battery is ");
    Serial.print(voltage);
    Serial.println(" volt");
  }
  total = 0; // reset value
  delay(1000); // one second between measurements
}