To assess the inaccuracy, I made the assumption that my computer clock, and hence the millis() in Processing was accurate. Hence, the answer was to replace the millis() interrupt using a counter that I could manipulate and that would count the milliseconds from midnight, resetting each day removing any run time restrictions. The second issue is that the internal millis() function resets itself every 50 days or so and you cannot manipulate the millisecond count. My other concern was whether the Arduino clock was consistently inaccurate, but as indicated, the clock I programmed has maintained very accurate time over 5 days so it appears that the inaccuracy is consistent. All that was then needed was to program a speed adjustment to add or deduct this difference from the internally tracked milliseconds each hour. My approach was to test the accuracy of the Arduino I was using and determine how many milliseconds it lost or gained per hour. Hence if you just rely on this then the count of the milliseconds elapsed will be out by a small percentage and the clock you are creating will either loose or gain time. The main issue with using just an Arduino is that its internal clock speed is not 100% accurate. After running for 5 days, it had not lost or gained any time. I started this as an academic exercise, but ended up with a very accurate clock. This entry was posted in Arduino, Programming by David Pankhurst. However, if we keep this in mind, this means that as long as we time frequently enough, code like unsigned long newTime=micros()-oldTime will work! The value as mentioned must be an unsigned long, which rolls over after FFFFFFFF.If we cycle over two or more times, the difference is meaningless since we can’t ‘hold’ multiple 71.5 minutes cycles in an unsigned long, we can’t figure out the whole time interval. For this to work, we MUST have an ‘oldTime’ that occurred in the last 71.5 minutes.So it would seem we can ignore rollover when we do time calculations, and use the result no matter what. But 4,294,967,296 doesn’t exist in an unsigned long, so it rolls over to zero.To see if this is right, let’s do some math: So the value rolls over like an old-fashioned odometer, and we get 546. But we’re working with unsigned longs – there’s only 32 bits, and no negative. What happened? In our world, we have negative numbers, so the result is negative. But look at our earlier example: decimal hexadecimal So if oldTime is 500, and newTime is 750, we have (750-500=250), which is fine. To see how that works, consider code to check the change in time, or delta: unsigned long oldTime=micros() In a nutshell – the same way we always did! However, what do we do then? For example, what if we need to keep track, and our last count was 4,294,967,000, and our new count is 250. To see how that works, consider: the largest value that micros() can produce is 2^32-1, or 4,294,967,295. However, there’s a big problem: its maximum size ends up being too small for long-term programs! But sometimes you need to do things smaller – enter the microsecond timing function, micros(). When timing on the Arduino, it’s common to use the millis() function, which counts the milliseconds the current program has been running.
0 Comments
Leave a Reply. |