Detecting battery voltage using bandgap / internal 1.1V reference

Hello,
I'm trying to use the "bandgap" method for measuring VCC (the battery voltage) of a battery powered Arduino. In all of these examples, they seem to suggest that I don't need to wire up the VCC to an analog pin. How are they doing that?

I understand that they're using the internal 1.1V reference and measuring it against VCC...but don't they need to use one of the analog pins and connect VCC to it? Or is there a magical command that lets you read VCC as an analog input between 0-1023? Is there really no extra wires I have to add to any pin?

There are two popular links that people use as reference:

http://jeelabs.org/2012/05/04/measuring-vcc-via-the-bandgap/#comments

http://provideyourown.com/2012/secret-arduino-voltmeter-measure-battery-voltage/

I don' t know what some of the code does - for example, the Jeelab code

  1. What does the ADMUX and bitSetwaiting do?

  2. returns (55U * 1023U) / (ADC + 1) - 50;...what's the U mean? It's not a variable that's been declared?

In general, I'd like to translate some of the confusing lines of code.

Jeelab's example code:

#include <JeeLib.h>
#include <avr/sleep.h>

volatile bool adcDone;

ISR(WDT_vect) { Sleepy::watchdogEvent(); }

ISR(ADC_vect) { adcDone = true; }

static byte vccRead (byte count =4) {
  set_sleep_mode(SLEEP_MODE_ADC);
  ADMUX = bit(REFS0) | 14; // use VCC and internal bandgap
  bitSet(ADCSRA, ADIE);
  while (count-- > 0) {
    adcDone = false;
    while (!adcDone)
      sleep_mode();
  }
  bitClear(ADCSRA, ADIE);  
  // convert ADC readings to fit in one byte, i.e. 20 mV steps:
  //  1.0V = 0, 1.8V = 40, 3.3V = 115, 5.0V = 200, 6.0V = 250
  return (55U * 1023U) / (ADC + 1) - 50;
}

void setup() {
  rf12_initialize(17, RF12_868MHZ, 5);
}

void loop() {  
  byte x = vccRead();
  Sleepy::loseSomeTime(16);

  rf12_sleep(RF12_WAKEUP);
  rf12_sendNow(0, &x, sizeof x);
  rf12_sendWait(2);
  rf12_sleep(RF12_SLEEP);

  Sleepy::loseSomeTime(1024);
}

provideyourown.com's example code

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);
  #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  
 
  delay(2); // 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
}

hi,

a quick answer to question 2 :

U means "unsigned"

A better reference...
http://forum.arduino.cc/index.php?topic=38119.0

arusr:
Or is there a magical command that lets you read VCC as an analog input between 0-1023?

Correct.

Is there really no extra wires I have to add to any pin?

Correct.