Well this is quite amusing. I tried to do it with noise cancelling (by going to sleep).
#include <avr/sleep.h>
void setup ()
{
Serial.begin (115200);
Serial.println ();
} // end of setup
const int ITERATIONS = 500;
unsigned long totals [6];
// when ADC completed, take an interrupt
EMPTY_INTERRUPT (ADC_vect);
int takeReading (byte port)
{
ADMUX = bit (REFS0) | ((port - A0) & 0x07); // AVcc
// ensure not interrupted before we sleep
noInterrupts ();
set_sleep_mode (SLEEP_MODE_ADC); // sleep during sample
sleep_enable();
// start the conversion
ADCSRA |= bit (ADSC) | bit (ADIE);
interrupts ();
sleep_cpu ();
sleep_disable ();
// reading should be done, but better make sure
// maybe the timer interrupt fired
// ADSC is cleared when the conversion finishes
while (bit_is_set (ADCSRA, ADSC))
{ }
byte low = ADCL;
byte high = ADCH;
// combine the two bytes
return (high << 8) | low;
}
void loop ()
{
for (int whichPort = A0; whichPort <= A3; whichPort++)
totals [whichPort - A0] = 0;
for (int i = 0; i < ITERATIONS; i++)
{
for (int whichPort = A0; whichPort <= A3; whichPort++)
{
int result = takeReading (whichPort);
totals [whichPort - A0] += result;
}
}
for (int whichPort = A0; whichPort <= A3; whichPort++)
{
Serial.print ("Analog port = ");
Serial.print (whichPort);
Serial.print (", average result = ");
Serial.println (totals [whichPort - A0] / ITERATIONS);
}
Serial.println ();
delay (1000);
} // end of loop
Output:
Analog port = 14, average result = 506
Analog port = 15, average result = 1022
Analog port = 16, average result = 670
Analog port = 17, average result = 0
(repeated)
Those figures are noticeably lower than before (506 compared to 508, and 670 compared to 672). But! During sleep mode, the load on the 5V bus decreased, and the 5V pin jumped to 5.028V. So recalculating with the new reference voltage gave similar answers to before.
This would appear to strongly support Coding Badly's suggestion of using a proper reference voltage, as clearly the 5V voltage isn't really 5V.