Shop OBEX P1 Docs P2 Docs Learn Events
Displaying millisecond resolution with DS1307 RTC — Parallax Forums

Displaying millisecond resolution with DS1307 RTC

Don MDon M Posts: 1,653
edited 2012-02-11 08:44 in Propeller 1
For a data logging project. Is it possible to get the 1307 to display hours:minutes:seconds:milliseconds or hours:minutes:milliseconds? If so how would it be done?

Comments

  • Duane C. JohnsonDuane C. Johnson Posts: 955
    edited 2012-02-08 18:21
    Hi Don;

    The DS1307 does not make milliseconds available to the user.
    The resolution of the seconds edge is accurate enough though.

    DS1307 Real Time Clock

    You may be able to setup a cog that maintains a mS counter synced to the seconds edge in the DS1307.

    Duane J
  • cavelambcavelamb Posts: 720
    edited 2012-02-08 18:22
    Don M wrote: »
    For a data logging project. Is it possible to get the 1307 to display hours:minutes:seconds:milliseconds or hours:minutes:milliseconds? If so how would it be done?

    CBD

    The chip doesn't return anything less than seconds...
  • JasonDorieJasonDorie Posts: 1,930
    edited 2012-02-08 18:30
    The 1307 only provides seconds as far as I know. It also has a 1Hz output pin, so if you were to grab the current time value, then use the 1Hz pin to keep your code sync'd, you could display the ms value yourself.

    In pseudocode:
    OneMs := clkfreq / 1000
    
    'Get the current time
    Time := GetTime
    
    'Syncronize to the tick clock
    waitpeq( HzPin, HzPinLow )
    waitpne( HzPin, HzPinLow )
    SecondStart := cnt
    
    ' ...less than one second passes....
    
    CurrentMs := (cnt - SecondStart) / OneMS
    


    Actually, looking at the datasheet, the Hz pin can output several frequencies:

    SQW/OUT (Square Wave/Output Driver) – When enabled, the SQWE bit set to 1, the SQW/OUT pin
    outputs one of four square wave frequencies (1Hz, 4kHz, 8kHz, 32kHz). The SQW/OUT pin is open
    drain and requires an external pull-up resistor. SQW/OUT will operate with either Vcc or Vbat applied.

    So if you set it up to drive one of the counters in a cog, you could use the 4/8/32 KHz output and just shift it down appropriately to get your millisecond value.
  • Don MDon M Posts: 1,653
    edited 2012-02-08 18:34
    Thanks guys but yes I knew that it only produces seconds that is why I was wondering if anyone had any way of resolving it into milliseconds. or if there might be any methods floating around that may do so.
  • Don MDon M Posts: 1,653
    edited 2012-02-08 18:39
    I wouldn't be opposed to even a different RTC that did resolve into milliseconds if one exists.
  • Don MDon M Posts: 1,653
    edited 2012-02-08 19:15
    Jason- I like your example. The only problem is that when I am logging data I'll call the "get time" routine and it won't know where it is in regards to the seconds when it is called.
  • Don MDon M Posts: 1,653
    edited 2012-02-08 19:17
    Duane- I see what you are saying- I'd have to have a cog running with the time routine and then call it's result when needed. Slowly I think I'm understanding what I need to do...
  • cavelambcavelamb Posts: 720
    edited 2012-02-08 19:25
    Don M wrote: »
    Jason- I like your example. The only problem is that when I am logging data I'll call the "get time" routine and it won't know where it is in regards to the seconds when it is called.


    I'm just getting started with the RTC code. Well, not exactly started yet - maybe tomorrow.

    But when it gets up and running I'll try to determine latency.
    We do that by reading the RTC chip twice and seeing how long it takes.
    I don't know yet, but I'll bet it's a whole bunch of microseconds.

    To include Jason's idea, you'd need to read the RTC and save that, then add your mSec count.
    It would not be a straight "read the RTC" GetTime function.
    Resolution would depend on how fast you could read the chip time + accumulate mSec counts.
    But there are a LOT of microseconds in a millisec.
  • jmgjmg Posts: 15,183
    edited 2012-02-08 20:32
    Don M wrote: »
    I wouldn't be opposed to even a different RTC that did resolve into milliseconds if one exists.

    Given they all start with 32768Hz, that's asking for a fractional divider, of 32.768 ?

    http://www.wolframalpha.com/input/?i=fraction+0.768
    gives some integer ratio choices.

    The Prop is easily capable of spitting your seconds into even sub-microseconds, if you do not mind running it all the time.
  • JasonDorieJasonDorie Posts: 1,930
    edited 2012-02-08 22:48
    How about this?
      SetRTC_1Hz()
    
      waitpne( HzPin , HzPin )
      waitpeq( HzPin , HzPin )  'wait for the Hz pin to transition
    
      SetCounterMode( OnFallingEdge )
      startTicks := ReadCounter()
    
      SetRTC_4KHz()
      startTime := GetTime()
    

    Assuming you can enable the counter in less than 1 millisecond (which should be trivial) you now know exactly where you are within the second, and you know what millisecond time it was when you started. From there, you can do this:
      waitpne( HzPin , HzPin )
      waitpeq( HzPin , HzPin )  'wait for the Hz pin to transition (ie, wait for the start of the next millisecond)
      currentTicks := ReadCounter()
      currentTime := GetTime()
      currentMS := (currentTicks - startTicks) / 2
    

    As soon as you begin reading the time from the RTC it latches all the values. Waiting for the Hz pin to transition is so you catch the time at the start of the millisecond so the MS ticker doesn't change just before you read the time. You could also read the counter before and after reading the time. If the counter has changed, use the latter value, otherwise use the former (it'll be more accurate).

    Does that make sense?
  • JonnyMacJonnyMac Posts: 9,197
    edited 2012-02-08 23:14
    Use the DS1307 as a backup. When your device powers up the DS1307 time can be read into a software RTC that _can_resolve milliseconds (you'll find one I wrote in ObEx).
  • MagIO2MagIO2 Posts: 2,243
    edited 2012-02-08 23:46
    May I ask a theoretical question?

    What is the advantage of using the 1s signal from RTC over using the propeller clock or a propeller counter?

    For my understanding the RTC is usefull to keep the time when whatever uC attached to it is switched off. So, when switching the uC on it would read the time. In interrupt-driven uCs the 1s signal is very usefull, because you'd simply attach it to an IRQ-input and the uC can easily count the seconds and it's usefull because the available overflow-interrupts would need a chrystal with odd frequencies (f=2^x) to allow internal timer interrupts to happen with a one second-resolution. But the propeller has no interrupts. So, you have to code something anyways. So, why not read the initial clock, sync with the sencond signal once (which in the end only makes sense if you have a radio controlled clock) and then let a COG take care of all the rest. If you also log the date, you could re-read the RTC each night around 0:00 which will update the date part without the need to code an overflow of hours to day, day to month, month to year with the additional need to have a calendar function.

    I'd do it this way:
    Have a string which keeps the date string - initialized by reading RTC when switching on
    Have a 32 bit variable which is used to count ms for 1 day. - initialized by reading RTC when switching on (32 bit in this case is enough to count for 49 days)
    At 0:00 re-read date/time from RTC
    Have a COG that keeps track of the ms


    Plan B:
    Use Jonnys Object ;o) Tztz ... so much time passed by between initially reading this thread and posting the response.
  • cavelambcavelamb Posts: 720
    edited 2012-02-09 00:05
    Dunno if the code works, but yes...
    That's it.

    You'd spend a few clock cycles counting milliseconds...
    But not all that many.

    waitpne, huh?
    That's slick!
  • cavelambcavelamb Posts: 720
    edited 2012-02-09 00:11
    Magi,

    The deal is, even if you HAD interrupts you'd have to write code to service them.
    So what's the difference between setting up for an interrupt verses setting up to poll for an event?
    Either way you respond to the changing of the millisecond.

    How much overhead would the rest of the task need?
    Read data from something and log it - per millisecond?
    Betcha there's a lot of standing around waiting for the millisecond to end...
  • cavelambcavelamb Posts: 720
    edited 2012-02-09 00:22
    And - if I misunderstood the question - the prop can count milliseconds while the RTC counts up the next full second.

    For what it's worth, I haven't tried this...
    But
    That's part and parcel about what is so neat about this chip.

    Worst case, use a counter to make a 5 megahertz clock and count THAT.
    (if you can figure out how? Spin may not respond that fast, but assembly might)
    That's only 200 nanoseconds per tick... - 1/5 Millisec per tick?
    How 'bout it, oh ye spin gurus?
    Can you increment a counter in 200 ns?

    BTW- this IS plan B
  • JasonDorieJasonDorie Posts: 1,930
    edited 2012-02-09 00:51
    MagIO2 wrote: »
    What is the advantage of using the 1s signal from RTC over using the propeller clock or a propeller counter?

    The RTC uses a crystal that is (typically) more accurate than the ones spec'd for the Prop. That's it. If you used a crystal that was better than std spec, there'd be no reason to use the RTC beyond the startup read as you suggested. Well, that and not having to keep track of hours, mins, secs, date, etc. for your timestamps.
  • Don MDon M Posts: 1,653
    edited 2012-02-09 04:35
    jonnymac- is this the object you are referring to? http://obex.parallax.com/objects/532/
  • JonnyMacJonnyMac Posts: 9,197
    edited 2012-02-09 08:10
    Yes. I just opened it and see that it can stand a bit of updating, so check back later when I've had a few minutes to refresh it.
  • Don MDon M Posts: 1,653
    edited 2012-02-09 13:07
    Looking forward to your revisions.
  • Don MDon M Posts: 1,653
    edited 2012-02-09 15:42
    It would be neat if it interfaced with a Dallas RTC and when you initialized it, it synced with an actual reading from the Dallas RTC.
  • JonnyMacJonnyMac Posts: 9,197
    edited 2012-02-09 16:24
    That's not going to happen; it is a separate object that is intended to be used on its own, whether there is a hardware RTC connected or not. Your application should have an object for your specific hardware RTC that is used to set the soft RTC.
  • JonnyMacJonnyMac Posts: 9,197
    edited 2012-02-10 08:05
    I've posted my soft RTC update.
    -- http://obex.parallax.com/objects/532/

    Note that some method names have changed and the PASM portion is now compatible with other languages (i.e., it only uses par for access).
  • Don MDon M Posts: 1,653
    edited 2012-02-10 11:39
    Thanks Jon!
  • kuronekokuroneko Posts: 3,623
    edited 2012-02-10 20:42
    JonnyMac wrote: »
    I've posted my soft RTC update.
    FWIW, you'll leak a lock handle every time cognew fails.
  • JonnyMacJonnyMac Posts: 9,197
    edited 2012-02-10 20:53
    Thanks for the catch, Marko, I fixed that.
  • kuronekokuroneko Posts: 3,623
    edited 2012-02-10 21:43
    One more, the today method should probably read:
    pub today
    
    '' Return RTC day of week, 0..6
    
      lock_regs(true) 
      [COLOR="orange"]result :=[/COLOR] rtc[DAY]
      lock_regs(false)
    
    Same is true for all the other single component methods.

    That said, I'd argue that locking single long access(es) isn't all that useful.
  • JonnyMacJonnyMac Posts: 9,197
    edited 2012-02-10 22:09
    That said, I'd argue that locking single long access(es) isn't all that useful.

    I agree that it's very cautious; that said, on the other side of things the RTC cog could be in the middle of the read-modify-write cycle for that register. By locking the "foreground" cog it ensures the background is not locked (busy with update) and the possibility of a collision -- I beleive -- is minimized.

    You're right, though, about the construction of those methods -- I have fixed all. Not making an excuse, but I was updating two versions of the file and just fouled this part. This is why I like to post objects in the forums before moving to ObEx. Should have done it this time, too. Thanks, again.
  • Don MDon M Posts: 1,653
    edited 2012-02-11 08:21
    Jon- I tried your demo and it shows 12:00:00 AM SUN but on line 60 when I change term.str(rtc.tstr_12) to term.str(rtc.tstr_24) I get this result: hh:mm:ss SUN

    What am I doing wrong?
  • JonnyMacJonnyMac Posts: 9,197
    edited 2012-02-11 08:44
    Sorry... copy-paste error on my part. It's fixed now. Version 2.04 is the latest.
Sign In or Register to comment.