millis not accurate?

True... I wasn't 100% on it myself but I was just a little ruffled to be kinda glazed-over being practically the first person to acknowledge that accurate timing even could be done, given accurately-timed code :wink:

Just mostly ruffled that the topic transitioned from "it can't be done" to "here's how to do it" without even recognizing the "oh, well, I guess it can be done!" aspect :sweat_smile:

No biggie, I'm just glad it works as I wrote from the start... give a crystal-based Arduino good code, and it'll give you good time! Only thing to worry about is the millis() overflow every 49 days :slight_smile:

BTW, here's why millis() is so accurate... millis() runs in TIMER0, which overflows every 1.024 milliseconds on a 16MHz clock (every 16,384 clock cycles, with 256 values and a clock/64 prescaler):

SIGNAL(TIMER0_OVF_vect)
{
	// copy these to local variables so they can be stored in registers
	// (volatile variables must be read from memory on every access)
	unsigned long m = timer0_millis;
	unsigned char f = timer0_fract;

	m += 1; // add 1 to timer0_millis
	f += 3; // add 3 to timer0_fract (24 >> 3 to save bits)
	if (f >= FRACT_MAX) { // if timer0_fract >= 125, add another 1ms since all the 0.024's added up
		f -= FRACT_MAX; // but don't lose precision.
		m += 1;
	}

	timer0_fract = f; // apply all we've counted so far
	timer0_millis = m;
	timer0_overflow_count++; //used to count cycles since this is incremented every 16,384 cycles
}

That's from wiring.c, modified with the values calculated in the macros, and with my comments describing what it does :slight_smile:

And millis() just pauses interrupts, reads timer0_millis, resumes interrupts, and returns timer0_millis. :slight_smile: