Let's face it, millis() is pretty badly broken. It rolls over after 9h 32m 39.738s (0x20C49BA milliseconds), which means that at that time, any delay or anything else that you are doing that depends on the value of millis() is likely to break. Also, 2.4% of the time, the value of millis() increments by two instead of by one - if your application depends on knowing the difference, it will probably break.
If it isn't possible/desirable to make timer0 tick at 1KHz (or some neat multiple of same), then at least make it tick faster than 1KHz (maybe >= 4KHz) instead of slower, so that the value of millis() never increments by more than one! Then -
#define CLOCK_CYCLES_PER_MILLISECOND (F_CPU / 1000UL)
volatile unsigned long millis;
unsigned long clock_ticks;
SIGNAL(SIG_OVERFLOW0)
{
clock_ticks += NUMBER_OF_CLOCK_CYCLES_PER_TIMER0_OVERFLOW;
while (clock_ticks >= CLOCK_CYCLES_PER_MILLISECOND) {
// Preferably this loop should only ever execute either 0 or 1 times per overflow
millis++;
clock_ticks -= CLOCK_CYCLES_PER_MILLISECOND;
}
}
unsigned long millis()
{
unsigned long return_val;
cli(); // disable interrupts so that the value of millis cannot update while we are reading it
return_val = millis;
sei(); // re-enable interrupts
return return_val;
}
(I'm not sure if it is necessary to disable interrupts, but I think it's a good idea).
I think the above code should give a millis() that rolls over after 2^32 milliseconds (i.e. 49d 17h 02m 47.296s). Better still, subtracting two different return values of millis() will ALWAYS give the right answer (unless the time difference between the two values is actually more than 2^31 milliseconds - i.e. 24 days and change).
Also, on an ATmega168 (and maybe others?), PWM on pins 5 and 6 is broken, in the sense that if you set a PWM value of 0, you don't get a constant 0 volts out - you get a high frequency signal with a very narrow spike in it. (This is because pins 5 and 6 use timer 0 in fast PWM mode, whereas the other PWM pins use their respective timers in phase-correct PWM mode). May I suggest that if a PWM value of 0 is being requested for pins 5 or 6, that the pin be set digitalWrite(pin, LOW)?