ardnut,
I would have expected 1023 also but the datasheet and Atmel app notes say 1024.
ADC = VIN ? 1024/VREF
Data sheets for most SAR ADCs use 2^n where n is the number of bits. I often use 2^n-1 since that is full scale.
MarkT,
Here is a demonstration of how the ADC MUX and S/H are affected by external resistance.
I connected analog pin 0 to ground and analog pin 1 to 5V through a resistor. I used resistor values from 10K to 470K.
I used ADC prescalers values from 16 to 128 which results in an ADC clock from 1MHz to 125kHz in this sketch.
const uint8_t ADC_PS_16 = (1 << ADPS2);
const uint8_t ADC_PS_32 = (1 << ADPS2) | (1 << ADPS0);
const uint8_t ADC_PS_64 = (1 << ADPS2) | (1 << ADPS1);
const uint8_t ADC_PS_128 = (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);
const uint8_t ADC_PS_BITS = ADC_PS_128;
void setup() {
Serial.begin(9600);
ADCSRA &= ~ADC_PS_BITS;
ADCSRA |= ADC_PS_128;
}
void loop() {
uint16_t v0 = analogRead(0);
uint16_t v1 = analogRead(1);
Serial.print(v0);
Serial.write(',');
Serial.println(v1);
delay(500);
}
Here are the results for the value of v1. It should be 1023.
| 10K | 22K | 33K | 47K | 68K | 100K | 220K | 330K | 470K | |
|---|---|---|---|---|---|---|---|---|---|
| PS16 | 970 | 920 | 880 | 840 | 805 | 770 | 727 | 710 | 704 |
| PS32 | 1023 | 1015 | 997 | 970 | 932 | 883 | 797 | 760 | 745 |
| PS64 | 1023 | 1022 | 1019 | 1010 | 990 | 950 | 858 | 808 | 785 |
| PS128 | 1023 | 1023 | 1023 | 1023 | 1022 | 1016 | 964 | 913 | 874 |
Note that even with zero external resistance, PS16 has an error. This is because the ADC input has more than 10K of internal resistance.
I then ran the test after adding a line to throw away the first reading after changing the channel to analog pin 1. This is recommended by Atmel for more accuracy in an app note.
Here is the sketch.
const uint8_t ADC_PS_16 = (1 << ADPS2);
const uint8_t ADC_PS_32 = (1 << ADPS2) | (1 << ADPS0);
const uint8_t ADC_PS_64 = (1 << ADPS2) | (1 << ADPS1);
const uint8_t ADC_PS_128 = (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);
const uint8_t ADC_PS_BITS = ADC_PS_128;
void setup() {
Serial.begin(9600);
ADCSRA &= ~ADC_PS_BITS;
ADCSRA |= ADC_PS_128;
}
void loop() {
uint16_t v0 = analogRead(0);
analogRead(1);
uint16_t v1 = analogRead(1);
Serial.print(v0);
Serial.write(',');
Serial.println(v1);
delay(500);
}
Here are the results.
| 10K | 22K | 33K | 47K | 68K | 100K | 220K | 330K | 470K | |
|---|---|---|---|---|---|---|---|---|---|
| PS16 | 1023 | 1023 | 1022 | 1019 | 1012 | 999 | 947 | 901 | 870 |
| PS32 | 1023 | 1023 | 1023 | 1023 | 1022 | 1017 | 992 | 966 | 941 |
| PS64 | 1023 | 1023 | 1023 | 1023 | 1023 | 1022 | 1010 | 997 | 983 |
| PS128 | 1023 | 1023 | 1023 | 1023 | 1023 | 1023 | 1022 | 1016 | 1011 |
If you have a very high impedance sensor you can add a one ms delay after the first analogRead(1) with PS128. Then even a 1Meg resistor will result in 1022 or 1023.
analogRead(1);
delay(1);
uint16_t v1 = analogRead(1);