Hi guys
Somewhere along my code I have:
ADCSRA = 0; // disable ADC
Is this the right way of turning it back on?:
ADCSRA |= (1<<ADEN); //Turn on ADC
ADCSRA |= (1<<ADSC); //Do an initial conversion because this one is the slowest and to ensure that everything is up and running
Furthermore... can this manual turning back on be skipped entirely if, say, analogRead() automatically turns on ADC?
TIA,
Pedro
Try the analogRead, see if it works.
CrossRoads:
Try the analogRead, see if it works.
Nope it didn't 
Ended up preserving ADCSRA state in a uint8_t and restoring it on waking up 
// save ADC previous state
previous_ADCSRA = ADCSRA;
// disable ADC
ADCSRA = 0;
later on, after waking up
ADCSRA = previous_ADCSRA;
Thanks,
Pedro
You probably forgot to set the prescaler bits. The ADC needs a certain frequency to work properly. If it's too fast, the results won't be accurate.
When you said analoRead "didn't work", co you be more specific about that?
Jiggy-Ninja:
You probably forgot to set the prescaler bits. The ADC needs a certain frequency to work properly. If it's too fast, the results won't be accurate.
When you said analoRead "didn't work", co you be more specific about that?
Hi Jiggy
I was testing battery voltage via A0 analogRead.
For that I was draining a 9V battery with a 20mA led. When ADC off analogRead ..errr.. readings
didn't change.
It was only after restoring the previous ADC (i.e. turning it back on) state that I began to get accurate readings (within 4% accuracy in my case).
So, AFAICS, analogRead doesn't automatically turn ADC on.
Thanks,
Pedro.
Here is extract from wiring_analog:
int analogRead(uint8_t pin)
{
uint8_t low, high;
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
if (pin >= 54) pin -= 54; // allow for channel or pin numbers
#elif defined(__AVR_ATmega32U4__)
if (pin >= 18) pin -= 18; // allow for channel or pin numbers
#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644__) || defined(__AVR_ATmega644A__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__)
if (pin >= 24) pin -= 24; // allow for channel or pin numbers
#elif defined(analogPinToChannel) && (defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__))
pin = analogPinToChannel(pin);
#else
if (pin >= 14) pin -= 14; // allow for channel or pin numbers
#endif
#if defined(__AVR_ATmega32U4__)
pin = analogPinToChannel(pin);
ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((pin >> 3) & 0x01) << MUX5);
#elif defined(ADCSRB) && defined(MUX5)
// the MUX5 bit of ADCSRB selects whether we're reading from channels
// 0 to 7 (MUX5 low) or 8 to 15 (MUX5 high).
ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((pin >> 3) & 0x01) << MUX5);
#endif
// set the analog reference (high two bits of ADMUX) and select the
// channel (low 4 bits). this also sets ADLAR (left-adjust result)
// to 0 (the default).
#if defined(ADMUX)
ADMUX = (analog_reference << 6) | (pin & 0x07);
#endif
// without a delay, we seem to read from the wrong channel
//delay(1);
#if defined(ADCSRA) && defined(ADCL)
// start the conversion
sbi(ADCSRA, ADSC);
// ADSC is cleared when the conversion finishes
while (bit_is_set(ADCSRA, ADSC));
// we have to read ADCL first; doing so locks both ADCL
// and ADCH until ADCH is read. reading ADCL second would
// cause the results of each conversion to be discarded,
// as ADCL and ADCH would be locked when it completed.
low = ADCL;
high = ADCH;
#else
// we dont have an ADC, return 0
low = 0;
high = 0;
#endif
// combine the two bytes
return (high << 8) | low;
}
It's not setting ADEN