Keeping time comments and solutions ?
Zap-o
Posts: 452
I want to keep time and try to keep it for as long as possible. I am using the code below and quite frankly became surprised when it started to drift after about 90 minutes. My prop is hooked up and running at 80Mhz with a precision x-tal that is rated at 50ppm. Nevertheless, shouldn't I get better out of it? I am updating another cog every second that sends it to my PC.
Your comments are greatly wanted.
{ Clock object used for keeping track of time in seconds } VAR Long cog Long Second Long Stack[noparse][[/noparse] 25 ] Pub Start : okay stop okay := cog := cognew(main, @stack) + 1 PUB stop '' Stop driver - frees a cog IF cog cogstop(cog~ - 1) PUB Main Second~ 'seconds in a year 31,556,926 2^32 = 4294967296 / 2 = 2,147,483,648 Repeat Waitcnt(clkfreq / 1 + Cnt) 'wait for .1 seconds Second ++ Pub Seconds
Your comments are greatly wanted.
Comments
you've got to account for the lost cycles in the repeat, save the clkfreq and count outside the repeat first.
- H
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
CounterRotatingProps - I am confused by what you are saying here "save the clkfreq and count outside the repeat first." I mean why will it matter? Sorry if it seems a dumb question
Mike - I could simply copy and paste this and run it, but I have to ask. Why is this better and shouldn't i remove the Second++ if you are using "Result"?
2) "Second" is something you're using to keep track of elapsed seconds. I was using "result" to keep track of clock ticks for the next second interval. It wraps around roughly every 50 seconds, so isn't very useful beyond that.
3) The reason this is better is that the execution time of the "Second++" statement and the "repeat" statement overlaps the one second interval rather than extending it as it did in your code. It's not a big difference, but it does accumulate over time. There is a little discussion on this in the Spin part of the Propeller Manual in the section on the WAITCNT statement.
Is there a better way to keep time?
There's the thermal variation. The crystal expands and contracts with changes in temperature and that changes its frequency. You can plot the frequency against the ambient temperature over time and get an adjustment factor that you can apply to the value you use for a 1 second pause.
Lastly, there's aging. Crystals go through a long period of aging after manufacture where their frequency drifts slowly as they operate. This is predictable and can be adjusted for. The crystal datasheet will generally have that information as well as information on thermal drift.
If you want accurate timekeeping over a long period of time, you need some kind of thermally compensated real time clock that's calibrated (adjusted for crystal accuracy). You can use the Propeller, calibrate its crystal against an atomic clock or frequency standard, and include a digital thermometer so it can compensate for the ambient temperature or you can buy a real time clock.
Dallas makes a temperature compensated 32KHz oscillator (www.maxim-ic.com/quick_view2.cfm/qv_pk/2940/t/al) that you could either use to feed a real time clock or directly input to a Propeller I/O pin for a time standard.
You may say that it is my xtal, but running a 20PPM xtal it should last a few days in my calculations. You may say that its the temperature causing the xtal to sway, but I contained the propeller with xtal in a temperature static room that is PID controlled.
Has anyone done better or find this unfortunate as well? I am open for suggestions and wish to brighten my understanding of the propeller.
-Phil
ac cycles using something like an opto coupler? They take great care to keep
that ac frequency stable enough to keep time. Or, you could do the timing just
as you are and every hour or whatever check a counter that you have ticking by
from reading the ac freq and then correct the xtal timers reading.... sort of like
those atomic wall clocks do. Doing it this way would let you keep time through
a power failure if your device had battery backup...although you might miss an
update and correction if the power was off for long.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
- Some mornings I wake up cranky.....but usually I just let him sleep in -
My code is as follows:
Now after some thought I think that writing the code in assembly might help this problem. Of course I have not wrote code in this form yet so excuse the question:
Maybe you can help, but each line in assembly can be counted as 1 clock cycle or more depending on the operand? I may be able to calculate each line of code and thus this may translate to time the code?
@ HollyMinkowski
Nice idea but the electronics is running off a DC supply.
Your object looks okay. However, none of the objections you have to the Propeller, including to Spin itself, are valid. The code you've posted should not accumulate any errors. Even being coded in Spin, there is plenty of time between "ticks". 'No timing issues there.
So let's take a closer look at your hardware. You say you're using a precision crystal, but what kind of crystal (series resonant? parallel resonant? ) and how have you hooked it up? PCB? Solderless breadboard? What drive level are you using? (That will be in your main program, which you should also post.)
Even if it's an irreconcilable hardware issue, there are ways to work around inaccurate oscillation. For one, you can fudge the _clkfreq value to correspond more closely with the actual oscillation frequency. But let's not go there just yet, unless we're sure it's necessary.
-Phil
Post Edited (Phil Pilgrim (PhiPi)) : 8/25/2009 3:17:37 AM GMT
Where Timer.Seconds is in the other cog. I posted up above --^
This code sends the "Tick Tock" every 3 seconds. I have a PC program that records the time and compares it from the propeller. If the propeller is off the PC program shows it and shows how much over time.
By the way; thanks for taking time to help and to teach.
What are your _clkmode and _clkfreq constants? What is the nominal frequency of your crystal? Are any other components connected to your crystal, other than the Prop pins?
Regarding the crystal type, a part number and datasheet when you get to work tomorrow will be very helpful.
-Phil
You have a potential problem with what you posted above. In particular, your Timer Main routine is running in another cog while the above Main program is running. You have two calls to Timer.Seconds and they can return different answers if your Timer Main routine updates Seconds in between these two calls. Better to have a temporary variable and do:
Author: Jeff Martin (Parallax)
Provides clock timing functions to:
* Set clock mode/frequency at run-time using the same clock setting constants as with _CLKMODE,
* Pause execution in units of microseconds, milliseconds, or seconds,
* Synchronize code to the start of time-windows in units of microseconds, milliseconds, or seconds.
obex.parallax.com/objects/139/
Mr.Green
...Yes your assumption was correct on T_Seconds. My mistake. For consistency purposes I re-posted the code
You mention:
[noparse][[/noparse]quote]You have two calls to Timer.Seconds and they can return different answers if your Timer Main routine updates Seconds in between these two calls. Better to have a temporary variable and do:
Is this refering to this line of code as the second call?
Bob Lawrence
...Thanks for the link and I have searched the object exchange. I just simply want to learn more about this problem I am having so forgive me for not needing this informatiom
Phil Pilgrim
...The x-tal is a 30ppm (I may have mentioned a 20ppm but still good enough imo) the link search.digikey.com/scripts/DkSearch/dksus.dll?Detail&name=X1091-ND
My Clock Constants
I ran the xtal on the oscilloscope and its running at: 4.99-5.010Mhz, 2.10Volts Pk-Pk
To all
...Thanks for all the help this has got to be the friendliest place to get help and learn.
As Mike mentioned earlier, I think the best solution would be some kind of watch crystal based time source, whether that be a 32.768 oscillator or an inexpensive rtc like the DS1307 (which can output several frequencies of timing pulses from 1 Hz to 32Khz in additon to providing full clock, calender and alarm functions).
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For < $7, you might consider something like this
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
The one seconds count was initially very stable. But warming up the crystal by just resting my finger on the crystal case caused an immediate drift in the crystal rate, as compared to the GPS clock. Then I touched an ice cube to the crystal case and swung the rate the other way.
This was just hacking around; I wasn't trying to make my propeller into a clock, so I didn't calculate what the drift was, but it was a great demo of crystal temperature sensitivity.
Sure that's a nice setup but, I am trying to learn more about the fine details programming a propeller and my board space is very limited. Not to mention I/O pins are limited. In the long run if this wont work as I have predicted I will have to go for some IC that keeps time.
The Propeller specs call for a parallel-resonant crystal rated for about an 18pF load capacitance. The crystal you're using is series-resonant. This discrepancy matters and will contribute to any timing inaccuracies you observe. A better choice would be a DigiKey part number X410-ND (not RoHS) or 300-8475-ND (RoHS-compliant).
-Phil
This is an interesting find you have presented to me. I looked on wiki and could not find any information about parallel-resonant / series-resonant crystal. If you have time could you tell me what this is about and effects it has on the timing?
Here's a link that explains the difference: www.maxim-ic.com/appnotes.cfm/an_pk/726/.
-Phil
Yeah, it's pretty subtle, that's for sure. Whenever you see a load capacitance mentioned, parallel resonance is implied. Crystals spec'd for series resonance don't include a load capacitance in their specifications. Parallax really should just include an explicit reference to "parallel resonance" in the datasheet, though, as this is not the first time this issue has come up in the forum. Here's a link to a thread where Chip warns against using series-resonant crystals: http://forums.parallax.com/showthread.php?p=585872.
-Phil
-Phil
The parent object just needs to define the global vars so they can be updatad from the ClockCounter object.
Then when you start the object simply insert the current time/date as shown here...
From this point on, the object will advance the clock for you keeping track down to the millisecond. Simply read from the Vars in your parent Cog and the lower one will change them as the clock advances.
I still need to add for Leap Years that are divisable by 400 but not 100. But it's good till the end of this century anyway...lol
I was up till 1:30am last night working on this and left it running till 7am and compared to my Asus laptop clock, there was no drift to the second level.
Use at your own risk.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jim Fouch
FOUCH SOFTWARE
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