Extended Timer() function

Started by Tom Becker November 9, 2009
Here is an exploit of the Basic-X register.RTCTick implementation which permits using Timer(), usually limited to a 24-hour period, to measure beyond 48-day periods.

Basic-X keeps the time as a 512Hz tick count in a system Long, register.RTCTick. It normally resets the register.RTCTick count to zero when it detects a count representing 24 hours since boot (or midnight if the Basic-X clock is set to correct current time).

If the tick count is positively offset by a value that is larger than one day of ticks, the 24-hour reset will not occur so the count will continue until the 32-bit value wraps. If the value is considered as an UnsignedLong, the wrap won't happen for more than 97 days of continuous operation since boot. Working with ULngs, though, is limited since multiplies, divides and Mod instructions are not permitted with that data type. So, staying within the 31 magnitude bits of a signed Long is easier and provides a ~48.5-day maximum count before the sign bit changes. If a two-day offset is imposed, a measurable period of ~46.5 days is available.

The following functions illustrate a method to use this feature:
const OneDayInTicks as long = 44236800
const TwoDaysInTicks as long = 88473600
const OneDayInSeconds as long = 86400
const TwoDaysInSeconds as single = 172800.0

function GetDayRTCTicks() as long
' RTC count is offset to avoid midnight, which
' provides >~46-day period measurement with Timer()
' This function provides the one-day count, like the normal register.RTCTick
GetDayRTCTicks = register.RTCTick mod OneDayInTicks
end function

sub SetRTCTicks(byval lTicks as long)
' RTC count is offset to avoid midnight
register.RTCTick = lTicks + TwoDaysInTicks
end sub

function DayTimer() as single
DayTimer = csng(clng(Timer) mod OneDayInSeconds) ' one-day Timer() in whole seconds
end function

function LongTimer() as single
LongTimer = Timer - TwoDaysInSeconds ' true seconds since boot
end function
The standard system function Timer() will yield seconds since boot plus (2 * 86400) seconds. Days can be counted when (GetDayRTCTicks) decreases in value. Note that the system date will not automatically increment at midnight, so date functions will not work properly.

The count must be set at Main() startup via SetRTCTicks(0) to impose the register.RTCTick offset. Periods between two Timer() executions will be correct, and as large as ~46 days, but some accuracy will be lost with long durations due to 32-bit magnitude limits.
Tom

Here is an exploit of the Basic-X register.RTCTick implementation which permits
using Timer(), usually limited to a 24-hour period, to measure beyond 46-day
periods.

Basic-X keeps the time as a 512Hz tick count in a system Long, register.RTCTick.
It normally resets the register.RTCTick count to zero when it detects a count
representing 24 hours since boot (or midnight if the Basic-X clock is set to
correct current time).

If the tick count is positively offset by a value that is larger than one day of
ticks, the 24-hour reset will not occur so the count will continue until the
32-bit value wraps. If the value is considered an UnsignedLong, the wrap
won't happen for more than 97 days of continuous operation since boot. Working
with ULngs, though, is limited since multiplies, divides and Mod functions
are not permitted with that data type. So, staying within the 31 magnitude bits
of a signed Long is easier and provides a ~48.5-day maximum count before the
sign bit changes. If a two-day offset is imposed, a measurable period of ~46.5
days is available.

The following functions illustrate a method to use this feature:
const OneDayInTicks as long = 44236800
const TwoDaysInTicks as long = 88473600
const OneDayInSeconds as long = 86400
const TwoDaysInSeconds as single = 172800.0

function GetDayRTCTicks() as long
' RTC count is offset to avoid midnight, which
' provides >~46-day period measurement with Timer()
' This function provides the one-day count, like the normal register.RTCTick
GetDayRTCTicks = register.RTCTick mod OneDayInTicks
end function

sub SetRTCTicks(byval lTicks as long)
' RTC count is offset to avoid midnight
register.RTCTick = lTicks + TwoDaysInTicks
end sub

function DayTimer() as single
DayTimer = csng(clng(Timer) mod OneDayInSeconds) ' one-day Timer() in whole
seconds
end function

function LongTimer() as single
LongTimer = Timer - TwoDaysInSeconds ' true seconds since boot
end function
The standard system function Timer() will yield seconds since boot plus (2 *
86400) seconds. Days can be counted when (GetDayRTCTicks) decreases in value.
Note that the system date will not automatically increment at midnight, so date
functions will not work properly.

The count must be set via SetRTCTicks(0) to impose the
register.RTCTick offset. Periods between two Timer() executions will be
correct, and as large as ~46 days, but some precision will be lost with long
durations due to the 6-7 digit 32-bit Single float magnitude restriction. The full-precision 512Hz tick count, however, will still be available in the 32-bit Long.
Tom

Edited with minor changes.