Shop OBEX P1 Docs P2 Docs Learn Events
Prop as controller for GPS disciplined oscillator — Parallax Forums

Prop as controller for GPS disciplined oscillator

jstjohnzjstjohnz Posts: 91
edited 2011-08-19 01:06 in Propeller 1
I'm thinking about using a prop as the controller for a GPSDO, where the 1PPS output of the GPS will 'discipline' a rubidium oscillator.

Basically, I need to lock the 1 PPS output of the GPS to the 10mhz output of the rubidium oscillator. The idea is that the rubidium oscillator has less jitter than the GPS signal, but the GPS signal has perfect long-term accuracy.

I have a couple of ideas, and am looking for input as to which might be the best approach.

My first thought was to divide the 10mhz down to something more manageable, then use a counter as a PLL to lock to the 1hz pulse. But I'm wondering if it would make more sense to use the rubidium source as the prop's clock (10mhz, PLLX8) and just count clock ticks between n cycles of the 1 hz signal to calculate the correction factor.

One issue is that we are talking about very small frequency variations. The rubidium oscillator can only be varied by +/- .15 hz, and the jitter of the 1 PPS output is typically <100ns.

I also need to generate my own 1 pps output.

With the prop clocked at 80mhz I have a max counter resolution of 12.5ns, so I will probably need a sample interval of 10, 100, or 1000 seconds.

Would a PWM output be feasible to control the rubidium oscillator, or do I need a DAC? The full range of the control voltage is 0-5V.

