PropTime: Unix style RTC using one cog

RaymanRayman Posts: 10,207
edited 2008-09-06 - 00:55:48 in Propeller 1
This code uses·one cog·to make a native RTC by keeping Unix time...

It offers a few different string formats of the current time.

It keeps track of time zone and daylight savings time.

I'm now testing this to see how accurate the clock on my demo board is...· If there is some fixed error, I believe I can compensate by adding or subracting a second or two whenever the time is read...



Post Edited (Rayman) : 9/3/2008 7:59:31 PM GMT
1152 x 864 - 575K
«1

Comments

  • RaymanRayman Posts: 10,207
    edited 2008-09-03 - 20:05:22
    Ok, I think I got it working now... Don't see any way around using a cog to keep track of seconds... But, one of the other drivers (like vga or mouse or keyboard) could be modified to do this, so that no extra cogs are used.
  • simonlsimonl Posts: 866
    edited 2008-09-04 - 00:55:50
    Nice work Rayman, do let us know how accurate you get it - though I suspect there'll be slight differences across chips & environmental conditions, this should be really useful to many smile.gif

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Cheers,
    Simon

    www.norfolkhelicopterclub.com

    You'll always have as many take-offs as landings, the trick is to be sure you can take-off again wink.gif
    BTW: I type as I'm thinking, so please don't take any offence at my writing style smile.gif
  • Beau SchwabeBeau Schwabe Posts: 6,419
    edited 2008-09-04 - 04:16:38
    Nice Raymon...

    now you just need to tie into NIST radio broadcasts and set the time automatically.

    http://tf.nist.gov/stations/wwvb.htm
    http://tf.nist.gov/general/pdf/1383.pdf

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    [url=mailto:bschwabe@parallax.com]Beau Schwabe[/url]

    IC Layout Engineer
    Parallax, Inc.
  • scanlimescanlime Posts: 106
    edited 2008-09-04 - 08:08:49
    You don't really need a dedicated cog, you just need some code which is guaranteed to be called at least once every (2^31 / clkfreq) seconds. It can look at the elapsed time and update a global counter. Most apps probably have some kind of main loop or other polling loop that will never take more than 26 seconds to make a full iteration, so why not just provide a Spin function that will poll the global counter and update your clock?

    --Micah
  • RaymanRayman Posts: 10,207
    edited 2008-09-05 - 13:00:43
    After 2.5 days, the demo board is 7 seconds fast...

    Assuming this is a fixed offset due to crystal error, it should be easy to add in a drift correction...
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 22,540
    edited 2008-09-05 - 16:52:56
    There may well be a fixed offest, but there will also be a temperature-dependent component, unless you use a TCXO or a crystal oven, or compute the drift based on an actual temperature measurement.

    -Phil

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    'Still some PropSTICK Kit bare PCBs left!
  • RaymanRayman Posts: 10,207
    edited 2008-09-05 - 17:51:53
    True, but most stuff I do is in a temperature controlled environment...· Plus, I'd imagine that's a small error in most cases...
  • rokickirokicki Posts: 1,000
    edited 2008-09-05 - 18:14:21
    You can use two counters of a cog, rather than a whole assembly cog, if you want; it's
    pretty easy to cascade two counters to give a 64-bit counter running at the system clock
    frequency.

    For a 80MHz clock, 64 bits is some 7,000 years.
  • RaymanRayman Posts: 10,207
    edited 2008-09-05 - 18:22:07
    I wasn't able to find a way to get accurate seconds out that way (without rounding)...
    I think the clock could be easily integrated into any of the commonly used drivers (vga, mouse, keyboard, etc..)
  • rokickirokicki Posts: 1,000
    edited 2008-09-05 - 18:25:26
    Why doesn't a simple 64-bit division by 80M work?
  • jazzedjazzed Posts: 11,803
    edited 2008-09-05 - 18:30:43
    How hard would it be to get Phil's Prop-Radio to tune to WWVB mentioned in Beau's link above? Of course, all kinds of wild clocks could be displayed on an OLED, LCD, or TV. This would be a nice project for OBC's PPDB book if adapted to LED segment displays.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    --Steve
  • RaymanRayman Posts: 10,207
    edited 2008-09-05 - 18:35:39
    rokicki: Maybe you're right... Perhaps that is the best approach... I'll have to think abou this...
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 22,540
    edited 2008-09-05 - 19:04:44
    rockiki said...
    Why doesn't a simple 64-bit division by 80M work?
    Because there's a remainder. That's why I suggested in another thread that he use a 4.194304 MHz crystal.

    BTW, I tried the WWVB approach with my Prop-Radio, using the special ferrite that DigiKey sells for the purpose, and it didn't work. I'm at the edge of the WWVB coverage area, though. I also bought a WWVB receiver module from DigiKey. It didn't work either. :-( (It may just be from too much RFI in my shop.) I'd be interested in hearing if others closer to the transmitter in Colorado have a better experience

    -Phil

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    'Still some PropSTICK Kit bare PCBs left!
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 22,540
    edited 2008-09-05 - 19:41:35
    There's another alternative that will work in a single cog with any clock frequency. For 80MHz, for example, you can keep time in increments of 0.2097152... seconds by dividing the clock by 2**24 (16_777_216):

    ····16_777216 / 80_000_000 = 0.209...

    Let that unit of time be your increment. (There's nothing magical about seconds, after all.) You can program a counter to output that exact frequency, which can then feed a second counter to count (in PHSx, w/ FRQx = 1) how many of them have transpired. Then, in the same cog, you can convert to seconds simply by reading the second counter's PHSx register, multiplying by $35AFE535 (treated as a hex fraction = 0.209...) and adding a constant (to get the time since the beginning of the Unix epoch). This will be more accurate than approximating seconds, since the correction is performed on the final result, not on each "tick".

    -Phil

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    'Still some PropSTICK Kit bare PCBs left!
  • RaymanRayman Posts: 10,207
    edited 2008-09-05 - 20:00:40
    the problem would be trying to set the time to an exact second, right?
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 22,540
    edited 2008-09-05 - 20:42:04
    The time that's tracked would be precise to within a fraction of a second. You can make that fraction as small as you want, and the reported time will be precise to within that amount. The actual time that you start the counter needs to be known and should be on a one-second boundary if you want accurate truncation (or a half-second boundary if you want rounding).

    -Phil

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    'Still some PropSTICK Kit bare PCBs left!
  • TimmooreTimmoore Posts: 1,022
    edited 2008-09-05 - 21:21:45
    If you assume you call settime on a sec boundary. Then use the counter as sec from the last set and in the settime save the phs, then you can always subtract the saved phs from the current phs, convert to sec and add to sec calculated from settime, to get the current time in seconds and then convert from there.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 22,540
    edited 2008-09-05 - 21:43:06
    Or you can just clear both PHSA and PHSB on settime. The fractional counter needs to be cleared first and the units counter that it feeds before one unit after that. That way counting begins right on the mark and you don't have to remember anything except the time setting, which becomes your zero reference.

    -Phil

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    'Still some PropSTICK Kit bare PCBs left!
  • RaymanRayman Posts: 10,207
    edited 2008-09-05 - 22:09:30
    rokicki said...
    Why doesn't a simple 64-bit division by 80M work?
    I think the possible problem is that you can't read both phsa and phsb at the same time...· So, I think you couldn't be sure that it didn't carry in between reading those values...
  • CJCJ Posts: 470
    edited 2008-09-05 - 22:54:04
    wouldn't it be possible to use a counter in duty mode such that you have a single high clock per second or in nco mode at 1Hz and the second counter count highs or in the nco case low/high transitions?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Parallax Forums - If you're ready to learn, we're ready to help.
  • TimmooreTimmoore Posts: 1,022
    edited 2008-09-05 - 23:06:24
    CJ, yes and thats what I do, the problem that you have and Phil points out is due to the way the counters work its difficult to get an exact divide so you end up with jitter/remainder on the first counter. Phil points out the simple fix: run the first counter faster than 1Hz, and divide the 2nd counter to get 1Hz output. If you pick the intermediate frquency correctly you get zero jitter/remainder.
  • rokickirokicki Posts: 1,000
    edited 2008-09-05 - 23:37:00
    My proposal and Phil's are the same, except my "constant" is 1/80M, and his constant is 0.2xxx. Clearly they are equivalent,
    modulo scaling, and I figured the scaling would be pretty obvious/transparent.

    As far as reading two counters reliably, that's easy; read hibits, read lobits, read hibits again. If the hibits have changed
    (and this will very seldom happen), do the whole thing again.
  • RaymanRayman Posts: 10,207
    edited 2008-09-05 - 23:38:38
    Timmoore:
    Yes. The only problem there is that you don't have all 32 bits... So, you may have trouble in 2038 or so...
  • TimmooreTimmoore Posts: 1,022
    edited 2008-09-05 - 23:52:12
    At least the way I do it, is you have a problem 27years after the prop starts. Since the counter counts from 0 when the prop starts at about 5 ticks per sec, in 27 years it wraps. If you set the time/date I dont use it to set the counter, I work out the seconds you set and save it. It gets added to the counter value when converting seconds back to time/date.
    I have attached by version. I "borrowed" your conversion routines since mine didn't to month/year/timezone stuff, my original used 1 sec counter. I added Phil's .2097152 timer for 80Mhz but leave 1 sec timer if the prop speed is not 80Mhz. I haven't tried a long time period to see if there is any accuracy problems.
  • RaymanRayman Posts: 10,207
    edited 2008-09-06 - 00:07:16
    Only problem there is that you can't go back in time, for instance if you want to calculate the number of days that have passed since 1988 or something...
    But, this is probably not a real issue for most applications...
  • TimmooreTimmoore Posts: 1,022
    edited 2008-09-06 - 00:09:51
    True, the other problem that I am fixing, is you can't call it on any cog except the one that called Init.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 22,540
    edited 2008-09-06 - 00:17:01
    timmoore said...
    Phil points out the simple fix: run the first counter faster than 1Hz, and divide the 2nd counter to get 1Hz output. If you pick the intermediate frquency correctly you get zero jitter/remainder.
    No, that's not what I meant at all. The second counter (PHSB) merely counts rising edges from CTRA (i.e. "ticks" of 0.209... seconds, or whatever), with FRQB = 1. (I doubt that there's any way, even with two counters working in tandem, to get an exact, jitter-free 1 Hz output from an 80 MHz clock.) The idea is that your fraction-of-a-second tick interval becomes what you measure — not seconds. Whatever that interval is, since FRQA is a power of two, there's no jitter or accumulated error. The second counter just counts those intervals. Nothing gets converted to seconds until someone asks for the time. Then you multiply PHSB by the fraction representing the base time interval add add the starting time. The central point here is that you don't need to count seconds. You can count any interval you want, so long as it's jitter-free and short enough to give the precision you need. Just do the correction after the fact.

    -Phil

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    'Still some PropSTICK Kit bare PCBs left!
  • RaymanRayman Posts: 10,207
    edited 2008-09-06 - 00:23:20
    I really wish there were a counter mode that would let us count seconds!

    In lieu of that, I'm inclined to modify a standard driver to do the counting...
  • TimmooreTimmoore Posts: 1,022
    edited 2008-09-06 - 00:37:19
    Phil Pilgrim (PhiPi) said...
    timmoore said...
    Phil points out the simple fix: run the first counter faster than 1Hz, and divide the 2nd counter to get 1Hz output. If you pick the intermediate frquency correctly you get zero jitter/remainder.
    No, that's not what I meant at all. The second counter (PHSB) merely counts rising edges from CTRA (i.e. "ticks" of 0.209... seconds, or whatever), with FRQB = 1. (I doubt that there's any way, even with two counters working in tandem, to get an exact, jitter-free 1 Hz output from an 80 MHz clock.) The idea is that your fraction-of-a-second tick interval becomes what you measure — not seconds. Whatever that interval is, since FRQA is a power of two, there's no jitter or accumulated error. The second counter just counts those intervals. Nothing gets converted to seconds until someone asks for the time. Then you multiply PHSB by the fraction representing the base time interval add add the starting time. The central point here is that you don't need to count seconds. You can count any interval you want, so long as it's jitter-free and short enough to give the precision you need. Just do the correction after the fact.

    -Phil

    Thats what I am doing, the description is unclear, the translation from ~5Hz to 1Hz is done in software on phsb after reading it, not by the counter, otherwise you dont get the remainder carryed over.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 22,540
    edited 2008-09-06 - 00:55:48
    Oh, sorry. I thought you meant the counter did the dividing...

    -Phil

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    'Still some PropSTICK Kit bare PCBs left!
Sign In or Register to comment.