Can an Arduino measure the voltage of it's own power source?

All helpers! I admire Your patience. Going for a master degree in electric/electronis measurement technic one year of class was on the schedule. "To measure is to know" and old experienced guy expressed it.
True, but knowing what one is measuring is a bit of science too.
What's the theoritical background/experience of OP?

It's actually kind difficult for me to experiment and test things because the Arduino is on a PCB already. It wozld be nice to just to power the thing from my lab psu and then Serial.print the voltages, but as soon as I attach the serial adapter, it powers the Arduino up to 3.3v or something. I do however have a very complex and complicated piece of code working that wakes the Arduino up when a button is pressed and wirelessly sends a packet containing the voltage to another Arduino and then goes back to sleep.
So at the moment I have no way to read multiple measurements without the Arduino going to sleep between each of these, I mean unless I were to spend a few more days on trying to modify the code without breaking everything.

I have no background in electronics or anything the like, I just do this for fun and have been for a few years.

Did You test Your theories on a breadboard before going for a PCB of Your own?
What other Arduino projects did You manage before this one?

I had everything on a breadboard before it put it on a PCB yes.
I wouldn't know where to begin. I've done lots of random Arduino/ESP/Pi projects.

How can I measure the internal voltage of the ATmega328p? Is it exposed to any of the pins?

felic:
Oh are you saying I don't need delay at all? I can just read the voltage 10 times and then use the last result?

Rather than wasting nine reads, why not average them?

After a bunch of trial and error, I figured out that "const long InternalReferenceVoltage = 1091L;" yields the most accurate results for me. With that I consistently get the same readings as my voltmeter down to a 100th of a volt.

Here's some useful information for future readers:

  • Adding delays of any kind didn't make any difference whatsoever.
  • The first voltage reading is always too low.
  • The second voltage reading and any following readings give consistent and accurate results.
  • You need to increase/decrease InternalReferenceVoltage for every Arduino individually until you see accurate results.

So this works great for me:

void setup() {
  Serial.begin(9600);
  Serial.println(getAccurateVoltage());
}

void loop() {}

int getAccurateVoltage() {
  getVoltage();
  return getVoltage();
}

// Read the voltage of the battery the Arduino is currently running on (in millivolts)
int getVoltage(void) {
  #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) // For mega boards
    const long InternalReferenceVoltage = 1115L;  // Adjust this value to your boards specific internal BG voltage x1000
    ADMUX = (0<<REFS1) | (1<<REFS0) | (0<<ADLAR) | (0<<MUX5) | (1<<MUX4) | (1<<MUX3) | (1<<MUX2) | (1<<MUX1) | (0<<MUX0);
  #else // For 168/328 boards
    const long InternalReferenceVoltage = 1091L; // Adjust this value to your boards specific internal BG voltage x1000
    ADMUX = (0<<REFS1) | (1<<REFS0) | (0<<ADLAR) | (1<<MUX3) | (1<<MUX2) | (1<<MUX1) | (0<<MUX0);
  #endif
  ADCSRA |= _BV( ADSC ); // Start a conversion 
  while( ( (ADCSRA & (1<<ADSC)) != 0 ) ); // Wait for it to complete
  int results = (((InternalReferenceVoltage * 1024L) / ADC) + 5L) / 10L; // Scale the value; calculates for straight line value
  return results*10; // convert from centivolts to millivolts
}

If anyone could explain the reason for why the first call to getVoltage() is always inaccurate, even if you add a 30 seconds delay before it that would be awesome.

I thought you just wanted to know when the battery is getting low to save data and shut down.