The secretVoltmeter (again) for MEGA 2560

Hi to all of you,

I will have a project base on the Mega Pro 2560 3.3 V (a clone of the Mega 2560 by Sparkfun) where a battery will be used. I need to measure that battery’s voltage. I came across the secretVolmeter and found out the proper code for the MEGA2560 here . The code is:

long readVcc() {
	// Read 1.1V reference against AVcc
	// set the reference to Vcc and the measurement to the internal 1.1V reference
	#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
	ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
	#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
	ADMUX = _BV(MUX5) | _BV(MUX0) ;
	ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
	delay(3); // Wait for Vref to settle
	ADCSRA |= _BV(ADSC); // Start conversion
	while (bit_is_set(ADCSRA,ADSC)); // measuring
	uint8_t low  = ADCL; // must read ADCL first - it then locks ADCH
	uint8_t high = ADCH; // unlocks both
	long result = (high<<8) | low;
	result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000
	return result; // Vcc in millivolts

That works fine… until I use analogRead(), then I get -1 (in fact the ADC value is 0) :~. Does some one know why readVcc() goes wrong after calling analogRead() ? Must be one of the registers that’s wrong afterwards, because if I reset the board, the readVcc() works fine. AnalgoRead() seems to set ADCSRB, but stragely readVcc() does not, and that’s strange because other versions of readVcc do.


Gilles Plante