int agg = 0; long int result; //voltage number reading in counted loop; also used later for calculation of voltage int nsamples = 64; //number of samples to aggregate // code for secret voltmeter adapted from a program by JRemington void setup() { // put your setup code here, to run once: Serial.begin(9600); } long readVcc() { // Read 1.1V reference against AVcc // set the reference to Vcc and the measurement to the internal 1.1V reference //choose the right register settings for the processor in use #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); #elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) ADMUX = _BV(MUX3) | _BV(MUX2); #else ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); #endif for (int count=0; count < nsamples; count++){ delay(2); // Wait for Vref to settle ADCSRA |= _BV(ADSC); // Start conversion while (bit_is_set(ADCSRA,ADSC)); // measuring // read it a second time 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 result = (high<<8) | low; agg = agg + result; //collect and add up nsamples readings delay(10); } // we dont find the average here, it gives better resolution to multiply by the calibration constant first // result = agg / nsamples result = 1115702L * nsamples / agg; // 1115702 = 1.0896 * 1024 * 1000 - calibration constant, different for each processor return result; // Vcc in millivolts } void loop() { Serial.print("Vcc is "); Serial.print(readVcc()); Serial.println(" mV"); agg=0; // reset aggreagate ready for next reading }