Re: [time-nuts] First success with very simple, very low cost GPSDO, under $8
Hi! If it is all the same for you, I prefer this thread continue "in the open" as I am interested both in using an Arduino-like for my first GPSDO and STM32 for event capture and timming. Regards, Edésio On Mon, Apr 21, 2014 at 04:29:35PM -0400, paul swed wrote: > Good afternoon very interested in the work you are doing with the STM board. > As I mentioned far earlier in this thread I am attempting to use it to > correct the BPSK WWVB signal here. Initial thoughts were using FORTH to > program the STM board. > Very curious what you are using as examples. > My experience in FORTH is from many years ago and have done very poorly at > C. But this may be the case to have something of interest to actually do. > In either language. > Regards > Paul > WB8TSL > > > On Mon, Apr 14, 2014 at 12:27 PM, d0ct0r wrote: > > > > > > > I was experimenting with the same setup for STM32 MCU. This microprocessor > > has accept the sine wave from external OCXO or GPSDO. No problem with this. > > The only thing: I was need to start MCU from slow "watch" crystal first. > > And then switch it to work to external one. In another case I got incorrect > > timing settings for MCU. Later, I decide to implement LTC6957-3 chip to > > "share" REFCLOCK source, since that chip has two equal CMOS-level outputs. > > Unfortunately I have no tool to measure the phase noise and jitters on > > each setup. > > > > > > > > > > It turns out all of this is built into the AVR chip. There is a counter > >> and logic to copy the current counter value to a register on a PPS pulse > >> raising edge.The counter keeps running and every second its value is > >> trapped. > >> > >> I can connect the OCXO and the PPS directly to the AVR pin. The AVR has > >> hardware (a fast comparator) to "square" a low amplitude sine wave and > >> trap > >> the counter on a zero crossing. So it looks like I can get rid of ALL > >> of > >> the external chips. The built in DAC is working well also but it needs > >> some external resisters and caps. > >> > >> No need for '74 FFs or '373' or counter chips.I do get precision > >> timing > >> with no time critical software, no 74xxx chips. > >> > > -- > > WBW, > > > > V.P. > > > > ___ > > time-nuts mailing list -- time-nuts@febo.com > > To unsubscribe, go to https://www.febo.com/cgi-bin/ > > mailman/listinfo/time-nuts > > and follow the instructions there. > > > ___ > time-nuts mailing list -- time-nuts@febo.com > To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts > and follow the instructions there. ___ time-nuts mailing list -- time-nuts@febo.com To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts and follow the instructions there.
Re: [time-nuts] First success with very simple, very low cost GPSDO, under $8
Actually GCC supporting Cortex. So, I am using Raisonance IDE plus GCC Toolchain as a development environment. My current project functional diagram is following: +--- STM32 -- (Pulse Counter, TTL Generator, DDS driver, GPSDO monitor) GPSDO--LTC6957-3--| || | +--- AD9852 -- VFO -> | | v +--- TADD3 -- (1PPS, TTL) --> As I'll finish it more or less, I'd like to compare the 1PPS which comes directly from GPSDO with 1PPS which I could create on MCU (and probably on DDS). As I mention before, each STM MCU comes with very useful Peripheral Library. That Library has tonnes of different examples. Regards, V.P. On 2014-04-21 16:29, paul swed wrote: Good afternoon very interested in the work you are doing with the STM board. As I mentioned far earlier in this thread I am attempting to use it to correct the BPSK WWVB signal here. Initial thoughts were using FORTH to program the STM board. Very curious what you are using as examples. My experience in FORTH is from many years ago and have done very poorly at C. But this may be the case to have something of interest to actually do. In either language. Regards Paul WB8TSL On Mon, Apr 14, 2014 at 12:27 PM, d0ct0r wrote: I was experimenting with the same setup for STM32 MCU. This microprocessor has accept the sine wave from external OCXO or GPSDO. No problem with this. The only thing: I was need to start MCU from slow "watch" crystal first. And then switch it to work to external one. In another case I got incorrect timing settings for MCU. Later, I decide to implement LTC6957-3 chip to "share" REFCLOCK source, since that chip has two equal CMOS-level outputs. Unfortunately I have no tool to measure the phase noise and jitters on each setup. It turns out all of this is built into the AVR chip. There is a counter and logic to copy the current counter value to a register on a PPS pulse raising edge. The counter keeps running and every second its value is trapped. I can connect the OCXO and the PPS directly to the AVR pin. The AVR has hardware (a fast comparator) to "square" a low amplitude sine wave and trap the counter on a zero crossing. So it looks like I can get rid of ALL of the external chips. The built in DAC is working well also but it needs some external resisters and caps. No need for '74 FFs or '373' or counter chips. I do get precision timing with no time critical software, no 74xxx chips. -- WBW, V.P. ___ time-nuts mailing list -- time-nuts@febo.com To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts [1] and follow the instructions there. Links: -- [1] https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts -- WBW, V.P. ___ time-nuts mailing list -- time-nuts@febo.com To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts and follow the instructions there.
Re: [time-nuts] First success with very simple, very low cost GPSDO, under $8
Perhaps this thread should go off line not to distract from the originators thread. Regards Paul. On Mon, Apr 21, 2014 at 4:29 PM, paul swed wrote: > Good afternoon very interested in the work you are doing with the STM > board. > As I mentioned far earlier in this thread I am attempting to use it to > correct the BPSK WWVB signal here. Initial thoughts were using FORTH to > program the STM board. > Very curious what you are using as examples. > My experience in FORTH is from many years ago and have done very poorly at > C. But this may be the case to have something of interest to actually do. > In either language. > Regards > Paul > WB8TSL > > > On Mon, Apr 14, 2014 at 12:27 PM, d0ct0r wrote: > >> >> >> I was experimenting with the same setup for STM32 MCU. This >> microprocessor has accept the sine wave from external OCXO or GPSDO. No >> problem with this. The only thing: I was need to start MCU from slow >> "watch" crystal first. And then switch it to work to external one. In >> another case I got incorrect timing settings for MCU. Later, I decide to >> implement LTC6957-3 chip to "share" REFCLOCK source, since that chip has >> two equal CMOS-level outputs. >> Unfortunately I have no tool to measure the phase noise and jitters on >> each setup. >> >> >> >> >> It turns out all of this is built into the AVR chip. There is a counter >>> and logic to copy the current counter value to a register on a PPS pulse >>> raising edge.The counter keeps running and every second its value is >>> trapped. >>> >>> I can connect the OCXO and the PPS directly to the AVR pin. The AVR has >>> hardware (a fast comparator) to "square" a low amplitude sine wave and >>> trap >>> the counter on a zero crossing. So it looks like I can get rid of ALL >>> of >>> the external chips. The built in DAC is working well also but it needs >>> some external resisters and caps. >>> >>> No need for '74 FFs or '373' or counter chips.I do get precision >>> timing >>> with no time critical software, no 74xxx chips. >>> >> -- >> WBW, >> >> V.P. >> >> ___ >> time-nuts mailing list -- time-nuts@febo.com >> To unsubscribe, go to https://www.febo.com/cgi-bin/ >> mailman/listinfo/time-nuts >> and follow the instructions there. >> > > ___ time-nuts mailing list -- time-nuts@febo.com To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts and follow the instructions there.
Re: [time-nuts] First success with very simple, very low cost GPSDO, under $8
Good afternoon very interested in the work you are doing with the STM board. As I mentioned far earlier in this thread I am attempting to use it to correct the BPSK WWVB signal here. Initial thoughts were using FORTH to program the STM board. Very curious what you are using as examples. My experience in FORTH is from many years ago and have done very poorly at C. But this may be the case to have something of interest to actually do. In either language. Regards Paul WB8TSL On Mon, Apr 14, 2014 at 12:27 PM, d0ct0r wrote: > > > I was experimenting with the same setup for STM32 MCU. This microprocessor > has accept the sine wave from external OCXO or GPSDO. No problem with this. > The only thing: I was need to start MCU from slow "watch" crystal first. > And then switch it to work to external one. In another case I got incorrect > timing settings for MCU. Later, I decide to implement LTC6957-3 chip to > "share" REFCLOCK source, since that chip has two equal CMOS-level outputs. > Unfortunately I have no tool to measure the phase noise and jitters on > each setup. > > > > > It turns out all of this is built into the AVR chip. There is a counter >> and logic to copy the current counter value to a register on a PPS pulse >> raising edge.The counter keeps running and every second its value is >> trapped. >> >> I can connect the OCXO and the PPS directly to the AVR pin. The AVR has >> hardware (a fast comparator) to "square" a low amplitude sine wave and >> trap >> the counter on a zero crossing. So it looks like I can get rid of ALL >> of >> the external chips. The built in DAC is working well also but it needs >> some external resisters and caps. >> >> No need for '74 FFs or '373' or counter chips.I do get precision >> timing >> with no time critical software, no 74xxx chips. >> > -- > WBW, > > V.P. > > ___ > time-nuts mailing list -- time-nuts@febo.com > To unsubscribe, go to https://www.febo.com/cgi-bin/ > mailman/listinfo/time-nuts > and follow the instructions there. > ___ time-nuts mailing list -- time-nuts@febo.com To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts and follow the instructions there.
Re: [time-nuts] First success with very simple, very low cost GPSDO, under $8
I was experimenting with the same setup for STM32 MCU. This microprocessor has accept the sine wave from external OCXO or GPSDO. No problem with this. The only thing: I was need to start MCU from slow "watch" crystal first. And then switch it to work to external one. In another case I got incorrect timing settings for MCU. Later, I decide to implement LTC6957-3 chip to "share" REFCLOCK source, since that chip has two equal CMOS-level outputs. Unfortunately I have no tool to measure the phase noise and jitters on each setup. It turns out all of this is built into the AVR chip. There is a counter and logic to copy the current counter value to a register on a PPS pulse raising edge.The counter keeps running and every second its value is trapped. I can connect the OCXO and the PPS directly to the AVR pin. The AVR has hardware (a fast comparator) to "square" a low amplitude sine wave and trap the counter on a zero crossing. So it looks like I can get rid of ALL of the external chips. The built in DAC is working well also but it needs some external resisters and caps. No need for '74 FFs or '373' or counter chips.I do get precision timing with no time critical software, no 74xxx chips. -- WBW, V.P. ___ time-nuts mailing list -- time-nuts@febo.com To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts and follow the instructions there.
Re: [time-nuts] First success with very simple, very low cost GPSDO, under $8
Your oscillator is on its way. I set it right on 10. MHz against a GPSDRb house standard. You will get a better waveform out if it sees about a 100 - 200 ohm termination, though the edge is nice and sharp with some peaking overshoot. You might get a bit more stability if you can add to the thermal insulation around the oscillator. Also, consider using the internal reference output on the pin marked n/c. It runs near 4.0 volts and is stable to ambient temp changes. Maybe put the whole thing in a Styrofoam container that has about one inch wall thickness. Regards, Tom - Original Message - From: "Chris Albertson" To: "Discussion of precise time and frequency measurement" ; "Magnus Danielson" Sent: Sunday, April 13, 2014 12:30 AM Subject: Re: [time-nuts] First success with very simple, very low cost GPSDO, under $8 On Sat, Apr 12, 2014 at 9:48 AM, Magnus Danielson < mag...@rubidium.dyndns.org> wrote: In fact a 5 bit counter is enough, and then a '373 to sample it. The enable to the 373 needs to be synchronous to the 5/10 MHz clock, so a pair of DFFs ('74) is needed to synchronize the PPS and another pair to create the single cycle enable. It turns out all of this is built into the AVR chip. There is a counter and logic to copy the current counter value to a register on a PPS pulse raising edge.The counter keeps running and every second its value is trapped. I can connect the OCXO and the PPS directly to the AVR pin. The AVR has hardware (a fast comparator) to "square" a low amplitude sine wave and trap the counter on a zero crossing. So it looks like I can get rid of ALL of the external chips. The built in DAC is working well also but it needs some external resisters and caps. No need for '74 FFs or '373' or counter chips.I do get precision timing with no time critical software, no 74xxx chips. -- Chris Albertson Redondo Beach, California ___ time-nuts mailing list -- time-nuts@febo.com To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts and follow the instructions there. ___ time-nuts mailing list -- time-nuts@febo.com To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts and follow the instructions there.
Re: [time-nuts] First success with very simple, very low cost GPSDO, under $8
On Sat, Apr 12, 2014 at 9:48 AM, Magnus Danielson < mag...@rubidium.dyndns.org> wrote: > > In fact a 5 bit counter is enough, and then a '373 to sample it. The > enable to the 373 needs to be synchronous to the 5/10 MHz clock, so a pair > of DFFs ('74) is needed to synchronize the PPS and another pair to create > the single cycle enable. > > It turns out all of this is built into the AVR chip. There is a counter and logic to copy the current counter value to a register on a PPS pulse raising edge.The counter keeps running and every second its value is trapped. I can connect the OCXO and the PPS directly to the AVR pin. The AVR has hardware (a fast comparator) to "square" a low amplitude sine wave and trap the counter on a zero crossing. So it looks like I can get rid of ALL of the external chips. The built in DAC is working well also but it needs some external resisters and caps. No need for '74 FFs or '373' or counter chips.I do get precision timing with no time critical software, no 74xxx chips. -- Chris Albertson Redondo Beach, California ___ time-nuts mailing list -- time-nuts@febo.com To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts and follow the instructions there.
Re: [time-nuts] First success with very simple, very low cost GPSDO, under $8
Hi, On 10/04/14 06:43, Tom Van Baak wrote: You are right in the I don't even need data cycles. All I want is the error which is 5,000,000 minus the count. this is hopefully zero. Correct. Keep the counter running. No need to zero it, ever. Use differential measurements. Essentially you are using binary modulus arithmetic. BTW a trick for zero-dead-time counters is to let the counters running and just sample them. This fits very well with the work description for the counter in a GPSDO. This would be easier if we have a 32 bit counter that could be reset to zero each second. In the past I think people have built counters like this but now I can buy a $3.80 Arduino that does the counting, ADC and DAC and computer USB interface. So I put up with a harder to use 16-bit nonresetable counter Chris, In applications like this, never reset a counter to zero; this opens chances for off-by-one errors and cycle slips. Just compute differences. The start-up value of the timer is irrelevant. Moreover, 32-bits is unnecessary. Perhaps you didn't understand Bob's posting. Even 16-bits is more than enough. Let me explain. You only need enough bits to cover the worst case OCXO frequency drift or the worst case GPS jitter error, per second. For example, if your OCXO stays accurate to 1 ppm it can't possibly drift more than 1 us per second. Similarly, it's a safe assumption that your GPS 1PPS stays within 1 us of correct time. Therefore, the maximum number of 100 ns ticks you will be off in any second is +/-10. So even a 8-bit counter is enough. Does this make sense now? In fact a 5 bit counter is enough, and then a '373 to sample it. The enable to the 373 needs to be synchronous to the 5/10 MHz clock, so a pair of DFFs ('74) is needed to synchronize the PPS and another pair to create the single cycle enable. If you were building a general purpose arbitrary frequency counter, then a resetable 32-bit counter would be nice. But you're not. A GPSDO is a special case where you know the frequency will always be very close to 5 or 10 MHz every second. So you only need a few bits to measure the error each second. To use your decimal example, if the measurements are mostly 500 but sometimes 499 or 501 you only need to look at the last digit for your error. In hex this would be 4C4B40, 4C4B3F, 4C4B41, only the bottom two bits are needed (0, F, or 1). The bottom line is you don't need timer interrupts, you don't need time. You don't need 32-bits. You probably don't need 16-bits. You don't need semaphores. All you're interested in is how far off the oscillator is each second. One interrupt (for the GPS 1PPS) is all you need. If your CPU has a capture register you don't need interrupts at all. Then you don't need volatile either. Since your error is limited to +100 and -100 you can use 8-bit integers. You don't need to test for 30 hours; instead the code will be simple enough that it is air tight by design, not by luck. You will avoid interrupt collisions by not having more than one interrupt; you don't have to enable or disable interrupts either. You'll be surprised how simple it all gets. If you use a simple SR flip-flop to hold the state if there is a new value or not. When a value is sampled, it is set. The software then polls that bit and if it is set, it reads the sampled counter, sets the R bit and then clears it. As long as you poll regularly you will not miss or double-read a value. It's fairly easy to decouple the hard timing requirements to looser timing requirements if you just care about a few details. Cheers, Magnus ___ time-nuts mailing list -- time-nuts@febo.com To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts and follow the instructions there.
Re: [time-nuts] First success with very simple, very low cost GPSDO, under $8
Correct, your code example is the traditional way to keep track of elapsed time without long-term rounding error, although it's usually not attributed to Bézier. My bad ! I messed up Bezier and Bresenham line algorithm, which I was using for generating one average timed period from any other timed period (like the PIC timer0 overflow period, for example). Not sure if you've been following the whole thread, though -- the problem with timer interrupt code is that it can, and will on rare occasion, conflict with 1PPS rising edge pin interrupts. On a microcontroller, for best precision, the solution is to get rid of the timer interrupts, or get rid of the 1PPS interrupts, or both. Secondly, you cannot share multi-byte variables between interrupt level and main level without synchronization or arbitration. I am not familiar with Arduino. STM32, for sure, has interrupt priority. But than it will not be 8$ project. ;-) The best results I achieve using DMA. Timer updating the buffer variable(s) in background and its not using interrupts for it. So, I could read the current value of counter any time. At least I got good results for this approach when I connect MCU clock to GPSDO and tried to measure the signal from external OCXO. I got perfect 10 Mhz at that time. Your code snippet is a good example of what is subtle and dangerous, and dare I say, wrong. You are updating long t_besier in an interrupt handler. Any main level code using t_besier faces byte carry corruption in the multi-byte value of t_besier. True, this works fine on a 32- or 64-bit cpu, but not on an 8- or 16-bit cpu. Hmm... - Original Message - From: "d0ct0r" To: Sent: Thursday, April 10, 2014 10:12 AM Subject: Re: [time-nuts] First success with very simple, very low cost GPSDO, under $8 I am not sure about Arduino, but probably it too has so-called "timer overflow interrupt". If so, then its possible to use that other interrupt and some "long" (lets say 32-bit) RAM variable to accumulate real value of counter. In one of my project I was using timer overflow and Besier method to make good 1 minutes intervals. volatile signed long t_besier = 1200L; interrupt void TPM2OV_ISR(void) { TPM2SC = TPM2SC; if (TPM2SC_TOF) TPM2SC_TOF=0; t_besier -= 65536L; if(t_besier < 0) { t_besier += 1200L; t_time++; } } ___ time-nuts mailing list -- time-nuts@febo.com To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts and follow the instructions there. -- WBW, V.P. ___ time-nuts mailing list -- time-nuts@febo.com To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts and follow the instructions there.
Re: [time-nuts] First success with very simple, very low cost GPSDO, under $8
Hi Vlad, Correct, your code example is the traditional way to keep track of elapsed time without long-term rounding error, although it's usually not attributed to Bézier. Not sure if you've been following the whole thread, though -- the problem with timer interrupt code is that it can, and will on rare occasion, conflict with 1PPS rising edge pin interrupts. On a microcontroller, for best precision, the solution is to get rid of the timer interrupts, or get rid of the 1PPS interrupts, or both. Secondly, you cannot share multi-byte variables between interrupt level and main level without synchronization or arbitration. Your code snippet is a good example of what is subtle and dangerous, and dare I say, wrong. You are updating long t_besier in an interrupt handler. Any main level code using t_besier faces byte carry corruption in the multi-byte value of t_besier. True, this works fine on a 32- or 64-bit cpu, but not on an 8- or 16-bit cpu. /tvb - Original Message - From: "d0ct0r" To: Sent: Thursday, April 10, 2014 10:12 AM Subject: Re: [time-nuts] First success with very simple, very low cost GPSDO, under $8 > > I am not sure about Arduino, but probably it too has so-called "timer > overflow interrupt". If so, then its possible to use that other > interrupt and some "long" (lets say 32-bit) RAM variable to accumulate > real value of counter. > > In one of my project I was using timer overflow and Besier method to > make good 1 minutes intervals. > > volatile signed long t_besier = 1200L; > > interrupt void TPM2OV_ISR(void) > { > TPM2SC = TPM2SC; > if (TPM2SC_TOF) > TPM2SC_TOF=0; > t_besier -= 65536L; > if(t_besier < 0) { > t_besier += 1200L; > t_time++; > } > } > ___ time-nuts mailing list -- time-nuts@febo.com To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts and follow the instructions there.
Re: [time-nuts] First success with very simple, very low cost GPSDO, under $8
I am not sure about Arduino, but probably it too has so-called "timer overflow interrupt". If so, then its possible to use that other interrupt and some "long" (lets say 32-bit) RAM variable to accumulate real value of counter. In one of my project I was using timer overflow and Besier method to make good 1 minutes intervals. volatile signed long t_besier = 1200L; interrupt void TPM2OV_ISR(void) { TPM2SC = TPM2SC; if (TPM2SC_TOF) TPM2SC_TOF=0; t_besier -= 65536L; if(t_besier < 0) { t_besier += 1200L; t_time++; } } On 2014-04-09 23:10, Chris Albertson wrote: Bob, Yes, that is kind of how it works. The timer is only read once per second. After reading it we subtract whatever was the count in the previous sample to get the number of cycles in this last second. There is no accurate way to reset the timer at the start of the second. So we let it run "forever". The 16-bit timer actually over flows many times per second. The maximum value it ever gets to is about 65,536. (actually 2^16 - 1)The counter will never reach 10,000,000. (but actually we count after a divide by 2 so 5,000,000 is the target number) As it turns out even in a perfect world the counter value every second is some random value between zero and 65535. Because when the overflows happen depend in the exact microsecond I applied power to the system., that is my arbitrary "zero" and I count up from there overflowing back to zero about 76.6 times per second Every second we capture whatever the timer value is and compute "delts cycles" You are right in the I don't even need data cycles. All I want is the error which is 5,000,000 minus the count. this is hopefully zero. This would be easier if we have a 32 bit counter that could be reset to zero each second. In the past I think people have built counters like this but now I can buy a $3.80 Arduino that does the counting, ADC and DAC and computer USB interface. So I put up with a harder to use 16-bit nonresetable counter On Wed, Apr 9, 2014 at 6:33 PM, Bob Stewart wrote: Have you considered reading the timer only at PPS? You don't need to keep track of the actual count. You just need to keep track of the difference between counts at each PPS. Resolution isn't a problem since the difference in the lower 16 bits is a fixed number for your purpose. IOW, 10,000,000 is 0x989680. You're only interested in the 0x9680. If there's a difference in two successive timer counts of 0x9680, then you know you counted 10,000,000, unless your oscillator is capable of running at one of the other values that gives 0x9680 as the lower two bytes. Bob From: Chris Albertson To: Discussion of precise time and frequency measurement Sent: Wednesday, April 9, 2014 6:35 PM Subject: Re: [time-nuts] First success with very simple, very low cost GPSDO, under $8 On Wed, Apr 9, 2014 at 1:04 PM, Tom Harris wrote: Another point with the software is that your handler for the PPS just reads the counter. This gives an offset between the PPS edge and the value read, as your software takes time to respond to the interrupt and read the counter. In your code, it doesn't matter as you only have one interrupt. Actually there are two interrupts. One is for PPS and the other is for overflow of the 16-bit counter. This over flow happens about 76 times per seconds. However, if you have another interrupt enabled, this could run after the PPS pulse but before the handler runs, giving you a very rare jitter. A better way would be to use the input capture feature to read the timer into a capture register. Then the interrupt handler has until the next edge to read the capture register. Do you know how to do this. I don't see any way to capture the timer value other then reading it with software. The timer capture register is 16 bits and is set atomically after each timer increment but I don't see a way to make an external interrupt pin capture a timer. The two interrupts do bump into each other about roughly every 100 seconds but I can detect that. I think I'll just ignore that second. -- Chris Albertson Redondo Beach, California ___ time-nuts mailing list -- time-nuts@febo.com To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts and follow the instructions there. ___ time-nuts mailing list -- time-nuts@febo.com To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts and follow the instructions there. -- WBW, V.P. ___ time-nuts mailing list -- time-nuts@febo.com To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts and follow the instructions there.
Re: [time-nuts] First success with very simple, very low cost GPSDO, under $8
In my case, the cold-start frequency of my OCXO with EFC at midpoint was off sufficiently far that I needed a minimum number of remainder bits to know which way to initially steer it. Don't recall the exact number I needed, but it was more than eight at 10 MHz. Like this design, I had 16 bits to work with, which gave me a usable range. > On Apr 10, 2014, at 11:35, Brian Lloyd wrote: > > On Wed, Apr 9, 2014 at 11:43 PM, Tom Van Baak wrote: > >>> You are right in the I don't even need data cycles. All I want is the >>> error which is 5,000,000 minus the count. this is hopefully zero. >> >> Correct. Keep the counter running. No need to zero it, ever. Use >> differential measurements. Essentially you are using binary modulus >> arithmetic. > > Chinese remainder theorem. Use that and stop worrying about how big your > word is. Since we have these really great integer divisors we can use > between 1e7 and 1e0, it becomes trivial. Your counter word only needs to be > large enough to handle the maximum possible accumulated error in an > interval. In fact, you probably can get by comfortably with an 8-bit > counter. > > -- > Brian Lloyd, WB6RQN/J79BPL > 706 Flightline Drive > Spring Branch, TX 78070 > br...@lloyd.com > +1.916.877.5067 > ___ > time-nuts mailing list -- time-nuts@febo.com > To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts > and follow the instructions there. ___ time-nuts mailing list -- time-nuts@febo.com To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts and follow the instructions there.
Re: [time-nuts] First success with very simple, very low cost GPSDO, under $8
On Wed, Apr 9, 2014 at 11:43 PM, Tom Van Baak wrote: > > You are right in the I don't even need data cycles. All I want is the > > error which is 5,000,000 minus the count. this is hopefully zero. > > Correct. Keep the counter running. No need to zero it, ever. Use > differential measurements. Essentially you are using binary modulus > arithmetic. > Chinese remainder theorem. Use that and stop worrying about how big your word is. Since we have these really great integer divisors we can use between 1e7 and 1e0, it becomes trivial. Your counter word only needs to be large enough to handle the maximum possible accumulated error in an interval. In fact, you probably can get by comfortably with an 8-bit counter. -- Brian Lloyd, WB6RQN/J79BPL 706 Flightline Drive Spring Branch, TX 78070 br...@lloyd.com +1.916.877.5067 ___ time-nuts mailing list -- time-nuts@febo.com To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts and follow the instructions there.
Re: [time-nuts] First success with very simple, very low cost GPSDO, under $8
Tom Harris On 10 April 2014 16:35, Chris Albertson wrote: > To many "ifs" and "you could...". The Arduino is what it is. There > is no capture register, no interrupt priorities and the counter is... > There certainly is an input capture, and it makes the code EASIER to understand, as you know that the timer will be captured on the next cycle after the PPS edge, not when the current instruction has finished and the time 1 overflow interrupt has exited (forgot about that one). This forum post should get you started. Sure the Arduino is a prettly limited processor but it is more than enough for this job. ___ time-nuts mailing list -- time-nuts@febo.com To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts and follow the instructions there.
Re: [time-nuts] First success with very simple, very low cost GPSDO, under $8
> But I still need to count all the cycles in the second and can't just let a > 8 or 16 bit counter run free. The reason is I don't know where the > overflow happens. Overflow is not in sync with PPS. > OK this might work. I hope it does as it would allow a bit of code to be > removed. Let's see... > The system powers up, I enable the 8-bit counter and then assign an > interrupt handler to the PPS and enable the PPS interrupt and I get the very > first PPS interrupt and notice the counter vale is 67. > At the next interrupt the counter is 82 > With only these two numbers 67 and 82 and knowing the counter is 8 bits how > to I know the "error" which is the number of cycles different from 500. > Or more simply: "after reading the 82 how to I adjust the DAC?" > If you can spell it out I'll try it. But I bet you need one more number: > the count of the times the 8-bit counter overflowed. > OK we might be able to assume a number of overflows because there are tight > bounds on the PPS and OCXO performance. ... I think it will be obvious after you see it. The basic idea is to do everything mod 256. I think your current scheme is roughly: read the counter (including overflows) subtract the previous counter subtract 500 (0x4C4B40) the answer should be -1, 0, or +1 If things are way off, it might be 4 or 5 bits plus a sign bit. To do that with just an 8 bit counter, subtract the bottom 8 bits of 500 There might be X or X+1 overflows in the main counter. There can also be an overflow when you subtract the previous counter and/or when you subtract 500. I think the total number of overflows will be the same each second. How big is your counter plus overflows? 24 bits? (that covers 500) 32 bits? Eventually, the "read the counter (including overflows)" step is going to overflow. But then there will be an overflow when you do the subtract the previous counter step. -- These are my opinions. I hate spam. ___ time-nuts mailing list -- time-nuts@febo.com To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts and follow the instructions there.
Re: [time-nuts] First success with very simple, very low cost GPSDO, under $8
The key is not to worry about overflows. Let them happen. Don't count them. Don't prevent them. Fixed point binary arithmetic is wonderful. Here we're only concerned with the modulus or remainder. If a 16-bit timer is counting at 5 MHz and its value is 0x, then one second later its value will be 0x+0x4B40. This because 500/65536 = 76.2939453125 = 76 + 19264/65536 and 19264 = 0x4B40. In other words, if you know the oscillator frequency is really close to 5 MHz and you know the 1PPS period is really close to 1 second, then the difference between timer now and timer a second ago will always be right around 0x4B40. This greatly simplifies the code, as it boils down to: error = TCNT1now - TCNT1then - 0x4B40. The decimal equivalent of this is to consider if your car had only a 2 digit odometer. If you expect to drive 123 miles every week, do you have to count odometer "overflows"? How do you tell if you drove 125 miles or 120 miles instead of 123? Easy. Just subtract successive readings and see how far you are from 23. That's the error value. Another analogy is a wrist watch. If you need to time something that takes about 195 seconds, you can essentially ignore the hour and minute hand, and look only at the seconds hand. Your events should occur about 15 seconds on the dial apart. If it's a bit more or less than 15 seconds, that's the error value. /tvb - Original Message - From: Chris Albertson To: Discussion of precise time and frequency measurement Cc: Tom Van Baak ; Hal Murray Sent: Thursday, April 10, 2014 12:11 AM Subject: Re: [time-nuts] First success with very simple, very low cost GPSDO, under $8 On Wed, Apr 9, 2014 at 11:18 PM, Hal Murray wrote: t...@leapsecond.com said: > You only need enough bits to cover the worst case OCXO frequency drift or > the worst case GPS jitter error, per second. For example, if your OCXO stays > accurate to 1 ppm it can't possibly drift more than 1 us per second. > Similarly, it's a safe assumption that your GPS 1PPS stays within 1 us of > correct time. Therefore, the maximum number of 100 ns ticks you will be off > in any second is +/-10. So even a 8-bit counter is enough. Does this make > sense now? Am I confused or did you forget to add the 2 errors to cover the case when they both happen during the same second? 2 us or a count of 20 is still tiny, even for an 8 bit counter. I think what you are saying is that the error can be expressed in about five bits. That is right. But I still need to count all the cycles in the second and can't just let a 8 or 16 bit counter run free. The reason is I don't know where the overflow happens. Overflow is not in sync with PPS. OK this might work. I hope it does as it would allow a bit of code to be removed. Let's see... The system powers up, I enable the 8-bit counter and then assign an interrupt handler to the PPS and enable the PPS interrupt and I get the very first PPS interrupt and notice the counter vale is 67. At the next interrupt the counter is 82 With only these two numbers 67 and 82 and knowing the counter is 8 bits how to I know the "error" which is the number of cycles different from 500. Or more simply: "after reading the 82 how to I adjust the DAC?" If you can spell it out I'll try it. But I bet you need one more number: the count of the times the 8-bit counter overflowed. OK we might be able to assume a number of overflows because there are tight bounds on the PPS and OCXO performance. One problem is I know for sure the overflow rate is not a fixed number per second. The 16-bit timer overflow happens 5000/65536 times per second and an 8-bit timer overflows 500/256 times per second. Neather in an integer. It might work, then I can get rid of counting overflows. -- Chris Albertson Redondo Beach, California ___ time-nuts mailing list -- time-nuts@febo.com To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts and follow the instructions there.
Re: [time-nuts] First success with very simple, very low cost GPSDO, under $8
A couple more comments on the Arduino... > > 1) Have you checked for glitches in your dual-DAC system? The Arduino API > is forcing you to make two successive calls to analogWrite(). I wonder if > there might be a glitch when the LSB carries/borrows into the MSB, since > each PWM is configured separately. You can check this with a test version > of your code that linearly sweeps through all possible DAC values and then > continuously measure the output voltage with a high-res voltmeter. > The 16-bit DAC has more resolution then my Fluke volt meter. I tested the DAC by generating triangle waves but any glitches would be hard to see. I think what makes this work is the very heavy analog filter. It goes into a CRC "pi" filter made with a 100K resister and two 4.7 uf caps. The PWM on both outputs uses the same clock The the pulses are in perfect phase What likely does mess it up is the resisters are not precision and the step sizes are not right. One idea I had was to not treat this as a 16-bit value. I might thnk of it as an 8-bit fine adjustment DAC with an 8-bit bias DAC. I need some method to test the DAC. I running blind now. > 2) Once you get rid of the unnecessary timer interrupt and have just the > GPS 1PPS interrupt, realize that since all you do is a PID calculation and > DAC update once a second, you can simply move that code to the interrupt > handler. That further avoids any contention between main and interrupt > code, since loop() has nothing to do. > I really do have to keep the interrupt handler short. The arduino does lots in the foreground, like PWM and serial data. This that LOOK simple like adding two numbers take time because this is an 8-bit CPU and even a 16-bit add is done is software. A multiply for the PID is way to long. The AVR lacks even an 8x8 multiply unit and has to use shits and addition in a loop. > 3) Please consider using the ATmega input capture feature rather than a > rising edge interrupt. The trouble with doing precise timing with > interrupts is that, in AVR chips at least, there is some latency and > jitter, depending if a multi-cycle instruction was in progress. You can > avoid this by using hardware timer/capture registers. To find examples > search for words like: Arduino timer ICR1H ICR1L > > 4) If you use (ICR1H) ICR1L you don't even need to use interrupts since > the value is frozen until the next edge. I mean, you could poll if the code > is simpler that way. Then your GPSDO is all in loop() with no interrupts at > all. It's hard to get much simpler than that. > I'm going to eventually use the TIC which is connected to the 74HC4046 PPL chip. I need a PPS interrupt for that. Also "loop" maybe e slow once I add a user interface and LCD screen and I will at some point need to read sawtooth from the GPS and I will also want to monitor the stays of the GPS > > /tvb > > ___ > time-nuts mailing list -- time-nuts@febo.com > To unsubscribe, go to > https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts > and follow the instructions there. > -- Chris Albertson Redondo Beach, California ___ time-nuts mailing list -- time-nuts@febo.com To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts and follow the instructions there.
Re: [time-nuts] First success with very simple, very low cost GPSDO, under $8
On Wed, Apr 9, 2014 at 11:18 PM, Hal Murray wrote: > > t...@leapsecond.com said: > > You only need enough bits to cover the worst case OCXO frequency drift or > > the worst case GPS jitter error, per second. For example, if your OCXO > stays > > accurate to 1 ppm it can't possibly drift more than 1 us per second. > > Similarly, it's a safe assumption that your GPS 1PPS stays within 1 us of > > correct time. Therefore, the maximum number of 100 ns ticks you will be > off > > in any second is +/-10. So even a 8-bit counter is enough. Does this make > > sense now? > > Am I confused or did you forget to add the 2 errors to cover the case when > they both happen during the same second? 2 us or a count of 20 is still > tiny, even for an 8 bit counter. > > I think what you are saying is that the error can be expressed in about five bits. That is right. But I still need to count all the cycles in the second and can't just let a 8 or 16 bit counter run free. The reason is I don't know where the overflow happens. Overflow is not in sync with PPS. OK this might work. I hope it does as it would allow a bit of code to be removed. Let's see... The system powers up, I enable the 8-bit counter and then assign an interrupt handler to the PPS and enable the PPS interrupt and I get the very first PPS interrupt and notice the counter vale is 67. At the next interrupt the counter is 82 With only these two numbers 67 and 82 and knowing the counter is 8 bits how to I know the "error" which is the number of cycles different from 500. Or more simply: "after reading the 82 how to I adjust the DAC?" If you can spell it out I'll try it. But I bet you need one more number: the count of the times the 8-bit counter overflowed. OK we might be able to assume a number of overflows because there are tight bounds on the PPS and OCXO performance. One problem is I know for sure the overflow rate is not a fixed number per second. The 16-bit timer overflow happens 5000/65536 times per second and an 8-bit timer overflows 500/256 times per second. Neather in an integer. It might work, then I can get rid of counting overflows. -- Chris Albertson Redondo Beach, California ___ time-nuts mailing list -- time-nuts@febo.com To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts and follow the instructions there.
Re: [time-nuts] First success with very simple, very low cost GPSDO, under $8
>> You only need enough bits to cover the worst case OCXO frequency drift or >> the worst case GPS jitter error, per second. For example, if your OCXO stays >> accurate to 1 ppm it can't possibly drift more than 1 us per second. >> Similarly, it's a safe assumption that your GPS 1PPS stays within 1 us of >> correct time. Therefore, the maximum number of 100 ns ticks you will be off >> in any second is +/-10. So even a 8-bit counter is enough. Does this make >> sense now? > > Am I confused or did you forget to add the 2 errors to cover the case when > they both happen during the same second? 2 us or a count of 20 is still > tiny, even for an 8 bit counter. Hal, Yes, thanks, for worst case, add them. Also include a +/- 1 count error for the timer/counter. In reality it might be hard to say for certain what the max oscillator or max GPS jitter is. Are the numbers min/max, or 1-sigma, or 3-sigma, etc.? I used 1 us as a very generous example. But as you see, the number of bits you need to hold the time interval error is still very small. Chris, A couple more comments on the Arduino... 1) Have you checked for glitches in your dual-DAC system? The Arduino API is forcing you to make two successive calls to analogWrite(). I wonder if there might be a glitch when the LSB carries/borrows into the MSB, since each PWM is configured separately. You can check this with a test version of your code that linearly sweeps through all possible DAC values and then continuously measure the output voltage with a high-res voltmeter. 2) Once you get rid of the unnecessary timer interrupt and have just the GPS 1PPS interrupt, realize that since all you do is a PID calculation and DAC update once a second, you can simply move that code to the interrupt handler. That further avoids any contention between main and interrupt code, since loop() has nothing to do. 3) Please consider using the ATmega input capture feature rather than a rising edge interrupt. The trouble with doing precise timing with interrupts is that, in AVR chips at least, there is some latency and jitter, depending if a multi-cycle instruction was in progress. You can avoid this by using hardware timer/capture registers. To find examples search for words like: Arduino timer ICR1H ICR1L 4) If you use (ICR1H) ICR1L you don't even need to use interrupts since the value is frozen until the next edge. I mean, you could poll if the code is simpler that way. Then your GPSDO is all in loop() with no interrupts at all. It's hard to get much simpler than that. /tvb ___ time-nuts mailing list -- time-nuts@febo.com To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts and follow the instructions there.
Re: [time-nuts] First success with very simple, very low cost GPSDO, under $8
To many "ifs" and "you could...". The Arduino is what it is. There is no capture register, no interrupt priorities and the counter is 16-bits and the overflow actually takes one cycle. The code is posted. You can read it. Every second it does what is suggested and computers the difference in cycles from 500. Mostly it gets zero. It ran for close to 100,000 continuous seconds without a glitch and then the OCXO failed. There is really no problem that requires a "fix". (other than an ovenized crystal that only works well when it's cold) The goal was to have minimally complex design to use as a baseline. The real experiment begins AFTER this. That is to add one "improvement" at a time and see what is gained in performance. So I think I have every flavor of sophistication backed out. I am only counting cycles and the PI contents are only roughly tuned. I'm at the point where if one more thing is removed it stops working. That is the baseline. One thing I added was the "I" term. I had just a "P" controller but had to move to PI because P would not lock even after one hour and if I moved the gain up it would over shoot and never lock. Adding "I" was only 3 lines of C code and makes it lock in a few minutes. On Wed, Apr 9, 2014 at 9:43 PM, Tom Van Baak wrote: >> You are right in the I don't even need data cycles. All I want is the >> error which is 5,000,000 minus the count. this is hopefully zero. > > Correct. Keep the counter running. No need to zero it, ever. Use differential > measurements. Essentially you are using binary modulus arithmetic. > >> This would be easier if we have a 32 bit counter that could be reset >> to zero each second. In the past I think people have built counters >> like this but now I can buy a $3.80 Arduino that does the counting, >> ADC and DAC and computer USB interface. So I put up with a harder to >> use 16-bit nonresetable counter > > Chris, > > In applications like this, never reset a counter to zero; this opens chances > for off-by-one errors and cycle slips. Just compute differences. The start-up > value of the timer is irrelevant. > > Moreover, 32-bits is unnecessary. Perhaps you didn't understand Bob's > posting. Even 16-bits is more than enough. Let me explain. > > You only need enough bits to cover the worst case OCXO frequency drift or the > worst case GPS jitter error, per second. For example, if your OCXO stays > accurate to 1 ppm it can't possibly drift more than 1 us per second. > Similarly, it's a safe assumption that your GPS 1PPS stays within 1 us of > correct time. Therefore, the maximum number of 100 ns ticks you will be off > in any second is +/-10. So even a 8-bit counter is enough. Does this make > sense now? > > If you were building a general purpose arbitrary frequency counter, then a > resetable 32-bit counter would be nice. But you're not. A GPSDO is a special > case where you know the frequency will always be very close to 5 or 10 MHz > every second. So you only need a few bits to measure the error each second. > > To use your decimal example, if the measurements are mostly 500 but > sometimes 499 or 501 you only need to look at the last digit for your > error. In hex this would be 4C4B40, 4C4B3F, 4C4B41, only the bottom two bits > are needed (0, F, or 1). > > The bottom line is you don't need timer interrupts, you don't need time. You > don't need 32-bits. You probably don't need 16-bits. You don't need > semaphores. All you're interested in is how far off the oscillator is each > second. One interrupt (for the GPS 1PPS) is all you need. If your CPU has a > capture register you don't need interrupts at all. Then you don't need > volatile either. Since your error is limited to +100 and -100 you can use > 8-bit integers. You don't need to test for 30 hours; instead the code will be > simple enough that it is air tight by design, not by luck. You will avoid > interrupt collisions by not having more than one interrupt; you don't have to > enable or disable interrupts either. You'll be surprised how simple it all > gets. > > /tvb > > > ___ > time-nuts mailing list -- time-nuts@febo.com > To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts > and follow the instructions there. -- Chris Albertson Redondo Beach, California ___ time-nuts mailing list -- time-nuts@febo.com To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts and follow the instructions there.
Re: [time-nuts] First success with very simple, very low cost GPSDO, under $8
t...@leapsecond.com said: > You only need enough bits to cover the worst case OCXO frequency drift or > the worst case GPS jitter error, per second. For example, if your OCXO stays > accurate to 1 ppm it can't possibly drift more than 1 us per second. > Similarly, it's a safe assumption that your GPS 1PPS stays within 1 us of > correct time. Therefore, the maximum number of 100 ns ticks you will be off > in any second is +/-10. So even a 8-bit counter is enough. Does this make > sense now? Am I confused or did you forget to add the 2 errors to cover the case when they both happen during the same second? 2 us or a count of 20 is still tiny, even for an 8 bit counter. -- These are my opinions. I hate spam. ___ time-nuts mailing list -- time-nuts@febo.com To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts and follow the instructions there.
Re: [time-nuts] First success with very simple, very low cost GPSDO, under $8
> You are right in the I don't even need data cycles. All I want is the > error which is 5,000,000 minus the count. this is hopefully zero. Correct. Keep the counter running. No need to zero it, ever. Use differential measurements. Essentially you are using binary modulus arithmetic. > This would be easier if we have a 32 bit counter that could be reset > to zero each second. In the past I think people have built counters > like this but now I can buy a $3.80 Arduino that does the counting, > ADC and DAC and computer USB interface. So I put up with a harder to > use 16-bit nonresetable counter Chris, In applications like this, never reset a counter to zero; this opens chances for off-by-one errors and cycle slips. Just compute differences. The start-up value of the timer is irrelevant. Moreover, 32-bits is unnecessary. Perhaps you didn't understand Bob's posting. Even 16-bits is more than enough. Let me explain. You only need enough bits to cover the worst case OCXO frequency drift or the worst case GPS jitter error, per second. For example, if your OCXO stays accurate to 1 ppm it can't possibly drift more than 1 us per second. Similarly, it's a safe assumption that your GPS 1PPS stays within 1 us of correct time. Therefore, the maximum number of 100 ns ticks you will be off in any second is +/-10. So even a 8-bit counter is enough. Does this make sense now? If you were building a general purpose arbitrary frequency counter, then a resetable 32-bit counter would be nice. But you're not. A GPSDO is a special case where you know the frequency will always be very close to 5 or 10 MHz every second. So you only need a few bits to measure the error each second. To use your decimal example, if the measurements are mostly 500 but sometimes 499 or 501 you only need to look at the last digit for your error. In hex this would be 4C4B40, 4C4B3F, 4C4B41, only the bottom two bits are needed (0, F, or 1). The bottom line is you don't need timer interrupts, you don't need time. You don't need 32-bits. You probably don't need 16-bits. You don't need semaphores. All you're interested in is how far off the oscillator is each second. One interrupt (for the GPS 1PPS) is all you need. If your CPU has a capture register you don't need interrupts at all. Then you don't need volatile either. Since your error is limited to +100 and -100 you can use 8-bit integers. You don't need to test for 30 hours; instead the code will be simple enough that it is air tight by design, not by luck. You will avoid interrupt collisions by not having more than one interrupt; you don't have to enable or disable interrupts either. You'll be surprised how simple it all gets. /tvb ___ time-nuts mailing list -- time-nuts@febo.com To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts and follow the instructions there.
Re: [time-nuts] First success with very simple, very low cost GPSDO, under $8
On Wed, Apr 9, 2014 at 11:03 AM, Chris Albertson wrote: > On Wed, Apr 9, 2014 at 2:08 AM, Hal Murray > wrote: > > > > > > Also any code that accesses them needs to do so with interrupts turned > > > off... otherwise you can wind up with corrupted values. > > > > Forgot if I made this point but in a GPSDO when the interrupt is caused by > the PPS, the interrupts are in effect off for 0.9 seconds after each > interrupt. The software can assume an interrupt will never happen less > then one second after an interrupt. So the software does all the variable > access within millisecond after each interrupt. > > These micro controllers are actually much easier to deal with than a > general purpose multi-tasking operating system. There is far less > non-determinism. Indeed. I was just thinking the same thing. It's much easier to deal with an interrupt routine updating variables than multiple threads fighting over them... I just had to replace a mutex lock with an atomic exchange to avoid a deadlock in my code at work. Orin. ___ time-nuts mailing list -- time-nuts@febo.com To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts and follow the instructions there.
Re: [time-nuts] First success with very simple, very low cost GPSDO, under $8
Bob, Yes, that is kind of how it works. The timer is only read once per second. After reading it we subtract whatever was the count in the previous sample to get the number of cycles in this last second. There is no accurate way to reset the timer at the start of the second. So we let it run "forever". The 16-bit timer actually over flows many times per second. The maximum value it ever gets to is about 65,536. (actually 2^16 - 1)The counter will never reach 10,000,000. (but actually we count after a divide by 2 so 5,000,000 is the target number) As it turns out even in a perfect world the counter value every second is some random value between zero and 65535. Because when the overflows happen depend in the exact microsecond I applied power to the system., that is my arbitrary "zero" and I count up from there overflowing back to zero about 76.6 times per second Every second we capture whatever the timer value is and compute "delts cycles" You are right in the I don't even need data cycles. All I want is the error which is 5,000,000 minus the count. this is hopefully zero. This would be easier if we have a 32 bit counter that could be reset to zero each second. In the past I think people have built counters like this but now I can buy a $3.80 Arduino that does the counting, ADC and DAC and computer USB interface. So I put up with a harder to use 16-bit nonresetable counter On Wed, Apr 9, 2014 at 6:33 PM, Bob Stewart wrote: > Have you considered reading the timer only at PPS? You don't need to keep > track of the actual count. You just need to keep track of the difference > between counts at each PPS. Resolution isn't a problem since the difference > in the lower 16 bits is a fixed number for your purpose. IOW, 10,000,000 is > 0x989680. You're only interested in the 0x9680. If there's a difference in > two successive timer counts of 0x9680, then you know you counted 10,000,000, > unless your oscillator is capable of running at one of the other values that > gives 0x9680 as the lower two bytes. > > Bob > > > >> >> From: Chris Albertson >>To: Discussion of precise time and frequency measurement >>Sent: Wednesday, April 9, 2014 6:35 PM >>Subject: Re: [time-nuts] First success with very simple, very low cost GPSDO, >>under $8 >> >> >>On Wed, Apr 9, 2014 at 1:04 PM, Tom Harris wrote: >>> Another point with the software is that your handler for the PPS just reads >>> the counter. This gives an offset between the PPS edge and the value read, >>> as your software takes time to respond to the interrupt and read the >>> counter. In your code, it doesn't matter as you only have one interrupt. >> >>Actually there are two interrupts. One is for PPS and the other is >>for overflow of the 16-bit counter. This over flow happens about 76 >>times per seconds. >>> However, if you have another interrupt enabled, this could run after the >>> PPS pulse but before the handler runs, giving you a very rare jitter. >>> A better way would be to use the input capture feature to read the timer >>> into a capture register. Then the interrupt handler has until the next edge >>> to read the capture register. >> >>Do you know how to do this. I don't see any way to capture the timer >>value other then reading it with software. The timer capture register >>is 16 bits and is set atomically after each timer increment but I >>don't see a way to make an external interrupt pin capture a timer. >> >>The two interrupts do bump into each other about roughly every 100 >>seconds but I can detect that. I think I'll just ignore that second. >> >>-- >> >>Chris Albertson >>Redondo Beach, California >>___ >>time-nuts mailing list -- time-nuts@febo.com >>To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts >>and follow the instructions there. >> >> >> > ___ > time-nuts mailing list -- time-nuts@febo.com > To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts > and follow the instructions there. -- Chris Albertson Redondo Beach, California ___ time-nuts mailing list -- time-nuts@febo.com To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts and follow the instructions there.
Re: [time-nuts] First success with very simple, very low cost GPSDO, under $8
Have you considered reading the timer only at PPS? You don't need to keep track of the actual count. You just need to keep track of the difference between counts at each PPS. Resolution isn't a problem since the difference in the lower 16 bits is a fixed number for your purpose. IOW, 10,000,000 is 0x989680. You're only interested in the 0x9680. If there's a difference in two successive timer counts of 0x9680, then you know you counted 10,000,000, unless your oscillator is capable of running at one of the other values that gives 0x9680 as the lower two bytes. Bob > > From: Chris Albertson >To: Discussion of precise time and frequency measurement >Sent: Wednesday, April 9, 2014 6:35 PM >Subject: Re: [time-nuts] First success with very simple, very low cost GPSDO, >under $8 > > >On Wed, Apr 9, 2014 at 1:04 PM, Tom Harris wrote: >> Another point with the software is that your handler for the PPS just reads >> the counter. This gives an offset between the PPS edge and the value read, >> as your software takes time to respond to the interrupt and read the >> counter. In your code, it doesn't matter as you only have one interrupt. > >Actually there are two interrupts. One is for PPS and the other is >for overflow of the 16-bit counter. This over flow happens about 76 >times per seconds. >> However, if you have another interrupt enabled, this could run after the >> PPS pulse but before the handler runs, giving you a very rare jitter. >> A better way would be to use the input capture feature to read the timer >> into a capture register. Then the interrupt handler has until the next edge >> to read the capture register. > >Do you know how to do this. I don't see any way to capture the timer >value other then reading it with software. The timer capture register >is 16 bits and is set atomically after each timer increment but I >don't see a way to make an external interrupt pin capture a timer. > >The two interrupts do bump into each other about roughly every 100 >seconds but I can detect that. I think I'll just ignore that second. > >-- > >Chris Albertson >Redondo Beach, California >___ >time-nuts mailing list -- time-nuts@febo.com >To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts >and follow the instructions there. > > > ___ time-nuts mailing list -- time-nuts@febo.com To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts and follow the instructions there.
Re: [time-nuts] First success with very simple, very low cost GPSDO, under $8
On Wed, Apr 9, 2014 at 1:04 PM, Tom Harris wrote: > Another point with the software is that your handler for the PPS just reads > the counter. This gives an offset between the PPS edge and the value read, > as your software takes time to respond to the interrupt and read the > counter. In your code, it doesn't matter as you only have one interrupt. Actually there are two interrupts. One is for PPS and the other is for overflow of the 16-bit counter. This over flow happens about 76 times per seconds. > However, if you have another interrupt enabled, this could run after the > PPS pulse but before the handler runs, giving you a very rare jitter. > A better way would be to use the input capture feature to read the timer > into a capture register. Then the interrupt handler has until the next edge > to read the capture register. Do you know how to do this. I don't see any way to capture the timer value other then reading it with software. The timer capture register is 16 bits and is set atomically after each timer increment but I don't see a way to make an external interrupt pin capture a timer. The two interrupts do bump into each other about roughly every 100 seconds but I can detect that. I think I'll just ignore that second. -- Chris Albertson Redondo Beach, California ___ time-nuts mailing list -- time-nuts@febo.com To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts and follow the instructions there.
[time-nuts] First success with very simple, very low cost GPSDO, under $8
Well, where interrupts are involved, NEVER assume something about how the code SHOULD/MIGHT be working. It is easy enough to disable interrupts before accessing the volatile variables and restore them afterwards. This is by far the simplest and most reliable way to do it correctly (no messy message passing/semaphores/smoke signals/etc). unsigned char sreg; // variable to save the processor status register in sreg = SREG; // save current processor status register cli(); // disable interrupts in the status register // access variables here SREG = sreg; // restore original interrupt state ito the processor status register ___ time-nuts mailing list -- time-nuts@febo.com To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts and follow the instructions there.
Re: [time-nuts] First success with very simple, very low cost GPSDO, under $8
Another point with the software is that your handler for the PPS just reads the counter. This gives an offset between the PPS edge and the value read, as your software takes time to respond to the interrupt and read the counter. In your code, it doesn't matter as you only have one interrupt. However, if you have another interrupt enabled, this could run after the PPS pulse but before the handler runs, giving you a very rare jitter. A better way would be to use the input capture feature to read the timer into a capture register. Then the interrupt handler has until the next edge to read the capture register. Just an idea, you might be able to assign the interrupt priority for the PPS edge to a priority above all others to avoid this problem, but this is getting complex. Simpler to handle it by hardware. To debug jitter, you could make your mainline set an output line, and watch the delay between the PPS and the line on a CRO set on infinite persistance, just to check if it works. Tom Harris On 9 April 2014 13:05, Chris Albertson wrote: > I just had some success with a new GPSDO based very much on Lars Walenius' > design > > I cut his design and his software down to make it even more simple and cost > less. The controller is now well under $8. The software is also much > simpler and easy to read even if you are not a "software guy". > > Lars' design and software will out perform mine. There is no question on > that. But my goal was to first build a VERY low cost and more importantly > easy to understand and replicate GPSDO. In this first version of the GPSDO > I did not implement the TIC. I only count how many cycles occur from the > local oscillator between PPS pulses and then use a PI control to adjust the > DAC. > > Performance. I am open to suggestions on how I can characterize the > performance. This project is being designed for a beginner who would not > have exotic test equipment. I would call the performance "not as bad as > you might guess". I have had the output of this GSPDP and the 10MHz signal > from a Trimble Thunderbolt both up on my Tek 365 100MHz dual channel scope > for about 26 hours and they seem to more or less keep in phase. The GPSDO > waveform drifts one way then the other. I can see the short term stability > is good only to about the E-9 level but of course being locked to a GPS it > has very good long term stability. And this with about $8 worth of parts > and build in about one hour. (Not counting the power supply (a plug-in wall > wort type), OCXO and GPS) Also the controller software is intentionally > simplified. The E-9 is an estimate. I'm looking for a good way to measure > it with simple tools. > > Plans: I will add features and sophistication one step at a time and I > will try to document the process. Even as I add more my goal is still (1) > an understandable design that anyone can build with no special tools or > equipment and (2) cost. With equal importance to each. The next step is > too add some refinements to the software, different modes and so one. But > this stripped down version will be the "introduction" for a tutorial on > GPSDO design. > > Goals: I want to document this as a design others can build. Even if they > are new to all of this. I also want to keep the software open and easy to > modify in the hope that others will actually modify it and post their mods > here for kind of peer review > > Parts list: 74HC390, Aruindo "pro mini", two small electrolytic caps and > three resisters. That's it. > The Mini is $3.71 with free shipping the 74hc390 was $1. Other parts where > in the junk box. > > A software listing is attached. I used some of Lars' code but added a few > ideas of my own and removed 80% of the functionality in preference to > clarity. I'm not 100% done. I know I can make if more readable. > -- > > Chris Albertson > Redondo Beach, California > > ___ > time-nuts mailing list -- time-nuts@febo.com > To unsubscribe, go to > https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts > and follow the instructions there. > ___ time-nuts mailing list -- time-nuts@febo.com To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts and follow the instructions there.
Re: [time-nuts] First success with very simple, very low cost GPSDO, under $8
To further Brian's comment: you have to keep in mind that the interrupt routine interrupts the mainline code, and not the other way around. So, you set a semaphore in your mainline code and your interrupt routine checks to see if that's set when it starts, or at least before it uses any variables you have protected by the semaphore. In my code, I just set a bit immediately before changing two critical variables, and reset it immediately afterward. If the interrupt routine finds the semaphore set, it returns and does nothing till next time. This prevents any question about whether the interrupt routine can update or even use the variables in question. And not that it makes any difference, but I went down much the same path as Chris is going down with my non-TIC code. Maybe Chris will find something that I couldn't find. For me, there was always something just out of reach to prevent it from working properly. That "something" may just be that I was using a nav receiver instead of a timing receiver. I wound up with a very accurate counter; but it was still just a counter when all was said and done. Bob > > From: Brian Lloyd >To: Discussion of precise time and frequency measurement >Sent: Wednesday, April 9, 2014 3:17 PM >Subject: Re: [time-nuts] First success with very simple, very low cost GPSDO, >under $8 > > >On Wed, Apr 9, 2014 at 1:34 PM, Hal Murray wrote: > >> >> > But I think you over looked one point that makes this project easier: We >> > KNOW 100% for certain that the interrupts happen only once per second. >> So >> > the foreground code knows for certain it has exclusive access to shared >> > variables for a given period of time. There is zero chance of a problem >> in >> > the next .999 seconds after an interrupt. >> >> Actually, you don't know that. You know that's the way it's supposed to >> work, but there are all sorts of ways that things can (and do) screw up and >> making that sort of assumption can lead to problems that are very hard to >> debug. >> > >So create a semaphore that says who owns the variable. Or, better still, us >a message-passing executive. > >-- >Brian Lloyd, WB6RQN/J79BPL >706 Flightline Drive >Spring Branch, TX 78070 >br...@lloyd.com >+1.916.877.5067 > >___ >time-nuts mailing list -- time-nuts@febo.com >To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts >and follow the instructions there. > > > ___ time-nuts mailing list -- time-nuts@febo.com To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts and follow the instructions there.
Re: [time-nuts] First success with very simple, very low cost GPSDO, under $8
On Wed, Apr 9, 2014 at 1:34 PM, Hal Murray wrote: > > > But I think you over looked one point that makes this project easier: We > > KNOW 100% for certain that the interrupts happen only once per second. > So > > the foreground code knows for certain it has exclusive access to shared > > variables for a given period of time. There is zero chance of a problem > in > > the next .999 seconds after an interrupt. > > Actually, you don't know that. You know that's the way it's supposed to > work, but there are all sorts of ways that things can (and do) screw up and > making that sort of assumption can lead to problems that are very hard to > debug. > So create a semaphore that says who owns the variable. Or, better still, us a message-passing executive. -- Brian Lloyd, WB6RQN/J79BPL 706 Flightline Drive Spring Branch, TX 78070 br...@lloyd.com +1.916.877.5067 ___ time-nuts mailing list -- time-nuts@febo.com To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts and follow the instructions there.
Re: [time-nuts] First success with very simple, very low cost GPSDO, under $8
On Wed, Apr 9, 2014 at 11:18 AM, Hal Murray wrote: > > I think you can turn that into a feature. Suppose you start with the > DAC/OCXO running at exactly 10 MHz, and the phasing such that you are right > on. Due to noise, the last count will be early and get counted half the > time. The other half of the time, it will be late and get counted in the > next second. So if you don't see that sort of noise occasionally, you know > you are drifting off from a phase that was "right on". > > Have you calibrated the DAC yet? If you bump it up by 1 count, how long does > it take for the OCXO to drift by a cycle? > > > Another low cost way to get better resolution would be to use 2 counters and > a delay line. Pick the length of the delay to be well above the noise level. I'm out of counters. The chip only has one 16-bit counter. I think I can do all the averaging and dithering using only the PI controller. The "I" term in effect handles dithering. When the error toggles from plus to minus I goes to zero and the DAC is not changed much. But if a few more pluses than minus happen the I term goes positive and slowly pulls the DAC up. I don't have to use "if statements" in the code. The effect is I see a dither between 499 and 500 which cases the DAC to move up then I see a long row of 500 samples which is the perfect count. But then I see a 500 and 501 dither which puss the DAC down and I get many more 500 samples. It mostly hangs out at 500 So I have to disagree, differing is not what I want. I want to be dead-on 500 cycles per second (that is 10MHZ after the divide by two in the 74HC390)Then as soon as I see a few 501 samples I need to very slowly go bcd down until a 499 is detected 10 or 15 seconds late. This is what is actually happening. It seems to work with no "if" statements. What I think I need is to fine tune the PID constants and likely have a few sets of constants. For example I find a larger I causes the system to very quickly get a lock but also the large I causes overshoot.I may implement different modes, like "fast lock" and "best short term" and "best long term" Maybe even have a PID auto tune mode where I measure the system response. I am only using a tiny fraction of the available space for code. There is room for many thousands more lines of C code. The line count is only a couple dozen at present. -- Chris Albertson Redondo Beach, California ___ time-nuts mailing list -- time-nuts@febo.com To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts and follow the instructions there.
Re: [time-nuts] First success with very simple, very low cost GPSDO, under $8
If my one interrupt per second assumption is wrong the GPS is badly broken and nothing I can do will make the gpsdo work. In a final system I should try and detect violations of the assumption and go into hold over mode. That said I tried a test where I took the interrupt line in my hand and rubbed it on a piece of metal and triggered tens of thousands of random interrupts per second. The code works even in this case. What happens in this code is that inside the interrupt handler the ONLY thing it does is with interrupts disabled, it copies data to global variables then exits. The copy is in effect atomic. You don't see all that is happening because the Aruino environment handles some of this. It writes about 40 bytes then sets a semaphore-like bit that says in effect "get it now", the foreground software spin-locks on this bit, gets the data and resets the bit. I've been know to make gross errors in software design and forget stuff but I should understand this. I've done a bit of graduate level work in computer science and worked a few years on operating system internals. In general you are correct but in this case the system is so darn simple that all the code fits on one screen and I can read the whole thing without scrolling, Ok I have a 27" screen but still there is not a lot going on here. On Wed, Apr 9, 2014 at 11:34 AM, Hal Murray wrote: > >> But I think you over looked one point that makes this project easier: We >> KNOW 100% for certain that the interrupts happen only once per second. So >> the foreground code knows for certain it has exclusive access to shared >> variables for a given period of time. There is zero chance of a problem in >> the next .999 seconds after an interrupt. > > Actually, you don't know that. You know that's the way it's supposed to > work, but there are all sorts of ways that things can (and do) screw up and > making that sort of assumption can lead to problems that are very hard to > debug. > > > It would be interesting to compare the size and complexity of simple code > that doesn't have much error checking with defensive code that checks all > sorts of things. Sometimes a sanity check is a good way to explain a subtle > point. > > -- > These are my opinions. I hate spam. > > > > ___ > time-nuts mailing list -- time-nuts@febo.com > To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts > and follow the instructions there. -- Chris Albertson Redondo Beach, California ___ time-nuts mailing list -- time-nuts@febo.com To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts and follow the instructions there.
Re: [time-nuts] First success with very simple, very low cost GPSDO, under $8
> But I think you over looked one point that makes this project easier: We > KNOW 100% for certain that the interrupts happen only once per second. So > the foreground code knows for certain it has exclusive access to shared > variables for a given period of time. There is zero chance of a problem in > the next .999 seconds after an interrupt. Actually, you don't know that. You know that's the way it's supposed to work, but there are all sorts of ways that things can (and do) screw up and making that sort of assumption can lead to problems that are very hard to debug. It would be interesting to compare the size and complexity of simple code that doesn't have much error checking with defensive code that checks all sorts of things. Sometimes a sanity check is a good way to explain a subtle point. -- These are my opinions. I hate spam. ___ time-nuts mailing list -- time-nuts@febo.com To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts and follow the instructions there.
Re: [time-nuts] First success with very simple, very low cost GPSDO, under $8
> Actaully I don't care much about an "off by one" count because the problem > is corrected in the next second. If I happen to miss a count one second the > very next second this shows up as an extra count.I notice that something > like this happens every few hundred seconds. I think you can turn that into a feature. Suppose you start with the DAC/OCXO running at exactly 10 MHz, and the phasing such that you are right on. Due to noise, the last count will be early and get counted half the time. The other half of the time, it will be late and get counted in the next second. So if you don't see that sort of noise occasionally, you know you are drifting off from a phase that was "right on". Have you calibrated the DAC yet? If you bump it up by 1 count, how long does it take for the OCXO to drift by a cycle? Another low cost way to get better resolution would be to use 2 counters and a delay line. Pick the length of the delay to be well above the noise level. -- These are my opinions. I hate spam. ___ time-nuts mailing list -- time-nuts@febo.com To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts and follow the instructions there.
Re: [time-nuts] First success with very simple, very low cost GPSDO, under $8
On Wed, Apr 9, 2014 at 2:08 AM, Hal Murray wrote: > > > Also any code that accesses them needs to do so with interrupts turned > > off... otherwise you can wind up with corrupted values. > Forgot if I made this point but in a GPSDO when the interrupt is caused by the PPS, the interrupts are in effect off for 0.9 seconds after each interrupt. The software can assume an interrupt will never happen less then one second after an interrupt. So the software does all the variable access within millisecond after each interrupt. These micro controllers are actually much easier to deal with than a general purpose multi-tasking operating system. There is far less non-determinism. -- Chris Albertson Redondo Beach, California ___ time-nuts mailing list -- time-nuts@febo.com To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts and follow the instructions there.
Re: [time-nuts] First success with very simple, very low cost GPSDO, under $8
On Wed, Apr 9, 2014 at 9:39 AM, Orin Eman wrote: > On Wed, Apr 9, 2014 at 2:08 AM, Hal Murray > wrote: > > The order the interrupt routine updates the counter shouldn't matter since > it's atomic as far as the mainline code is concerned. > > In my case it's the other way around, the 16 bit counter is updated by pin-5 and it is "atomic" It is done in the chip's hardware. Actaully I don't care much about an "off by one" count because the problem is corrected in the next second. If I happen to miss a count one second the very next second this shows up as an extra count.I notice that something like this happens every few hundred seconds. The PI controller algorithm is very simple and acts as a kind of filter. It all works in integer math and the DAC is only 16-bits so this kind of error s "lost between the bits". I don't care if the DAC's value is off by .04 because it can only be set on full counts. The goal was to keep the first version of the code SIMPLE. One problem I want to avoid is where I measure a board with a micrometer and then cut it with an axe. When you know you are cutting an axe, you don't even need a tape measure. Later I add some sophistication back in and measure the effect. Heck at this point I have a capacitor based TIC that I am completely IGNORING. The point is to see what each added layer of complexity buys. -- Chris Albertson Redondo Beach, California ___ time-nuts mailing list -- time-nuts@febo.com To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts and follow the instructions there.
Re: [time-nuts] First success with very simple, very low cost GPSDO, under $8
On Tue, Apr 8, 2014 at 10:44 PM, Mark Sims wrote: > I'm not sure how the Arduino environment handles interrupts, but in C you > need to declare any variables altered by an interrupt as "volatile" so that > the compiler optimization routines know not to assume they contain known > values. > Also any code that accesses them needs to do so with interrupts turned > off... otherwise you can wind up with corrupted values. Imagine that the > mainline code is accessing a multi-byte variable. The code accesses the > lower byte, in comes an interrupt that changes the variable (new low and > high bytes, then the interrupt routine returns to the mainline code), and > then the mainline code proceeds to access the (now changed) high byte of > the variable... the resulting value is a mishmash of the old and new > values. > You are 100% correct. You can read in the code I posted that all variables used in the interrupt handler are declared "volatile" The Arduino programming environment uses the GCC C++ compiler But I think you over looked one point that makes this project easier: We KNOW 100% for certain that the interrupts happen only once per second. So the foreground code knows for certain it has exclusive access to shared variables for a given period of time. There is zero chance of a problem in the next .999 seconds after an interrupt. I tested this for 30+ hours and no problem was detected. But yes. iff a second PPS happens just a millisecond later you have a potential problem but then t=you also have a broken GPS receiver and the GPSDO would not work no matte what you did. The test I ran sent the OCXO signal to both an HP counter and the Arduino. My spot checking over a 24 hour run showed the two agree. (I added code to display the count to an LCD screen that was physically close to the counter and just looked by eye to see that were the same, The last digitals (0.1Hz) differs by one as I would expect.) Then as maybe you read in my next post the OCXO failed. The arduino measured "0 Hz" and quickly moved the DAC output to full 5 volts trying to pull the frequency back up to 10MHz from 0. My next test will be to feed a 10MHZ and PPS signals into the Arduino from a Thunderbolt. The TB signal is near perfect and I will look at the "noise" reported by the Arduino. Something to try while I unsolder the can. -- Chris Albertson Redondo Beach, California ___ time-nuts mailing list -- time-nuts@febo.com To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts and follow the instructions there.
Re: [time-nuts] First success with very simple, very low cost GPSDO, under $8
On Wed, Apr 9, 2014 at 2:08 AM, Hal Murray wrote: > > hol...@hotmail.com said: > > I'm not sure how the Arduino environment handles interrupts, but in C > you > > need to declare any variables altered by an interrupt as "volatile" so > that > > the compiler optimization routines know not to assume they contain known > > values. > > Good point. > > > Also any code that accesses them needs to do so with interrupts turned > > off... otherwise you can wind up with corrupted values. > > Not quite. That may be the simplest way, but you can also use > inter-process > communications type tricks. The classic for a two byte counter is to read > high-low-high and try again if the high values don't match. That assumes > the > interrupt routine updates low then (maybe) high. You have to read hardware counter registers on some PIC chips that way. You have to read the documentation carefully to work out how to correctly read 16bit counters on an 8 bit CPU. The order the interrupt routine updates the counter shouldn't matter since it's atomic as far as the mainline code is concerned. Orin. ___ time-nuts mailing list -- time-nuts@febo.com To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts and follow the instructions there.
Re: [time-nuts] First success with very simple, very low cost GPSDO, under $8
hol...@hotmail.com said: > I'm not sure how the Arduino environment handles interrupts, but in C you > need to declare any variables altered by an interrupt as "volatile" so that > the compiler optimization routines know not to assume they contain known > values. Good point. > Also any code that accesses them needs to do so with interrupts turned > off... otherwise you can wind up with corrupted values. Not quite. That may be the simplest way, but you can also use inter-process communications type tricks. The classic for a two byte counter is to read high-low-high and try again if the high values don't match. That assumes the interrupt routine updates low then (maybe) high. -- These are my opinions. I hate spam. ___ time-nuts mailing list -- time-nuts@febo.com To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts and follow the instructions there.
[time-nuts] First success with very simple, very low cost GPSDO, under $8
I'm not sure how the Arduino environment handles interrupts, but in C you need to declare any variables altered by an interrupt as "volatile" so that the compiler optimization routines know not to assume they contain known values. Also any code that accesses them needs to do so with interrupts turned off... otherwise you can wind up with corrupted values. Imagine that the mainline code is accessing a multi-byte variable. The code accesses the lower byte, in comes an interrupt that changes the variable (new low and high bytes, then the interrupt routine returns to the mainline code), and then the mainline code proceeds to access the (now changed) high byte of the variable... the resulting value is a mishmash of the old and new values. ___ time-nuts mailing list -- time-nuts@febo.com To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts and follow the instructions there.
[time-nuts] First success with very simple, very low cost GPSDO, under $8
I just had some success with a new GPSDO based very much on Lars Walenius' design I cut his design and his software down to make it even more simple and cost less. The controller is now well under $8. The software is also much simpler and easy to read even if you are not a "software guy". Lars' design and software will out perform mine. There is no question on that. But my goal was to first build a VERY low cost and more importantly easy to understand and replicate GPSDO. In this first version of the GPSDO I did not implement the TIC. I only count how many cycles occur from the local oscillator between PPS pulses and then use a PI control to adjust the DAC. Performance. I am open to suggestions on how I can characterize the performance. This project is being designed for a beginner who would not have exotic test equipment. I would call the performance "not as bad as you might guess". I have had the output of this GSPDP and the 10MHz signal from a Trimble Thunderbolt both up on my Tek 365 100MHz dual channel scope for about 26 hours and they seem to more or less keep in phase. The GPSDO waveform drifts one way then the other. I can see the short term stability is good only to about the E-9 level but of course being locked to a GPS it has very good long term stability. And this with about $8 worth of parts and build in about one hour. (Not counting the power supply (a plug-in wall wort type), OCXO and GPS) Also the controller software is intentionally simplified. The E-9 is an estimate. I'm looking for a good way to measure it with simple tools. Plans: I will add features and sophistication one step at a time and I will try to document the process. Even as I add more my goal is still (1) an understandable design that anyone can build with no special tools or equipment and (2) cost. With equal importance to each. The next step is too add some refinements to the software, different modes and so one. But this stripped down version will be the "introduction" for a tutorial on GPSDO design. Goals: I want to document this as a design others can build. Even if they are new to all of this. I also want to keep the software open and easy to modify in the hope that others will actually modify it and post their mods here for kind of peer review Parts list: 74HC390, Aruindo "pro mini", two small electrolytic caps and three resisters. That's it. The Mini is $3.71 with free shipping the 74hc390 was $1. Other parts where in the junk box. A software listing is attached. I used some of Lars' code but added a few ideas of my own and removed 80% of the functionality in preference to clarity. I'm not 100% done. I know I can make if more readable. -- Chris Albertson Redondo Beach, California #define PWMHIGHPIN 3 // high PWM-DAC pin (connected to 39k) #define PWMLOWPIN 11 // low PWM-DAC pin (connected to 10M) volatile boolean pps_interrupt = false; volatile unsigned long timer1CountNew = 0; volatile unsigned long timer1CountOld = 0; volatile unsigned long overflowCount = 0; // counter for timer1 overflows volatile unsigned long overflowsNew = 0; unsigned long overflowsOld = 0; unsigned int dacOutCount; // PPS interrupt routine. // This code executes once per second at the raaising edage of each PSS void pps() { timer1CountNew = TCNT1; // get Timer1 counter value overflowsNew = overflowCount; pps_interrupt = true; } // Timer1 overflow Interrrupt Service Routine ISR (TIMER1_OVF_vect) { overflowCount++; // count number of Counter1 overflows } // Setup Timer // This is hard to understand without looking at the AVR data sheet. // After this setup the result is... // Timer1 is a 16-bit counter on pin-D5 that interrupts on overflow void setupTimer() { overflowCount = 0; // no overflows yet (move to variables?) // stop Timer 0 so that timer1 not misses counts due to timer0 interrupts // note: millis() delay()) etc will not work! TCCR0A = 0; TCCR0B = 0; // reset Timer 1 TCCR1A = 0; TCCR1B = 0; // Timer 1 - counts events on pin D5 // 5MHz external clock source on T1 pin (D5). Clock on rising edge. TIMSK1 = _BV (TOIE1); // interrupt on Timer 1 overflow TCNT1 = 0; //counter 1 to zero TCCR1B = _BV (CS10) | _BV (CS11) | _BV (CS12); // start Timer 1 } // The DAC is actually two smaller DAC with ther output summed. // We need to set each DAC void dacOut(unsigned int dacValueOut) { analogWrite(PWMHIGHPIN, highByte(dacValueOut)); analogWrite(PWMLOWPIN, lowByte (dacValueOut)); } void setup() { // connect the PPS handler to the PPS pin attachInterrupt(0, pps, RISING); //Set up Timer1 setupTimer(); // Sert the DAC to a default value. // Any random value is oK dacOutCount = 32000; dacOut(dacOutCount); } long I = 0; void loop() { if (pps_interrupt) { long error = 0; long countsPPS; int overflowsPPS; long timer1CountPPS; // The number of Timer1 overflows b