I'm building a timer for a robotics race.
Start timer when robot breaks laser light beam.
Finish and stop timer when robot breaks the beam the second time.
My timer works off millis(). I do
start = millis()
...then a continuous loop that does
now = millis()
number = now - start
...then I parse number to get seconds, tenths and hundredths.
I'm reading that millis() has known accuracy problems and cannot be used for an accurate clock. I don't need a long term clock since a few minutes constitutes a long race. My question & concern is - - Can I be sure that two robots with an actual time (say of 9.87 seconds) will both show the same time?? If they both finished with a wrong time (say 9.85 seconds) consistantly, I don't care, but if one finish showed 9.85 and the racer with the same showed 9.86 on the timer, then I don't want that.
If this is possible, I think I'd rather do more work to have an accurate, consistant timer.
What would be the best way to do this??
(For this race I can live with a MAX of 9 minutes, 59 seconds, but I have another race where I have much shorter times, so I think four seven-segments will do it for me.)
If you disable interrupts, millis() won't work. It uses an interrupt approximately every millisecond to add 1 to a counter.
It should be consistent, and fairly accurate, under the situations you describe. The accuracy would depend on the processor's crystal or resonator accuracy, however even if out by a percent or two, it would be repeatable.
I would use an interrupt to start timing (eg. when the beam is broken) and again to stop timing. That way you should be able to get a pretty accurate start and stop time.
I shone a cheap 1W laser pointer onto the LDR. The resistance is low with the light on it (I read about 1.9V on pin D2) which registers as a LOW input. When you break the beam the resistance is high and the pin gets about 3V (being a HIGH). Thus the beam is broken on a RISING interrupt.
The code times the intervals between rising interrupts and reports them to the serial monitor. Of course you could use a LCD or something. You might want to omit very short intervals (eg. less than a second) because that might be "bounce" for where the light passes through a hole in the robot.
eg. After:
unsigned long elapsed = triggerTime - lastTriggerTime;
Add:
if (elapsed < 1000000L)
{
triggered = false;
return; // ignore if less than a second
}
This should give time to the nearest microsecond, more or less.
You might want to play with the resistor value to make it more reliable (although it was reliable enough in my test).
Also to confirm it works, you could make up two of them (it took me about 10 minutes to assemble). Then check they get the same result for a particular race.