Shop OBEX P1 Docs P2 Docs Learn Events
NIST WWVB WWV WWVH & Propeller — Parallax Forums

NIST WWVB WWV WWVH & Propeller

PJAllenPJAllen BannedPosts: 5,065
edited 2015-03-16 20:48 in Propeller 1
OK
This subject and all Replies shall be about using the Propeller as it relates to capturing and otherwise making use of the time signals from WWVB, WWV and WWVH and their technologies as applicable.

If you're about GPS or something or anything else then take those concerns or objections someplace else.
The same goes for any "accuracy" rumbles, "what is time" theorizing, etc.
«1

Comments

  • PJAllenPJAllen Banned Posts: 5,065
    edited 2014-11-06 05:51
    reserved_01

    Waiting for my WWVB receivers from Inglaterra.

    Links --

    http://www.pvelectronics.co.uk/rftime/SYM-RFT-XX.pdf

    http://www.nist.gov/pml/div688/grp40/wwvb.cfm
  • PJAllenPJAllen Banned Posts: 5,065
    edited 2014-11-06 05:52
    reserved_02
  • David BDavid B Posts: 591
    edited 2014-11-06 10:58
    I've successfully decoded time signals from the 10 mHz WWV station. I've tried but never successfully received the WWVB signal.

    For WWV, I took the audio signal from a commercial HF receiver, built an op-amp active bandpass filter, then rectified the output, digitized it with a Schmidt, and the computer took over from there with conventional serial message decoding.

    I say conventional because it's not rocket science, but all the same, there's a real art to being able to detect sync, decode partial messages, re-acquire sync after signal loss, etc. It's not so easy to do a good job at this. On the other hand, once it's working, it's really rewarding to watch your program smoothly decode the time from a signal that's so weak and staticy that the voice part of the broadcast is virtually unintelligible.

    The trouble I've had with WWVB is that there's no conventional voice signal to show that the station has been acquired, and the signal where I live is weak enough that circuit noise, radio noise, oscillating op-amps, power supply hum all muddy up the received signal strength to the point where I can't tell whether the circuit is receiving the signal or not.

    I could see two parts to this as related to the propeller. First, decoding the serial stream into date and time values. WWV and WWVB have slightly different formats, but if I remember right, they have a similar concept of several frames of data sent over about a minutes time, so I'd guess one propeller library could serve to decode both. Second, for the adventuresome, the propeller might be able to do some of the radio frequency signal processing as well.

    Years ago I bought a dedicated WWV receiver, a little board about 2 inches square, into which is installed your choice of either a 5 or 10 mHz crystal, and it does a pretty decent job of receiving WWV audio. It would be a nice project to add a propeller time decoder to that board. Maybe Phil Pilgrim's Goertzel propeller code routine could replace the 100 Hz active filter and detector.
  • PJAllenPJAllen Banned Posts: 5,065
    edited 2014-11-06 11:34
    Yes, I've done with WWV, too. And not just the 100Hz (there's the top of the hour Peep, too.)
    As you say, it's easier to experiment with something that you can hear.
    WWV, WWVH reception quality varies by time of day and seasonally.
    That can depend the aerial used and other factors.

    I think that the idea is to update an "RTC" or similar, at least once a day, and not be pinned down to an all-or-nothing constant reception-dependent paradigm.

    (I hope those Ingles get my receivers on their way soon.)
  • RsadeikaRsadeika Posts: 3,824
    edited 2014-11-06 12:02
    Which ones did you buy? When I first glanced at the ad, I saw 12.95, thinking that's not a bad price, then looking at it again I saw the US dollar price, which still is not that bad.

    Ray
  • PublisonPublison Posts: 12,366
    edited 2014-11-06 12:02
    PJ, are you in a region to get CHU? I can get that signal 80% of the time on the East coast.
  • PJAllenPJAllen Banned Posts: 5,065
    edited 2014-11-06 16:54
    Ray,
    Both sellers noted on that other page feature the same device (same pictures, descriptions, etc.) and both have commendable feedback / ratings.

    I bought a "CMRR" or some blasted thing from "DK" several years ago, but its documentation was a black hole, instructions by serial and they kept those secret (part of the expensive Development Kit or whatever.)

    Publison,
    I'm well outside CHU's reception area. I'm familiar with their 300bps format. If you work out something for that, feel free to post about that for sure.
  • David BDavid B Posts: 591
    edited 2014-11-07 08:31
    I just read something on the WWV website that I hadn't realized, that 2 years ago WWVB changed their 60 kHz broadcast format, adding phase modulation to the signal in addition to the power modulation.

    That apparently broke some radio-controlled clocks, while others were able to absorb the new format with no ill effects.

    http://www.nist.gov/pml/div688/grp40/wwvb.cfm
  • PublisonPublison Posts: 12,366
    edited 2014-11-07 08:35
    David B wrote: »
    I just read something on the WWV website that I hadn't realized, that 2 years ago WWVB changed their 60 kHz broadcast format, adding phase modulation to the signal in addition to the power modulation.

    That apparently broke some radio-controlled clocks, while others were able to absorb the new format with no ill effects.

    http://www.nist.gov/pml/div688/grp40/wwvb.cfm

    Yes; PJ provided that link in post #2.
    reserved_01

    Waiting for my WWVB receivers from Inglaterra.

    Links --

    http://www.pvelectronics.co.uk/rftime/SYM-RFT-XX.pdf

    http://www.nist.gov/pml/div688/grp40/wwvb.cfm
  • Duane DegnDuane Degn Posts: 10,588
    edited 2014-11-07 20:06
    Dang nabbit, guess what I found while looking for parts for some other project? You guessed correctly. My radio time receiver kit I purchased from SparkFun several years ago. It was still in its unopened pink plastic.

    I opened it up and soldered some headers to it and procrastinated other projects while working on trying to receive time signals.

    Earlier today it didn't do anything interesting but tonight it started jabbering away at me.

    This is what it said:
    .....Pulse too long. Pulse LOW for 5 seconds and 46787888 clock ticks.Xa\a\0\0\0,a..
    Pulse too long. Pulse LOW for 2 seconds and 77346256 clock ticks.Xa\a\a\0,a./0,b,0,0\a\0\a\0,0,0,0\a\0,1,b\a\0,1,0,0,0,0,0,a\a\0
    ,M,b,0,1,a\0\b\0,0,1,a\b,1,1,0,0\a\0,0,0,0\a\0,1,1,1,0,0,1,1,0,0,0,0,1,1,0,0\a\b\0\0,0\a\0\a\0,a\a\b\0\a\b\a\0,1,0,0,a\0,0,0,0,1
    ,b,0,1,a\a\0,0,0,0,0,0,1\a\0\a\a\0,1,1,0,1,0,0,0,1\a\a\0,0,0,0,0,0,0\a\0\0\1,b\0\0\a\a\0,1\a\1,0,0,0,0,1,a\b\0,0,b,0,0,0,0,0\a\0
    \0\b,0,1,0,0,0\a\0\a\a\a\0,0,1,1\a\a\0,1,0,0,0,0,0,0,0,M,M,0,1,1,0,1,a\a\a\0,1,M,a\a\0,0,0,0,0,0,1,0\0\M,0,0,b\a\1,0,0,0\a\0,1,M
    ,0,0,1,0,0\a\0,0,1,0,M,0,1,0\a\0,0,0,0,a\0,1,b\a\0,1,0,0,0,a\a\0,0,0,b\a\1\b\a\1,0,0\a\0,0,0,0,0,M,0,0,0,0,0,0,0,1,1,b\a\0,0,1,1
    ,0,0,0,0,1,M,0,0,a\b\0,0,0,a\a\1,0,M,0\b\1,0,0\a\0,0,0,0,0\a\0\a\b\a\0,1,0\a\0,0,0,0,0,0,M,b\a\1,0,0,0,0,0,0,1,a\M,0,0,0,a\0\0,0
    ,0,a\a\b\1,b,0,0,1,1,0,0,0\a\a\a\0,1,0\b\0,0,1,0\a\0,0,0,1,0,1\a\0,1,0,0,0,0,0,0,1,b,0,1,0,0,a\0\a\0,0,0,a\a\1,M,1,0,a./0.......
    ...
    Input from radio has been HIGH for 10 seconds...........
    Input from radio has been HIGH for 20 seconds.
    

    The various characters are all listed in the constant section but here are the main characters seen above.

    If I didn't hold the radio in the correct position, I received the multiple second error messages.
    ZERO_CHARACTER = "0"
      ONE_CHARACTER = "1"
      MARKER_CHARACTER = "M"
      LESS_THAN_0_CHARACTER = "a"
      LESS_THAN_1_CHARACTER = "b"
      DELAY_MORE_THAN_SECOND_CHAR = "X"
          
      APPARENT_VALID_SECOND_CHAR = ","
      TOO_SHORT_2ND_CHARACTER = "\"
    
    
      SECONDS_TICKING_CHARACTER = "."
    

    I never received a full set of ones and zeros between to markers without some sort of timing error. Even though I'm not capturing the complete signal, I think it's promising.

    Once I can get the ones and zeros sorted out, I can start to decode the message. I'm using a circular buffer to hold the pulses but so far the program doesn't analyze more than one set of high and low pluses at a time.

    Here's the code in case any of you are interested (it's also attached to this post).
    DAT programName         byte "NistClock141107h", 0
    CON
    {{ ****** Public Notes ******
    
    
      An attempt to make sense of the output from
      a NIST Radio Clock Module.
    
    
    }}  
    CON
    { ****** Private Notes ******
    
    
      141107a Mirror input with LED output.
      07b Add terminal display.
      07f Some promise.
      07g Reverse pulse state.
      07g Works much better. Still getting extra characters
      (besides ones, zeros and marks).
      07h Clean up a bit to post to forum.
      
    }  
    CON ' Parent Constants                    
                         
      _clkmode = xtal1 + pll16x 
      _xinfreq = 5_000_000
    
    
      CLK_FREQ = ((_clkmode - xtal1) >> 6) * _xinfreq
      MICROSECOND = CLK_FREQ / 1_000_000
      MILLISECOND = CLK_FREQ / 1_000
    
    
      'max 32-bit positive 2_147_483_647
      ' 3_600 seconds per hour
      ' 86_400 seconds per day
      
      ALLOWED_ERROR = 100 * MILLISECOND
      ZERO_TIME = 200 * MILLISECOND
      MIN_ZERO_TIME = ZERO_TIME - ALLOWED_ERROR
      MAX_ZERO_TIME = ZERO_TIME + ALLOWED_ERROR
      ONE_TIME = 500 * MILLISECOND
      MIN_ONE_TIME = ONE_TIME - ALLOWED_ERROR
      MAX_ONE_TIME = ONE_TIME + ALLOWED_ERROR
      MARKER_TIME = 800 * MILLISECOND
      MIN_MARKER_TIME = MARKER_TIME - ALLOWED_ERROR
      MAX_MARKER_TIME = MARKER_TIME + ALLOWED_ERROR
      BIT_TIME = CLK_FREQ 
      MIN_BIT_TIME = BIT_TIME - ALLOWED_ERROR
      MAX_BIT_TIME = BIT_TIME + ALLOWED_ERROR
    
    
      BAD_BIT_TIME = BIT_TIME * 2
      
      ZERO_CHARACTER = "0"
      ONE_CHARACTER = "1"
      MARKER_CHARACTER = "M"
      LESS_THAN_0_CHARACTER = "a"
      LESS_THAN_1_CHARACTER = "b"
      LESS_THAN_MARKER_CHARACTER = "c"
      LESS_THAN_SECOND_CHARACTER = "d"
      ABOUT_ONE_SECOND_CHARACTER = "S"
      MORE_THAN_SECOND_CHARACTER = "_"
      PULSE_MORE_THAN_SECOND_CHAR = "x"
      DELAY_MORE_THAN_SECOND_CHAR = "X"
          
      APPARENT_VALID_SECOND_CHAR = ","
      TOO_LONG_2ND_CHARACTER = "/"
      TOO_SHORT_2ND_CHARACTER = "\"
      TOO_LONG_1ST_CHARACTER = "|"
    
    
      SECONDS_TICKING_CHARACTER = "."
      
      TIMED_PULSE_STATE = 1
      
      UPDATE_STATUS_SECONDS = 10
    
    
      BUFFER_SIZE = 100
      MAX_BUFFER_INDEX = BUFFER_SIZE - 1
      RADIO_IN_PIN = 0
      LED_MIRROR_PIN = 16
    
    
      DEBUG_BAUD = 115_200
      
    VAR
    
    
      long secondsBuffer[BUFFER_SIZE], cyclesBuffer[BUFFER_SIZE]
      long bufferHead, activeStateTime
    
    
      byte characterBuffer[BUFFER_SIZE], receptionFlag
      byte validPulseFlag
      
    OBJ
    
    
      Pst : "Parallax Serial Terminal"
      
    PUB Setup
      
      dira[LED_MIRROR_PIN] := 1
    
    
      Pst.Start(DEBUG_BAUD)
      
      Pst.Str(string(13, "programName = "))
      Pst.Str(@programName)
      Pst.Char(13)
      Main
      
    PUB Main | previousInput, frozenCnt
    
    
      previousInput := -1
      cyclesBuffer[bufferHead] := cnt
      
      repeat
        result := ina[RADIO_IN_PIN]
        frozenCnt := cnt
        outa[LED_MIRROR_PIN] := result
        if frozenCnt - cyclesBuffer[bufferHead] > CLK_FREQ
          Pst.Char(SECONDS_TICKING_CHARACTER)
          secondsBuffer[bufferHead]++
          cyclesBuffer[bufferHead] += CLK_FREQ
          if secondsBuffer[bufferHead] // UPDATE_STATUS_SECONDS == 0
            Pst.Str(string(13, "Input from radio has been "))
            if result
              Pst.Str(string("HIGH"))
            else
              Pst.Str(string("LOW"))
            Pst.Str(string(" for "))
            Pst.Dec(secondsBuffer[bufferHead])
            Pst.Str(string(" seconds."))
        if result <> previousInput
          previousInput := result
          cyclesBuffer[bufferHead] := frozenCnt - cyclesBuffer[bufferHead]
          characterBuffer[bufferHead] := GetCharacter(result, secondsBuffer[bufferHead], cyclesBuffer[bufferHead])
          Pst.Char(characterBuffer[bufferHead])
          bufferHead := AdvanceHead(bufferHead, MAX_BUFFER_INDEX)
          secondsBuffer[bufferHead] := 0
          cyclesBuffer[bufferHead] := frozenCnt
        
    PUB AdvanceHead(head, limit)
    
    
      if head => limit
        head := 0
      else
        head++
    
    
      result := head
    
    
    PUB GetCharacter(pinState, seconds, cycles) : character 
    
    
          
      if seconds < 2
        cycles += seconds * CLK_FREQ
      else
        Pst.Str(string(13, "Pulse too long. Pulse "))
        if pinState
          Pst.Str(string("HIGH"))
        else
          Pst.Str(string("LOW"))
        Pst.Str(string(" for "))
        Pst.Dec(seconds)
        Pst.Str(string(" seconds and "))
        Pst.Dec(cycles)
        Pst.Str(string(" clock ticks."))
        validPulseFlag := 0
        activeStateTime := BAD_BIT_TIME
        if pinState == TIMED_PULSE_STATE
          character := PULSE_MORE_THAN_SECOND_CHAR
        else
          character := DELAY_MORE_THAN_SECOND_CHAR
        return
          
      if pinState == TIMED_PULSE_STATE
        validPulseFlag := 1
        activeStateTime := cycles
        case cycles
          0..MIN_ZERO_TIME:
            character := LESS_THAN_0_CHARACTER
          MIN_ZERO_TIME..MAX_ZERO_TIME:
            character := ZERO_CHARACTER
          MAX_ZERO_TIME..MIN_ONE_TIME:
            character := LESS_THAN_1_CHARACTER
          MIN_ONE_TIME..MAX_ONE_TIME:
            character := ONE_CHARACTER
          MAX_ONE_TIME..MIN_MARKER_TIME:
            character := LESS_THAN_1_CHARACTER
          MIN_MARKER_TIME..MAX_MARKER_TIME:
            character := MARKER_CHARACTER
          MAX_MARKER_TIME..MIN_BIT_TIME:
            character := LESS_THAN_SECOND_CHARACTER
          MIN_BIT_TIME..MAX_BIT_TIME:
            character := ABOUT_ONE_SECOND_CHARACTER
          other:
            character := MORE_THAN_SECOND_CHARACTER
            validPulseFlag := 0
            activeStateTime := BAD_BIT_TIME
         
      elseif validPulseFlag 
        validPulseFlag := 0
        activeStateTime += cycles
        case activeStateTime
          0..MIN_BIT_TIME:
            character := TOO_SHORT_2ND_CHARACTER
          MIN_BIT_TIME..MAX_BIT_TIME:
            character := APPARENT_VALID_SECOND_CHAR
          other:
            character := TOO_LONG_2ND_CHARACTER
      else
        character := TOO_LONG_1ST_CHARACTER
    
  • Duane DegnDuane Degn Posts: 10,588
    edited 2014-11-07 21:46
    Okay, this is getting cool.

    I was able to get a good signal for over four minutes. The Prop and radio were being powered from the USB cable so my setup wasn't portable. I had to hold the setup at almost arms length away from me to get a good signal. After four minutes, my arm got too tired.

    Here's the output (it's from a functionally identical program to the one I posted1).
    programName = NistClock141107
    g|b\0,0,0,0\a\0,0./b\0./a./0./a\a,0./a...
    Pulse too long. Pulse LOW for 3 seconds and 69513968 clock ticks.Xa\a.....
    Pulse too long. Pulse LOW for 5 seconds and 4357424 clock ticks.Xa\a\0..
    Pulse too long. Pulse LOW for 2 seconds and 2029808 clock ticks.Xa..........
    Input from radio has been HIGH for 10 seconds..........
    Pulse too long. Pulse LOW for 19 seconds and 49233344 clock ticks.X0......
    Pulse too long. Pulse LOW for 6 seconds and 48520560 clock ticks.Xa\0\a\a\a\a\a\a\0\a\1\a\a\1\a\a\0\a\a\a\1\0/0\a\0,0,0,0,0\a\a\
    a\b\a\0\b\0\1\a\0\.S/0\0\1\a\0\a\0\a\a\a\a\a\a\a./a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\1\0,0,0,0,0,0,1,0,0,M,0,0,1,1,0,0,0,0,1,M,0,0,1,
    0,0,0,0,1,0,M,0,1,0,0,0,0,0,0,1,M,0,1,0,0,0,0,0,0,0,[COLOR=#ff0000]M,M[/COLOR],0,0,0,0,0,[COLOR=#00ff00]0,0,0[/COLOR],M,0,0,0,0,0,0,1,0,1,M,0,0,1,1,0,0,0,0,1,M,0,0,1,0,0,0,0,
    1,0,M,0,1,0,0,0,0,0,0,1,M,0,1,0,0,0,0,0,0,0,[COLOR=#ff0000]M,M[/COLOR],0,0,0,0,0,[COLOR=#00ff00]0,0,1[/COLOR],M,0,0,0,0,0,0,1,0,1,M,0,0,1,1,0,0,0,0,1,M,0,0,1,0,0,0,0,1,0,M,0,
    1,0,0,0,0,0,0,1,M,0,1,0,0,0,0,0,0,0,[COLOR=#ff0000]M,M[/COLOR],0,0,0,0,0,[COLOR=#00ff00]0,1,0[/COLOR],M,0,0,0,0,0,0,1,0,1,M,0,0,1,1,0,0,0,0,1,M,0,0,1,0,0,0,0,1,0,M,0,1,0,0,0,
    0,0,0,1,M,0,1,0,0,0,0,0,0,0,[COLOR=#ff0000]M,M[/COLOR],0,0,0,0,0,[COLOR=#00ff00]0,1,1[/COLOR],M,0,0,0,0,0,0,1,0,1,M,0,0,1,1,0,0,0,0,1,M,0,0,1,0,0,0,0,1,0,M,0,1,0,0,0,0,0,0,1,
    M,0,1,0,0,0,0,0,0,0,[COLOR=#ff0000]M,M[/COLOR],0,0,0,0,0,[COLOR=#00ff00]1,0,0[/COLOR],M,0,0,0,0,0,0,1,0,1,M,0,0,1,1,0,0,0,0,1,M,0,0,1,0,0,0,0,1,0,M,0,1,0,0,0,0,0,0,1,M,0,1,0,
    0,0,0,0,0,0,[COLOR=#ff0000]M,M[/COLOR],0,0,0,0,0,[COLOR=#00ff00]1,0,1[/COLOR],M,0,0,0,0.....
    Pulse too long. Pulse LOW for 5 seconds and 4657232 clock ticks.X0\0,a,0,a,a\a
    

    The good stuff is where the ones, zeros and "M"s show up.

    Apparently two markers"M,M" indicate the beginning of a frame. The first three binary numbers is the tens of minutes (zero in this case) and the next five bits are the minutes less than ten (0 through 5 are displayed).

    The NIST website has the info to decipher the rest of the bits.

    I don't think it will be too hard to decode the transmission but turning the code into a useful self correcting clock will be more challenging.

    1. I still had version "g" loaded in the EEPROM but the only difference between "g" and the "h" version I posted is I deleted a bunch of commented out code from the "h" version.
  • PJAllenPJAllen Banned Posts: 5,065
    edited 2014-11-08 04:58
    Well, well - look at you taking the ball and running with it.
    Good on ya, DD.

    Still, I anticipate Los Ingles. (I am in receipt of an order update, they've "been shipped.")
    David B wrote: »
    I just read something on the WWV website that I hadn't realized, that 2 years ago WWVB changed their 60 kHz broadcast format, adding phase modulation to the signal in addition to the power modulation.

    That apparently broke some radio-controlled clocks, while others were able to absorb the new format with no ill effects.

    This may account for the "attractive" pricing for these units.
    :eek:
    Won't know till we know.
  • tomcrawfordtomcrawford Posts: 1,126
    edited 2014-11-08 08:53
    For those of us who do not have an infinite supply of "stuff" and have to wait for orders from England, here is a WWVB simulator. This is the same as the one I posted in the other thread with a couple of fixes including no more 60-hour days. I am using it debug my decoder. You can have it generate incrementing time or send the same pattern over and over. It would be cool to have it running in a separate cog on the same Prop Chip as ones clock.

    As to the decoder: I have written a clock that keeps Greenwich (UTC) time in hours, minutes, seconds, and DayOfYear. That data gets fiddled to local time, date, month, DayOfWeek, and year, and displayed on a 2 x 16 LCD. I will add a WWVB decoder in a separate cog that reads UTC in hours, minutes, seconds, and DayOfYear, that being what WWVB provides. It will set a flag when it has good data which the propellor clock will use to overwrite the time it is keeping. The resulting display will be correct to within one second (neglecting LCD response time).

    The wiki article for WWVB describes the AM coding in detail. Basically, it transmits minutes, hours, DayOfYear, year, and a few others once a minute. DD is correct is saying that a double marker indicates the beginning of a frame.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2014-11-08 20:56
    I haven't had good reception so far today. I was able to successfully decode the hour and minute from the signal but date was decoded incorrectly.

    Here's the output from my latest program.
    Date: October 28, 2000
    Time: 04 46 01
    SOME_RECEPTION0WM,,\a\a\\
    

    The time here was 9:46 PM Standard Mountain Time.

    Obviously I need to fix the output formatting as well as the logic of the program.

    I hope to make my system portable tomorrow so I can go outside to see if I can get better reception.

    It's approaching the time of night when I've previously got good reception but I think I'm headed to bed. I'll try again tomorrow night.

    I've attached the buggy program used to generate the above output.

    I'm not there yet but I keep getting closer.
  • tomcrawfordtomcrawford Posts: 1,126
    edited 2014-11-09 09:48
    Here is my shot at a WWVB AM decoder. There is a "free-running" clock running in the top cog that keeps UTC time in the form secs, mins, ours, DayOfYear. It translates that time to California time (zone -8 this time of year) and prints the result on a LCD 2 x 16.

    There is a second cog that monitors a simulated WWVB signal. It uses pretty much brute force, finding two markers in a row (top of frame) and then watching the next 58 pulses. If any pulse is incorrect for its second, the cog just starts over, looking for a new frame. If all the pulses make sense, this cog overwrites the time the prop crystal is keeping, always at second number 54.

    This is working given an input that amounts to perfect WWVB reception (my simulator in a previous reply in this thread). I am anxiously awaiting my real WWVB receiver to see what I need to do (or what I *can* do). I am on the west slope of the Sierra Nevada range. I have a "atomic" clock that has always worked just fine as far as I know, so I have high hopes.

    Edit: I just realized I had uploaded an old version. I replaced it with the current version at about 10am Cal time. Sorry, my bad.
    1024 x 768 - 70K
  • SapphireSapphire Posts: 496
    edited 2014-11-09 10:07
    Tom,

    Nice job. What you are going to need to do is not quit the process if one bit is missing over the frame. That's a real possibility in even the best reception.

    The trick is to save each bit in an array, either 0, 1 or 2 (invalid) as you go through the minute. Some will be invalid, but that's okay as you will pick them up in the next minute. After 2-3 minutes, you'll receive all of the bits, just not all of them in one minute.

    You also have to update the array at the top of each frame so the good bits increment, otherwise the final time will be incorrect. If you miss the top of frame, either dump the array and start over, or increment it and wait for the next expected top of frame.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2014-11-09 10:22
    In general aren't we really only interested in the minutes?

    I'd think the two markers indicating the start of the message and then the minutes frame would be enough to update a clock that is slightly fast or slow. The other stuff isn't going to change much.
  • SapphireSapphire Posts: 496
    edited 2014-11-09 10:29
    Duane,

    After initial reception, yes. But on power-up, you might not know anything about the time and have to decode the entire frame. Plus, you should check for the DST bits to account for the hour shift.
  • PJAllenPJAllen Banned Posts: 5,065
    edited 2014-11-09 10:42
    All I can really do is twiddle my thumbs, but after acquiring time I was thinking that it could look for frame markers from that point and "watchdog" if two seconds had passed w/o getting a frame marker.
    That would speed things up instead of waiting for a whole frame and that delay.
    Got time data locked; if frame w/o interruption then incr; frame w/o interruption then incr;...

    And then deciding when it's appropriate to update an RTC or leave the Propeller-based clock in check.

    Does that make good sense?

    "Propeller-based clock," you ask?
    Well, yes, have a Propeller cog running an hh:mm:ss clock based on its crystal.
    Radical concept?
  • Duane DegnDuane Degn Posts: 10,588
    edited 2014-11-09 10:52
    PJ Allen wrote: »
    "Propeller-based clock," you ask?
    Well, yes, have a Propeller cog running an hh:mm:ss clock based on its crystal.
    Radical concept?

    You don't even need a separate cog for a Propeller RTC. Just have the main loop check to see if a second has passed and if a second has passed, update the time.

    I have the main loop call the method "CheckTime".
    PUB CheckTime 
    
      if cnt - secondTimer > CLK_FREQ
        AdvanceSeconds
        secondTimer += CLK_FREQ
        if displayTimeFlag
          DisplayTime
    
    
    

    The method also updates the display (by calling the "DisplayTime" method) with each new second.
  • PJAllenPJAllen Banned Posts: 5,065
    edited 2014-11-09 12:21
    I was meaning a cog running an hh:mm:ss clock and have no RTC (external IC).
    I think that would not drift more than 1 sec or so per day (but, please, don't anyone take me to task for my fantastic optimism).

    Maybe I should try my hand at that before I go shooting from the hip.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2014-11-09 12:29
    PJ Allen wrote: »
    I was meaning a cog running an hh:mm:ss clock and have no RTC (external IC).

    Yes, I understood. I think this is a rather common practice in Propeller land. (The code I posted, includes a software RTC.)

    I was pointing out you don't need a dedicated cog to run the software RTC, the main loop can just check the system clock ever so often to see if the seconds count of the software clock needs to be adjusted.
  • tomcrawfordtomcrawford Posts: 1,126
    edited 2014-11-09 13:40
    PJ Allen wrote: »
    I was meaning a cog running an hh:mm:ss clock and have no RTC (external IC).
    I think that would not drift more than 1 sec or so per day (but, please, don't anyone take me to task for my fantastic optimism).

    Maybe I should try my hand at that before I go shooting from the hip.

    That's how the one I posted works. The cog monitoring WWVB is just there to correct the prop clock at most once per minute.
  • tomcrawfordtomcrawford Posts: 1,126
    edited 2014-11-10 08:35
    As a practical matter, here is what NIST says about how often you need to correct your local clock:

    "Once your radio controlled clock has synchronized, it won’t decode the signal from WWVB again for a while. Most clocks only decode the signal once per day, but some do it more often (for example, every 6 hours). Those that decode the signal just once per day usually do it at midnight or in the very early hours of the morning, because the signal is easiest to receive when it is dark at both WWVB and at the site where the clock is located. In between synchronizations, the clocks keep time using their quartz crystal oscillators. A typical quartz crystal found in a radio controlled clock can probably keep time to within 1 second for a few days or longer. Therefore, you shouldn’t notice any error when you look at your clock display, since it will appear to be on the right second, even though it has probably gained or lost a fraction of a second since the last synchronization."

    http://www.nist.gov/pml/div688/grp40/radioclocks.cfm

    A crystal that is correct to within 10 ppm will be good to about a second per day. I guess it all depends on how well you have to keep time. I can remember when we needed +- 10 milliseconds. Nowadays, as the guy in "Soul of a New Machine" said, "...I will not consider any period of time shorter than a season".
  • Duane DegnDuane Degn Posts: 10,588
    edited 2014-11-10 09:26
    So when is the very beginning of the first second within the signal? I'm under the impression, it's at the beginning of the second marker indicating the start of a new cycle.

    I use a "possibleSync" variable to hold the beginning cnt setting as a bit is received. If the bit turns out to be the second marker, then I use the value stored in "possibleSync" to update the seconds time.
  • SapphireSapphire Posts: 496
    edited 2014-11-10 09:34
    Duane Degn wrote: »
    So when is the very beginning of the first second within the signal? I'm under the impression, it's at the beginning of the second marker indicating the start of a new cycle.

    Duane,

    Yes, the beginning of the first marker in the frame is the beginning of second 0. Subsequent markers are at the beginning of seconds 9, 19, 29, 39, 49 and 59.


    http://www.nist.gov/pml/div688/grp40/wwvbtimecode.cfm
  • tomcrawfordtomcrawford Posts: 1,126
    edited 2014-11-10 09:37
    Duane Degn wrote: »
    So when is the very beginning of the first second within the signal? I'm under the impression, it's at the beginning of the second marker indicating the start of a new cycle.

    I use a "possibleSync" variable to hold the beginning cnt setting as a bit is received. If the bit turns out to be the second marker, then I use it to update the seconds time.

    That is my understanding from reading the spec. The instant the signal strength decreases (the fancy new receivers from England {which I have ordered but not yet received} say it is inverted on their digital output) to begin the second marker is the beginning of the minute.

    I am currently correcting my "free-running" clock on the 54th second. Probably ought to be waiting until the 59th.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2014-11-10 09:41
    (the fancy new receivers from England {which I have ordered but not yet received} say it is inverted on their digital output)

    It's also inverted in the SparkFun radio. The pin goes high when the signal strength drops.
  • tomcrawfordtomcrawford Posts: 1,126
    edited 2014-11-11 14:26
    Okay, well I got it working. I found that I cannot have a running laptop within about 4 feet and that I have to be a LOT more tolerant about what pulse widths to accept. I ended up with nominal plus or minus 50 msec. But it does sync up within a couple of minutes (one to find top of frame and one to get the minutes, hours, DayOfYear, and year). It is currently mid afternoon here, which is said to be about the worst-case reception.
    1024 x 768 - 103K
  • Duane DegnDuane Degn Posts: 10,588
    edited 2014-11-12 06:51
    Very cool Tom.

    I'm surprised you received a clear signal during the day. I need to make my setup portable so I can try it away from all the noise near my PC. I'd think receiving the signal in Idaho shouldn't be any harder than receiving it in California.

    Is this the device you purchased? It looks like it's working well. If the device you purchased is the same as the one I linked to, I'll probably purchase one. I may want to make a radio syncing clock as a Christmas present for a family member.

    Do you mind posting your latest code? I'm not going to look at it right away, but once I have my clock working as I'd like, I'd like to compare my program against yours to see what sorts of things we did differently.

    Thanks for the update.
Sign In or Register to comment.