Hi,
I try to use ADC with ATMEGA328 @8MHz after sleep , the other parts of the code giving the expected results ;
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
power_all_disable(); // all bits set in PRR register (I/O modules clock halted)
ADCSRA &= ~(1<<ADEN); // ADC shutdown
sleep_enable();
sleep_bod_disable();
sleep_cpu();
sleep_disable();
power_all_enable(); // all bits clr in PRR register
ADCSRA |= (1<<ADEN); // ADC enable
delay(60); // 60mS is the smallest delay to have correct reading
analogReference(INTERNAL);
uint16_t volts=analogRead(VINPUT);
Without the 60mS delay before reading, I got wrong and unstable readings from 0x0380 to 0x0100 with the real value near 0x358, on 3 different boards.
So I took the datasheet...
In the Atmel datasheet, p240, we can read that :
"By default, the successive approximation circuitry requires an input clock frequency between 50kHz and
200kHz to get maximum resolution. If a lower resolution than 10 bits is needed, the input clock frequency to the ADC can be higher than 200kHz to get a higher sample rate."
"...A normal conversion takes 13 ADC clock cycles. The first conversion after the ADC is switched on (ADEN in
ADCSRA is set) takes 25 ADC clock cycles in order to initialize the analog circuitry.
When the bandgap reference voltage is used as input to the ADC, it will take a certain time for the voltage to
stabilize. If not stabilized, the first value read after the first conversion may be wrong.
The actual sample-and-hold takes place 1.5 ADC clock cycles after the start of a normal conversion and 13.5
ADC clock cycles after the start of an first conversion. When a conversion is complete, the result is written to the
ADC Data Registers, and ADIF is set. In Single Conversion mode, ADSC is cleared simultaneously. The
software may then set ADSC again, and a new conversion will be initiated on the first rising ADC clock edge."
So I tried by myself without arduino functions
ADMUX |= (1<<REFS1) | (1<<REFS0) | VCHECKADC ; // internal 1,1V ref + ADC input for volts
ADCSRA |= (1<<ADEN) | (1<<ADSC) | (1<<ADPS2) | (0<<ADPS1) | (1<<ADPS0); // ADC enable + start conversion + prescaler /32 (cpu clk/64)
delayMicroseconds(320); // 25+14 ADC clk so 39*8uS to make 1+1 conv @8MHz/64
// changing the delay to 1000 has no effect
v=ADCL;
v+=ADCH*256;
and I got the same result... needs to add 60mS before reading...
Sleep after sleep, reading after reading, the value is going down (333,249,1D1,14A...)
Any idea ?
Thx