Here’s an explanation for versions of uLisp with 16-bit integers. In these the (millis) function returns the bottom 16 bits of the 64-bit Arduino milliseconds counter. So rollovers as you call them are the result of converting this to a 16-bit signed integer:
Arduino millis (in hex) |
Count in milliseconds |
uLisp returns |
#x0000 |
0 |
0 |
… |
… |
… |
#x7fff |
32767 |
32767 |
#x8000 |
32768 |
-32768 |
… |
… |
… |
#xffff |
65535 |
-1 |
#10000 |
65536 |
0 |
and so on… |
|
|
You can use (millis) to time up to 65535 millis, or 65.5 seconds, by doing the following calculation:
(defun millis-fix ()
(let ((m (millis)))
(if (minusp m) (+ 65536 m) m)))
Beyond that you would need to check (millis) repeatedly, at least every 65 seconds, and keep count of when it wraps around. The time would then be:
(+ (millis-fix) (* counter 65536))
Or you could write a uLisp extension that returned the number of milliseconds as a list of values, or a string giving milliseconds as a decimal number, up to the full 64-bit precision of the Arduino millis.
The above also applies on platforms with 32-bit integers, but after 2147483647 milliseconds, or about 24.9 days. I can’t think what might be happening after 9 hours in your code; 9 hours is about 2^25 milliseconds; perhaps that’s a clue?