I notice that when I run a simple loop, the time it takes reported by millis() is all over the map. See the code below. Is my loop really taking anywhere from 0.25ms to 3 ms, or is the resolution of millis() only +/- 3 ms? What you see below was run on a 3.3V, 8MHz Arduino Pro Mini.
unsigned long msecs; // Storage for result of millis()
unsigned long variable; // Just for time killing
unsigned int k[20]; // Storage for split times
void setup()
{
Serial.begin(9600); // Set up serial monitor
delay(2000); // Wait for me to open monitor window
variable=500;
for(unsigned int i=0; i<20; i++){ // For 20 split times
for(unsigned int j=0; j<500; j++){ // Kill some time between splits
variable=variable^msecs;
}
msecs=millis();
k*=(unsigned int)msecs; // Record the split time*
Thank you, CrossRoads. The suggestion of using micros() instead of millis() and trying the same code on a Diecimila demonstrates clearly that mills() has a resolution of only 2 milliseconds on a processor running at 8MHz. I guess this is because it uses timer0 which has been set up for other purposes. If I want to do better, I guess I must either use micros() or dedicate another timer to the task.
Per the advice of el_supremo, I'm posting the modified code below. I see that "
" gets inserted, but otherwise the preview looks the same.
[code]unsigned long msecs1; // Storage for result of millis()
unsigned long msecs2; // Storage for result of micros()
unsigned long variable; // Just for time killing
unsigned int k[20]; // Storage for split times
unsigned int m[30];
void setup()
{
Serial.begin(9600); // Set up serial monitor
delay(2000); // Wait for me to open monitor window
variable=500;
for(unsigned int i=0; i<20; i++){ // For 20 split times
for(unsigned int j=0; j<500; j++){ // Kill some time between splits
variable=variable^msecs1;
}
msecs1=millis();
msecs2=0.001*micros();
k[i]=(unsigned int)msecs1; // Record the split time
m[i]=(unsigned int)msecs2;
}
for(unsigned int i=0; i<20; i++){ // End of measurement,
Serial.print(k[i]); // Display result
Serial.write(" ");
Serial.println(m[i]);
}
}
void loop()
{
}
If you want close control of timing make sure that loop() can repeat absolutely as fast as possible (no delay() or anything like that) and use millis() or micros() to manage the timing as shown in Several Things at a Time
It matters not whether my time killer is being optimized away by the compiler, or how fast I can make the loop go. Since the loop is clearly being executed multiple times per millisecond, as reported by micros(), the fact that millis() running in the same loop always reports an increase of zero or two milliseconds, but never an increase of one millisecond is pretty conclusive proof that the resolution of mills() is only two milliseconds (with the 8 MHz clock rate).
The bottom line is that I now know what to do, and it does not include using millis(). Thanks for your help.