PDA

View Full Version : Accurate Timekeeping

SRLM
01-17-2009, 10:59 AM
Hi,

I'm working on a clock project, and I'm looking for input on the execution of spin code. I wrote the bit of code below, and it's launched into a new cog and I just read the variables (hour, minute, and second) as needed from other parts of the program. However, I suspect that the spin execution code and the time it takes will be a problem. Even if it misses a single clock cycle every time, that adds up the longer the project runs. I'd like to avoid that if possible. Any ideas on how to make it determinate and execute in constant time?

PUB Clock
repeat
repeat until hour => 12 'hour
repeat until minute => 60 'min
repeat until second => 60 'sec
waitcnt(clkfreq + cnt)
second++
second := 0
minute++
minute := 0
hour++
hour := 0

Thanks!

Kye
01-17-2009, 11:37 AM
Just use the cnt register and compute your time from that. It will be more accurate than keeping your own clock.

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nyamekye,

mirror
01-17-2009, 11:45 AM
PUB Clock | clk
clk := cnt
repeat
repeat until hour => 12 'hour
repeat until minute => 60 'min
repeat until second => 60 'sec
clk += clkfreq
waitcnt(clk)
second++
second := 0
minute++
minute := 0
hour++
hour := 0

This will be a good start in making your clock as accurate as the crystal.

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔

SRLM
01-17-2009, 01:05 PM
Won't the line "clk += clkfreq" take some amount of clock clycles to execute, and therefore throw it off? Then each line that increments a variable would take a little bit of time, along with the waitcnt. So should I have something like this:

PUB Clock | clk
clk := cnt
repeat
repeat until hour => 12 'hour
repeat until minute => 60 'min
repeat until second => 60 'sec
clk += clkfreq - 12
waitcnt(clk)
second++
second := 0
minute++
clk -= 12
minute := 0
hour++
clk -=12
hour := 0
clk -= 12

But what should I replace 12 with?

mirror
01-17-2009, 01:11 PM
clkfreq is a constant. With a 5 MHz crystal at PLLx16 its value is 80MHz.
So, every time clk += clkfreq is executed, the value of clk is increased by 80M.
WaitCnt will wait until the value of CNT = clk.

There's a good description (including pictures) in the Propeller Manual for WaitCNT.

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔

SRLM
01-17-2009, 01:28 PM
The problem (at least the one that I'm seeing :) isn't that clkfreq is a constant, it's that the code execution takes time that's not accounted for. For example, inside the second loop are the following values that determine the number of clock cycles that it takes to execute.

Repeat command with variable comparison (? number of clock cycles)
addition and subtraction, assignment (? number of clock cycles)
waitcnt command execution (? of clock cycles)
clkfreq constant (clkfreq number of clock cycles)
increment operator (? number of clock cycles)

I can infer that the there must be at least clkfreq number of cycles in the above command, and some number more to execute all the other commands. My question is: how do I get that number, and make it stay the same every time?

mctrivia
01-17-2009, 01:42 PM
yes the command takes time. no you do not need to account for it. by subtracting 12 you will make your clock run slightly fast. since no longer how long it takes to run your code(assuming it takes less then 80,000,000 cycles it will wait until the last time used +80,000,000 not the current time so your code will start exactly 1sec apart each time.

SRLM
01-17-2009, 01:46 PM
Seems I was a bit hasty... All it took was a shove (a hard one, too!) to the waitcnt manual page, and lo and behold, a whole section on constant time. Also, it took a slightly different frame of thought.

PUB Clock | currentClk

currentClk := cnt
repeat
waitcnt(currentClk += clkfreq)
second++
fixMainClock

The method fixMainClock is simply a method that rolls the numbers over so I don't get 60 seconds displayed. Thanks for all the help! :)

StefanL38
01-17-2009, 03:10 PM
How about using the timer-object from the obex

it's always a good thing to make a quick search with some keywords in the obex

Anyway by creating methods on your own you have learned a lot about the use of the systemcounter

best regards

Stefan

SRLM
01-18-2009, 12:04 AM
From what I can tell, the timer object doesn't take into account code execution time. It also has some weird variable: tix and TIX_DLY...

Andy Lindsay (Parallax)
01-18-2009, 12:56 PM
For examples of timekeeping without losing clock cycles, see Propeller Education Kit Labs: Fundamentals page 62.