A little ago someone asked a question on Github about the different analogRead() values he obtained when compiling at different CPU clock speeds. I found it an interesting question and did some tests, which confirmed his findings.
I tried if there was a difference between using analogRead() or using the ADC directly, with or without ADC prescaling. Even when I prescale the ADC to always use a 125KHz ADC clock I get different results.
The 1.1V internal reference is used and I then used a potmeter to set a voltage just under 1.1V on pin PA3 and measure that at 1MHz, 4MHz and 8MHz.
Apart from a little noise, that I averaged out, I get constant and consistent different ADC values. I have no more idea's what could cause this.
Test sketch:
/* Possible values to compute a shifting average in order to smoothen */
#define AVG_WITH_1_VALUE 0
#define AVG_WITH_2_VALUES 1
#define AVG_WITH_4_VALUES 2
#define AVG_WITH_8_VALUES 3
#define AVG_WITH_16_VALUES 4
#define AVERAGE_LEVEL AVG_WITH_8_VALUES /* Choose here the average level among the above listed values */
/* Higher is the average level, more the system is stable (jitter suppression), but lesser is the reaction */
/* Macro for average */
#define AVERAGE(ValueToAverage,LastReceivedValue,AverageLevelInPowerOf2) ValueToAverage=(((ValueToAverage)*((1<<(AverageLevelInPowerOf2))-1)+(LastReceivedValue))/(1<<(AverageLevelInPowerOf2)))
// AVERAGE( xxxxx , yyyyy , AVERAGE_LEVEL) ;
uint16_t adc_average;
void setup()
{
ADMUX = _BV(REFS1) | _BV(MUX0) | _BV(MUX1);; //internal 1.1V reference and PA3 channel
#if (F_CPU == 8000000)
ADCSRA = _BV(ADPS2) | _BV(ADPS1); // Set ADC prescaler to 64 125KHz ADC clock at 8MHz CPU
#elif (F_CPU == 4000000)
ADCSRA = _BV(ADPS2) | _BV(ADPS0); // Set ADC prescaler to 32 125KHz ADC clock at 4MHz CPU
#elif (F_CPU == 1000000)
ADCSRA = _BV(ADPS1) | _BV(ADPS0); // Set ADC prescaler to 8 125KHz ADC clock at 1MHz CPU
#else
#ifndef F_CPU
#error "F_CPU not defined"
#else
#error "F_CPU defined as an unsupported value for ADC prescaler test"
#endif
#endif
ADCSRA |= _BV(ADEN); // Enable ADC
delay(5);// allow internal reference to settle.
Serial.begin(9600);
adc_average = analogReadDirect(); // initail value for averaging
}
void loop()
{
AVERAGE(adc_average, analogReadDirect(), AVERAGE_LEVEL);
Serial.print("CPU speed = ");
Serial.print(F_CPU/1000000);
Serial.print(" MHz, ADC value: ");
Serial.println(adc_average);
delay(500);
}
uint16_t analogReadDirect(){
ADCSRA |= _BV(ADSC); // Start conversion
while (bit_is_set(ADCSRA,ADSC)); // measuring, wait until conversion complete
return ADC;
}
my rather consistent results:
CPU speed = 1 MHz, ADC value: 992
CPU speed = 1 MHz, ADC value: 992
CPU speed = 1 MHz, ADC value: 992
CPU speed = 1 MHz, ADC value: 992
CPU speed = 1 MHz, ADC value: 992
CPU speed = 1 MHz, ADC value: 992
CPU speed = 1 MHz, ADC value: 992
CPU speed = 1 MHz, ADC value: 992
CPU speed = 1 MHz, ADC value: 992
CPU speed = 1 MHz, ADC value: 992
CPU speed = 1 MHz, ADC value: 992
CPU speed = 1 MHz, ADC value: 992
CPU speed = 1 MHz, ADC value: 992
CPU speed = 1 MHz, ADC value: 992
CPU speed = 1 MHz, ADC value: 992
CPU speed = 1 MHz, ADC value: 992
CPU speed = 4 MHz, ADC value: 1012
CPU speed = 4 MHz, ADC value: 1012
CPU speed = 4 MHz, ADC value: 1012
CPU speed = 4 MHz, ADC value: 1012
CPU speed = 4 MHz, ADC value: 1011
CPU speed = 4 MHz, ADC value: 1011
CPU speed = 4 MHz, ADC value: 1011
CPU speed = 4 MHz, ADC value: 1011
CPU speed = 4 MHz, ADC value: 1011
CPU speed = 4 MHz, ADC value: 1011
CPU speed = 4 MHz, ADC value: 1011
CPU speed = 4 MHz, ADC value: 1011
CPU speed = 4 MHz, ADC value: 1011
CPU speed = 4 MHz, ADC value: 1011
CPU speed = 4 MHz, ADC value: 1011
CPU speed = 4 MHz, ADC value: 1011
CPU speed = 4 MHz, ADC value: 1011
CPU speed = 4 MHz, ADC value: 1011
CPU speed = 4 MHz, ADC value: 1011
CPU speed = 8 MHz, ADC value: 1004
CPU speed = 8 MHz, ADC value: 1004
CPU speed = 8 MHz, ADC value: 1004
CPU speed = 8 MHz, ADC value: 1004
CPU speed = 8 MHz, ADC value: 1004
CPU speed = 8 MHz, ADC value: 1004
CPU speed = 8 MHz, ADC value: 1004
CPU speed = 8 MHz, ADC value: 1004
CPU speed = 8 MHz, ADC value: 1004
CPU speed = 8 MHz, ADC value: 1004
CPU speed = 8 MHz, ADC value: 1003
Any idea's ?