Comments

  • BeanBean Posts: 8,129
    edited 2011-08-15 04:42
    jstjohnz,
    Is this something you want to sell ? Or is it just for your personal use ?

    Bean
  • jstjohnzjstjohnz Posts: 91
    edited 2011-08-15 05:10
    This is for my personal use.
  • BeanBean Posts: 8,129
    edited 2011-08-15 05:25
    Okay, Then I can help you.

    I have done this exact thing for my employer using the SX chip (which made it alot harder).

    Basically, you want to divide the 10Mhz by some value (I think I used 128) that comes out to a whole number (10MHz / 128 = 78125), then feed that into a pin (let's call it pin A) and feed the GPS 1pps into another pin (we'll call it pin B). Then wait for pin B to go high (or low, whichever is more stable) and then start a counter until pin A goes high (or low). That measurement is the base time (let's assume it was 1,000 using a 80Mhz counter).

    Now keep measuring that time for say 20 cycles. You don't need to store all 20 values, just the last one. Let's say the 20th cycle returned a value of 1005. That means that your 10MHz is slow by (1005 - 1000) / 80MHz/20 seconds = 3.125 ppB. If the 20th value is less than the base value, then the 10MHz is fast.

    Instead of waiting a fixed number of seconds, I would keep getting values until the difference was greater than a certain value (say 10) then make an adjustment. But make sure wait at least 10 seconds because the GPS 1pps is very jittery. I was using a resolution-T GPS which is very stable, so you may need to have a higher minimum number of seconds if your GPS is less stable.

    I hope this helps, and let me know if you have any trouble.

    Bean
  • jstjohnzjstjohnz Posts: 91
    edited 2011-08-15 22:37
    Bean wrote: »
    Okay, Then I can help you.

    I have done this exact thing for my employer using the SX chip (which made it alot harder).

    Basically, you want to divide the 10Mhz by some value (I think I used 128) that comes out to a whole number (10MHz / 128 = 78125), then feed that into a pin (let's call it pin A) and feed the GPS 1pps into another pin (we'll call it pin B). Then wait for pin B to go high (or low, whichever is more stable) and then start a counter until pin A goes high (or low). That measurement is the base time (let's assume it was 1,000 using a 80Mhz counter).

    Now keep measuring that time for say 20 cycles. You don't need to store all 20 values, just the last one. Let's say the 20th cycle returned a value of 1005. That means that your 10MHz is slow by (1005 - 1000) / 80MHz/20 seconds = 3.125 ppB. If the 20th value is less than the base value, then the 10MHz is fast.

    Instead of waiting a fixed number of seconds, I would keep getting values until the difference was greater than a certain value (say 10) then make an adjustment. But make sure wait at least 10 seconds because the GPS 1pps is very jittery. I was using a resolution-T GPS which is very stable, so you may need to have a higher minimum number of seconds if your GPS is less stable.

    I hope this helps, and let me know if you have any trouble.

    Bean

    Thanks for the response.
    OK, I see where you're going with this. Basically you are measuring how much the phase offset changes over whatever time span you need to use to get a sufficiently large value. What was the frequency source that you were trying to sync with?

    For sake of discussion, let's say that the frequency error of the adjustable oscillator was 1x10^^-7. That would be 1 hz at 10mhz. The divided by 128 signal would 'slip' 1 cycle, or about 13us, or about 1000 counts every 128 seconds, so about 8 counts/second per 1x10^^-7 error. If I'm within 1x10^^-10 thats 8 counts per thousand seconds. So it seems as though I'm going to be looking at some pretty long intervals between corrections.

    What do you do if your reference (first) count is near 0 such that the possibility exists of the count going to 0 during the measurement? I suppose you could insert some type of calculated offset if your initial count was too low, something that would put you back near mid-cycle, so that your initial count is always somewhere near mid-span, or about 500 ticks.

    Would a PWM output suffice for controlling the oscillator? I'm guessing I will need 9 or 10 bits of resolution.
  • BeanBean Posts: 8,129
    edited 2011-08-16 04:34
    Yes, you got it.

    Yes, very small errors take many 100's of seconds to detect. A faster counter helps. Our SX design was to sync a 10MHz OCXO to GPS 1pps.

    About the roll-over problem. What I did was if the difference was greater than 1/2 the maximum then you subtract the maximum (1024) value from it.
    So if the base was 5 and the measurement was 1022.
    1022 - 5 = 1017
    1017 > 512 so use 1017 - 1024 = -7

    Another option is to just repeat the measurement when a roll-over occurs.

    To control the osc. I would use a DAC with at least 14 bit, but it depends on the pullability of the osc, and how close you need it to be.

    Bean
  • DogPDogP Posts: 168
    edited 2011-08-16 12:01
    I've also done something similar, for locking an OCXO to GPS. For Rb, we typically use the PRS10, which has this functionality built in. If you're looking for a good read, the theory of operation of their PLL is pretty good: http://www.thinksrs.com/products/PRS10.htm (click the manual link).

    In my implementation, I basically had two modes... one was simply a frequency locking loop to get the oscillator in the ballpark (similar to what Bean is describing)... once it was close enough (error accumulator hadn't reached the threshold in x seconds), it switched to phase locking, where it'd pick a phase and keep trying to drive that to 0. Of course it takes some tweaking and trial/error to get the gain of the loop just right.

    One thing I disagree on though is simply taking the last value. IMO, you should take them all and perform a least squares fit. Otherwise, your error is skewed by the error of the last measurement, rather than the averaged error of all the measurements. Using a Prop w/ a divided clock input may have more error than this introduces though, so it may not matter. I had an FPGA taking care of triggering and counting, which of course is more ideal than a uC.

    Just out of curiosity, which Rb module do you plan on using?

    Pat
  • jstjohnzjstjohnz Posts: 91
    edited 2011-08-16 22:51
    It's the Efratom LPRO-101. I may start out with a vcxo though, the bigger frequency swings would probably make testing go faster since things would be happening more quickly.
  • DogPDogP Posts: 168
    edited 2011-08-17 00:35
    A VCXO would work for initial testing, but the stability is pretty poor, and they're very sensitive to the environment, so you'll probably outgrow it pretty quickly (assuming you're final goal is really good accuracy out of your Rb). The PLL would certainly have a hard time trying to dial that in really close, but you can definitely test how well your loop does at recovery by simply blowing on the oscillator. Another option would be something like: http://cgi.ebay.com/Pletronics-26MHz-OCXO-Miniature-Oscillator-NEW-/140398082881?pt=LH_DefaultDomain_0&hash=item20b060bb41 ... it's cheap, an OCXO, and controlled similarly to your Rb... though of course 26MHz isn't your final frequency.

    I'm not sure how you plan on testing, or what equipment you have... but a really easy method would be to just have a counter count 10 million clock cycles from the oscillator and output a pulse. Reset the counter once with the GPS 1PPS so both 1PPS pulses approximately line up, and then let your loop do the work... if it's working well, your 10 million counter will track the PPS (watch them both on an oscope). While you could do this with discrete logic chips, an FPGA would make testing this extremely simple.

    Pat
  • jstjohnzjstjohnz Posts: 91
    edited 2011-08-18 18:53
    I found another rubidium oscillator that looks interesting, it's a Temex LPFRS. it allows adjustment of the frequency offset via RS232, so it would eliminate the need for the DAC.

    How does this sound as far as a method to measure the 1PPS error? I've not used prop counters before so bear with me...

    Drive prop CPU from rubidium oscillator's output. 10mhz and PLLX8 for 80mhz clock.

    Feed the 1PPS signal from the GPS to a pin on the prop. Set CTRA to count clock cycles when this pin is 0, set CTRB to count clock cycles if this pin is high.
    So one counter or the other is always accumulating clock counts.

    Initlz:
    cumerror = 0 'cumulative error in prop clocks
    time = 0
    wait for input =1
    clear counter A
    wait for input=0
    clear counter B

    loop:
    wait for input=1
    temp=ctrA 'get # of clocks counted while input was low
    ctrA=0 'then reset that counter

    wait for input=0
    temp=temp+ctrB 'add # of clocks while input = high
    ctrB=0 'reset that counter

    error = temp-80_000_000 'calc timing error over this one second interval
    cumerror = cumerror + error 'add this error to the cumulative error
    time = time +1 'incr seconds count

    So at any point I have a cumulative error in clock ticks and the time interval in which that error was accumulated.
    Once my total error reaches a certain threshhold, I would calculate a correction factor for the rubidium.
  • DogPDogP Posts: 168
    edited 2011-08-19 01:06
    I'm not totally familiar with the Prop counters (I've just never had a need to use them), but I think that would work to get a tick count. I guess you could also poll the pin and read CNT on the 1PPS edge, but I think the counter would be more accurate. And yeah, I think your algorithm will basically work... you'll just need to do some calculations to figure out the correct gain values for various corrections.

    I'd also have a frequency locking mode (where you clear the cumulative error after applying corrections) when it's way off (for initial startup, and any really large disturbance)... otherwise it'll be working hard (at the wrong frequency) trying to unroll all of the accumulated phase error. I'd also have a timeout where you compute and apply the correction rather than going only for error threshold (no point in being off 1ppb for 10 minutes when you could tell, and correct it, much sooner).

    Also, make sure that the Rb is locked before attempting to steer it.

    Pat
Sign In or Register to comment.