# How many millis() takes a delay()

Hi,
I’m troubleshooting an analog logger (based on the sdfat example) and duration of the delay(x) shows less millis difference than expected:
Exampe:

mil1 = millis();
delay(5000);
m = millis();
Serial.print(m-mil1);

gives me 4808. I am using 7.37MHz crystal.
P.

Your system probably needs an 8 Mhz crystal, as you crystal is lower you should get 5000 * (7.37 /8 ) = 4606 ... OK that is lower than what you got that's the theory (and in theory there is no difference between theory and practice but in practice ...)

I was thinking the delay() is based on millis, thus I expected a delay(5000) would be equal or longer than 5000 millis for ANY crystal value. But I see the delay() is based on micros currently, where a lot of alchemy has been applied. It would be nice to have the delay() and millis() aligned in a way it will not be dependant on the crystal frequency... It cannot be a rocket science, though. :).P.

It cannot be a rocket science, though

Due to a lack of a hardware floating-point unit and other constraints, early space flight computers used fixed point math. So technically the millis implementation is "rocket science".

equal or longer than 5000 millis for ANY crystal value

It is very close to equal if you set the appropriate number in whatever file deals with this, (boards.txt?)

the delay() and millis() aligned in a way it will not be dependant on the crystal frequency

These simple delay functions are based on the clock frequency, so they can’t be independent of it. The only way to get an accurate and independant frequency would be to have another (normally external) clock source.

Rob

Frankly, I do not understand why the delay() and millis() shall be dependant on a crystal frequency entered in boards.txt. My understanding is for the clock frequencies from 32KhZ to 20MHz one shall be able to compile a delay() and millis() where one millis() unit is very close to 1ms and a delay(3333) gives you a ~3333 millis units of difference. It must not be extremly precise (because of interrupts and other obstacles you may encounter) but basically delay() millis() and micros() shall be in a relationship such the values for millis() >=delay(). It means: m1=micros(); delay_us(2000); m2=micros(); m2-m1 is >= 2000

m1=millis(); delay(2000); m2=millis(); m2-m1 is >= 2000

for ANY value of the crystal used (compiled).

P.

pito: Frankly, I do not understand why the delay() and millis() shall be dependant on a crystal frequency entered in boards.txt.

The code for millis has to be told (at compile) the speed of processor clock. There is no way for that to be determined later (at run).

My understanding is for the clock frequencies from 32KhZ to 20MHz one shall be able to compile a delay() and millis() where one millis() unit is very close to 1ms

The Arduino folks wanted an efficient millisecond clock and as many PWM pins as possible. Those three goals drive the structure of the code and limit the clock speed choices.

The simple fact is that the code in wiring.c requires the processor clock to be a power of 2 (1 MHz, 2 MHz, ... 8 MHz, 16 MHz). To support arbitrary clock speeds requires code that is more complicated (less efficient) and, in some cases, giving up PWM on timer 0.