A bit of some code help - Time keeping -
grasshopper
Posts: 438
I am using the code below that I got from forums.
I want to understand this code more and don't understand the following line of code.
Whats the "||" mean? The book states that its the absolute vale, but I am still confused.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Those who criticize our generation forget who raised it.
Post Edited (grasshopper) : 2/19/2009 3:53:59 PM GMT
PUB Timer(In) | RightNow, ClockTicks RightNow~ ClockTicks~ RightNow := cnt IF RightNow < In ClockTicks := ||($FFFFFFFF - RightNow + In) ELSE ClockTicks := || ( RightNow - In ) result := ClockTicks / (clkfreq / 1_000)
I want to understand this code more and don't understand the following line of code.
ClockTicks := || ( $FFFFFFFF - RightNow + In )
Whats the "||" mean? The book states that its the absolute vale, but I am still confused.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Those who criticize our generation forget who raised it.
Post Edited (grasshopper) : 2/19/2009 3:53:59 PM GMT
Comments
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
· -- Carl, nn5i@arrl.net
Leon
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Amateur radio callsign: G1HSM
Suzuki SV1000S motorcycle
The code above just checks to see if a rollover has happened since the last time you checked, and if so, adjusts the math to produce the correct difference value.· Think of it this way· (assuming a 10 cycle rollover):
If your first measurement was '2', and now you're at '8', it's pretty obvious that the time passed is (8-2), or·6 clock cycles.· On the other hand, if the last time you measured was '8', but the clock rolls over after 9 and goes back to 0, and the 2nd measurement is '2', you have a rollover.· 2 - 8 is not the right answer.· The clock counted 9, then 0, 1, 2, for a total of 4 cycles.· The math in your code is actually computing the length of the two segments of time involved - One from 'LastTime' to $FFFFFFFF, and the other from zero to RightNow.
It's also handling the problem that Spin doesn't appear to deal with unsigned numbers, which would make this much simpler.· When your clock goes from $7FFFFFFF to $80000000, only one cycle has passed, but to Spin, those two numbers are·2147483647, and -2147483648.· The funky bit with $FFFFFFFF takes care of that.
So for your problem, you're trying to track periods of time longer than your 32 bit clock allows, so you need more than one counter.· If you can call an 'update' function more than once every 53 seconds, you're in business:
That code looks to see how many cycles have passed since you last called the function and adds that amount of time to 'ElapsedTime'.· If 'ElapsedTime' has accumulated a second or more, the Seconds value is incremented, and a single second worth of cycles (80 million) is subtracted from the 'ElapsedTime' value, leaving any fractions of a second that might be there intact.
If you call this code at least once a second, it'll work just fine.· If you call it less often than that, you'll need to change the 'if' to a 'while' (while there's a second or more in 'ElapsedTime', increment seconds and subtract cycles).
Does that make sense?
Jason
Post Edited (JasonDorie) : 2/19/2009 9:01:45 AM GMT
If you can afford the I/O pin, chaining the two counters in a cog together gives you a "set and forget" timer.
Post Edited (Mike Green) : 2/19/2009 4:16:12 PM GMT
The 80_000_000 is the clock frequency. You could actually replace that with clkfreq, which would be more portable, and better coding practice. I've only run the prop at 80MHz, so I tend to just use the constant.
Jason
For time differences less than 53+ seconds (80MHz clock), you're making things way too complicated. In this case, you have only to subtract the prior cnt from the current cnt to get the time difference. If the timer rolled over in between, the math still works — without a bunch of conditionals. The only catch is that if the interval was longer than 26+ seconds, the difference will be negative. But one seldom needs times accurate to 1/80E6 seconds anyway, and you can simply shift the difference right to eliminate the sign bit. Once you've shifted right by one, you'll have a positive number representing the time difference in 1/40E6 seconds.
-Phil
if you want to measure longer times than the 26 or 53 seconds
without stopping the whole cog
If you have a cog to spend you can use the timer-object from the obex
which gives a clock with milliseconds seconds minutes hours and even days
if you don't want to spend a cog to this
you can use something like this
with this code you can count up the seconds until 2.147483648e9 which is more than 68 years (@Chip: ) is this enough time to finish the Prop II including a 64bit counter ? ))
best regards
Stefan
The new UpdateSeconds code looks like this:
Stefan - Your approach will work, but since you're recording a new cnt value after a second has passed instead of using the existing value, you'll miss fractions of seconds, which will accumulate over time.· If this doesn't need to be accurate that won't be a big deal, but you'd lose a thousand cycles or more per second with that code.
Jason