Yep, it's ANOTHER GPSDO - Development rig MKII - Page 1
Forum section: electronics / projects

author: intabits
author_rank: Frequent Contributor
timestamp: January 18, 2019, 09:24:49 am
content: I'm just so excited by my first results, I just had to tell someone...This GPSDO is inspired by the project in Silicon Chip magazine, September 2018:-http://www.siliconchip.com.au/Issue/2018/October/GPS-synched%2C+lab-quality+frequency+reference+(Part+2)(select #5 at left)(I won't reveal any details of that project not visible above, out of consideration for the magazine. If you're interested, the article can be purchased )I've used the voltage controlled, oven stabilized oscillator part of the project, and will use it's multiple output frequency synthesizer in the final build.But I've used a different processor (Arduino Nano - that may change), and implemented the counter function in external hardware.The oscillator produces 40MHz nominal, which is counted during the GPS PPS pulse. After the count, the control voltage to the oscillator (with quasi 24 bit resolution) will adjust the frequency until a count of 40,000,000 is obtained. The counter can operate over multiple PPS periods (up to 106 seconds) to reduce jitter effects, and get very fine resolution measurements of the output frequency.I'm excited because the first test, with no oven cover (and a ceiling fan blowing cool air all over the place), and with the heater turned off, shows only one count deviation. Which is *far* better than I expected.The measured frequency is 39,999,469 to 39,999470 - I've seen only those two numbers after operating for well over an hour now.(And that variation could simply be because the actual oscillator frequency is 39,999,469.5Hz)This is my development rig:-Top left PCB: Oven and oscillator, with cover removed.Bot left PCB: Counter and gating logicTop right PCB: Just a 32 bit divider to get a bunch of frequencies (not completed)Bot right PCB: Output frequency synthesizer (not completed)Middle: Bodge board with oscillator buffers, ambient temp sensor, shift register to read counter output.Bottom: Small GPS module (covered by wires), and Arduino Nano(if there's interest, I can share details of the counter and gating logic used here)Here is the first page of output:-This setup could be used for any voltage controlled oscillator, but I really like the idea of the SC design, since it's a TCXO built from scratch, using all brand new parts, and therefore no need to use whatever can be found on eBay.Earlier development of the oven control shows a very stable 35C, with only +/-1 resolution unit of the DS18B20 sensor (0.0625C):-Now to work on the software combining the oven control and get to adjusting for 40,000,000Hz...

author: intabits
author_rank: Frequent Contributor
timestamp: January 19, 2019, 12:42:36 am
content: So I hard-coded a DAC value to push the oscillator frequency up to 40MHz, but got some strange count values:-Values of 39999999,40000000,40000001 and 39999744.That last one had me tossed until I realized that 39999744=40000000-256.So I believe the 39999744's are actually 40000000 with two bits crossed up:-Code:value hex ** *39,999,744 = 262 5900 = 10 0110 0010 0101 1001 0000 000040,000,000 = 262 5A00 = 10 0110 0010 0101 1010 0000 000039,999,872 = 262 5980 = 10 0110 0010 0101 1001 1000 0000The first two have bits 8 and 9 swapped, and I've occasionally also got the last one, where bits 7 and 8 have flipped.I thought of a solder bridge, but no. And anyway, everything, hardware and code, is common for all four bytes, so I can't see how just these 3 bits out of 32 are getting screwed up.The counter, gating and readout circuitry is:-And my code to read from it is:-Code:unsigned long ReadCounterRegister() {unsigned long CV; byte BV;CV=0; // Clear resultBV=ReadCtrRegByte(0); CV=CV|BV; CV=CV<<8; // Get MS Byte,BV=ReadCtrRegByte(1); CV=CV|BV; CV=CV<<8; // OR into result, shift 8 bits,BV=ReadCtrRegByte(2); CV=CV|BV; CV=CV<<8; // making room for the next byteBV=ReadCtrRegByte(3); CV=CV|BV; // Get LS Byte, OR into result, but no shiftreturn CV;}byte ReadCtrRegByte(byte BI) {byte CB,BT,BM,BC;// Set 74HC138 select lines for specified 74HC590 chip. LSB is chip 3, should be reversed...digitalWrite(CtrRegOS1,(BI&2)>>1);digitalWrite(CtrRegOS0,(BI&1));// Pulse ParSerCtl High to latch selected CtrReg output byte into CD4021digitalWrite(ShfRegLoad,1);digitalWrite(ShfRegLoad,0);// Serial shift CD4021 data into byteCB=0; BM=0x80; // Reset result byte and Bit Maskfor (BC = 0; BC < 8; BC++) { // Loop to get 8 bits...BT=digitalRead(ShfRegData); // Get CD4021 output on Q8 pinif (BT!=0) // A 1?CB=(CB|BM); // if so, insert bit mask bit into result byteBM=(BM>>1); // Shift bit mask to next bitdigitalWrite(ShfRegClok,1); // Pulse Shift Clock HighdigitalWrite(ShfRegClok,0); // to shift next bit to Q8}return CB;}I've tried inserting short delays all over the place, in case of a marginal timing issue, but I still get the swapped bits.Any ideas on why this might be happening?

author: metrologist
author_rank: Super Contributor
timestamp: January 19, 2019, 01:02:55 am
content: Just saying Thanks for posting! I love these GPSDO projects.

author: NorthGuy
author_rank: Super Contributor
timestamp: January 19, 2019, 01:31:31 am
content: Quote from: intabits on January 18, 2019, 09:24:49 amYou don't read the bytes at the same time. After you read byte 2, byte 3 may roll over (and you're actually deliberately trying to catch it at this bad time). Hence you get - 256.Same goes with bits within Q0-Q7 - you may latch them while they're changing.Latching must be synchronized to the 40 MHz clock and done all at the same time, such as with 4 different shift registers.<edit>My mistake. I see you gate the clock with PPS, so what you're doing should work. Since it doesn't, one may suspect the gating is not working properly and you're reading the data while the clock is still running.

author: intabits
author_rank: Frequent Contributor
timestamp: January 19, 2019, 01:59:46 am
content: Quote from: NorthGuy on January 19, 2019, 01:31:31 amNo, (unless I'm screwing something up - I'll check to be sure) the counter has been stopped when I read it. I can pull the bytes out at my leisure...Here is the timing diagram (a bit busy, with some small errors, but it shows what's going):-1/ Top trace is counter enable2/ is PPS signal3/ is Arm signal from CPU4/ is Disarm signal from CPUBasically, it holds the counter disabled, but "armed", waiting for the next PPS, which immediately enables the counter.During the PPS period (or during the last, if counting over more than one), "disarm" is set to stop the counter at the next PPS.Anytime after that, the count is latched into the 74590 registers, and then one by one, each byte is enabled onto the shared bus to the 4021, then clocked into the CPU, and repeated for the other three bytes. All this can occur at any speed, because the counter has stopped.

author: NorthGuy
author_rank: Super Contributor
timestamp: January 19, 2019, 02:18:21 am
content: Quote from: intabits on January 19, 2019, 01:59:46 amMy mistake. I already figured that you stop the clock with CE.However, CE is not synchronized with the 40 MHz clock neither, so if the edge of CE happens about the same time as the edge of 40 MHz clocks, some of the counters may count the edge while others won't. Say, if counter 2 doesn't count the carry bit from counter 3, you get exactly this situation - counter 3 is already at 0 while counter 2 didn't count the carry and is therefore one less than it should be.The same mechanism may work within 74HC590 for consecutive bits (thus giving you 128, or possibly 64, difference), however this is far less likely than between the ICs.

author: intabits
author_rank: Frequent Contributor
timestamp: January 19, 2019, 03:10:52 am
content: OK, I see what you're saying. I can't picture clearly what you said about carrys, but I see that dropping CE while the count is still rippling may screw things up.It does seem very specific to these particular bits though...There is some logic in the 74590 that gates the clock with CE (which I don't understand), but even if it helps within a chip, does nothing for multiple chips.I was looking at synchronous counters, but couldn't find one that I liked for this job (I forget what issues I had in mind at the time that ruled them out)I'll go back to the drawing board and come up with a bodge that only switches CE when the 40MHz is high, or something like that.74590 clocks on a L-H, so that puts the CE switch at least 12nS before the first clock event.(Or maybe that should be to hold off disabling CE as long as possible after the last clock event, to allow the ripple to complete)Or maybe I should be just gating the incoming 40MHz, and leave the CE out of it.Just thinking aloud here...

author: intabits
author_rank: Frequent Contributor
timestamp: January 19, 2019, 03:53:44 am
content: @NorthGuy BTW, thanks for your help on this.QuoteThat one.Something like this:-Timing:-

author: NorthGuy
author_rank: Super Contributor
timestamp: January 19, 2019, 04:50:01 am
content: Quote from: intabits on January 19, 2019, 03:53:44 amI think this should work. It will produce truncated pulses, but the counter should be consistent in all cases.

author: intabits
author_rank: Frequent Contributor
timestamp: January 19, 2019, 08:32:38 am
content: Yay! That fixed it!Thanks NorthGuy for spotting the problem.I've set it to count over 1 second, then over 10 seconds, 5 times each, alternating:-19:10:14.866 -> Armed C Complete Count=40000001 Repeat...19:10:17.851 -> Armed C Complete Count=40000001 Repeat...19:10:20.871 -> Armed C Complete Count=40000001 Repeat...19:10:23.755 -> Armed C Complete Count=40000001 Repeat...19:10:26.776 -> Armed C Complete Count=40000000 Repeat...19:10:29.762 -> Armed CCCCCCCCCCCCCCCCCCCCCCCC Complete Count=400000007 Repeat...19:10:41.789 -> Armed CCCCCCCCCCCCCCCCCCCCCCCC Complete Count=400000006 Repeat...19:10:53.772 -> Armed CCCCCCCCCCCCCCCCCCCCCCCC Complete Count=400000007 Repeat...19:11:05.792 -> Armed CCCCCCCCCCCCCCCCCCCCCCCC Complete Count=400000005 Repeat...19:11:17.782 -> Armed CCCCCCCCCCCCCCCCCCCCCCCC Complete Count=400000005 Repeat...19:11:29.797 -> Armed C Complete Count=40000001 Repeat...19:11:32.821 -> Armed C Complete Count=40000000 Repeat...19:11:35.807 -> Armed C Complete Count=40000001 Repeat...19:11:38.827 -> Armed C Complete Count=40000001 Repeat...19:11:41.815 -> Armed C Complete Count=40000001 Repeat...19:11:44.803 -> Armed CCCCCCCCCCCCCCCCCCCCCCCC Complete Count=400000003 Repeat...19:11:56.821 -> Armed CCCCCCCCCCCCCCCCCCCCCCCC Complete Count=400000003 Repeat...19:12:08.845 -> Armed CCCCCCCCCCCCCCCCCCCCCCCC Complete Count=400000003 Repeat...19:12:20.852 -> Armed CCCCCCCCCCCCCCCCCCCCCCCC Complete Count=400000002 Repeat...19:12:32.857 -> Armed CCCCCCCCCCCCCCCCCCCCCCCC Complete Count=400000001 Repeat...19:12:44.837 -> Armed C Complete Count=40000000 Repeat...19:12:47.862 -> Armed C Complete Count=40000001 Repeat...19:12:50.847 -> Armed C Complete Count=40000001 Repeat...19:12:53.870 -> Armed C Complete Count=40000000 Repeat...19:12:56.856 -> Armed C Complete Count=40000000 Repeat...19:12:59.845 -> Armed CCCCCCCCCCCCCCCCCCCCCCCC Complete Count=400000001 Repeat...19:13:11.764 -> Armed CCCCCCCCCCCCCCCCCCCCCCCC Complete Count=399999999 Repeat...19:13:23.767 -> Armed CCCCCCCCCCCCCCCCCCCCCCCC Complete Count=399999999 Repeat...19:13:35.781 -> Armed CCCCCCCCCCCCCCCCCCCCCCCC Complete Count=399999999 Repeat...19:13:47.795 -> Armed CCCCCCCCCCCCCCCCCCCCCCCC Complete Count=399999998 Repeat...19:13:59.806 -> Armed C Complete Count=40000000 Repeat...19:14:02.794 -> Armed C Complete Count=40000000 Repeat...19:14:05.814 -> Armed C Complete Count=40000001 Repeat...19:14:08.802 -> Armed C Complete Count=40000000 Repeat...19:14:11.789 -> Armed C Complete Count=40000000 Repeat...Which is pretty good I think, especially as that's still with no oven cover, and no heating. Just at ambient temp (25C).And with a hand coded DAC value to set the frequency to 40MHz, but that's a moving target without the oven.So I'm very happy with the progress so far. But it's all a bit rickety, with sloppy breadboard wires and various bodges.I'd love to just consolidate it all onto a new PCB for stability right now, but that must wait until more issues are uncovered and resolved.The next thing is making some solid structured firmware with all the bells and whistles I want, along with PC software to drive and monitor it all...

author: iMo
author_rank: Super Contributor
timestamp: January 19, 2019, 04:15:16 pm
content: I built a similar stuff but placed into an iCE40LP384 fpga. Basically a reciprocal counter. My counters are latched (by a single edge coming from an MCU) into registers, and those registers are then read out by the MCU. The counters do not stop nor are reset, so you can do "new-old" without loosing the phase information in your math then .When talking GPSDO - I doubt you will be happy by measuring the frequency with 1 count resolution, though. You have to go much deeper, into mHz resolution. That could be only achieved by a time interpolator (analog or digital).When using an interpolator you cannot stop or reset the counters as your "phase" information will be lost.For example the Lars' GPSDO claims "1ns" resolution (it is using an analog time interpolator). That is equivalent of counting 1GHz for 1sec with 1 count resolution. Or counting 10MHz for 100 seconds.Thus to get a better performance you have to get an information on the actual 10MHz OCXO frequency with better than 10 milliHertz resolution each second.PS: a good 10MHz OCXO drifts +/- few mHz when locked to GPS timing pulses.

author: metrologist
author_rank: Super Contributor
timestamp: January 19, 2019, 05:02:57 pm
content: Quote from: imo on January 19, 2019, 04:15:16 pmMy Wenzel timekeeper drifts an average 5mHz per day while free running. Since September it's moved ~700mHz.

author: iMo
author_rank: Super Contributor
timestamp: January 19, 2019, 05:29:33 pm
content: For example, in order to discipline an average 10MHz OCXO your counter's readings may look like:Code:Time  Reading 455 9.999.999,989456 9.999.999,993457 9.999.999,995458 9.999.999,992459 9.999.999,988460 9.999.999,991461 9.999.999,996462 10.000.000,002463 9.999.999,997..That frequencies are then inputs into your PI(D) control loop math (math->DAC->OCXO_EFC).

author: intabits
author_rank: Frequent Contributor
timestamp: January 20, 2019, 02:52:20 am
content: Quote from: imo on January 19, 2019, 04:15:16 pmSo counting 40MHz for 25 seconds is also 1nS resolution, isn't it?The following is still without an oven cover, heating, temperature control or frequency control:-09:09:03.244 -> Measure for 25s: Count=100000000209:09:30.254 -> Measure for 25s: Count=100000000309:09:57.257 -> Measure for 25s: Count=100000000309:10:24.308 -> Measure for 25s: Count=100000000109:10:51.218 -> Measure for 25s: Count=100000000109:11:18.203 -> Measure for 25s: Count=100000000209:11:45.225 -> Measure for 25s: Count=100000000309:12:12.249 -> Measure for 25s: Count=100000000409:12:39.255 -> Measure for 25s: Count=100000000509:13:06.247 -> Measure for 25s: Count=100000000309:13:33.283 -> Measure for 25s: Count=100000000409:14:00.287 -> Measure for 25s: Count=100000000409:14:27.183 -> Measure for 25s: Count=100000000409:14:54.220 -> Measure for 25s: Count=100000000209:15:21.226 -> Measure for 25s: Count=100000000409:15:48.250 -> Measure for 25s: Count=100000000409:16:15.254 -> Measure for 25s: Count=100000000209:16:42.258 -> Measure for 25s: Count=100000000409:17:09.261 -> Measure for 25s: Count=100000000209:17:36.188 -> Measure for 25s: Count=100000000209:18:03.223 -> Measure for 25s: Count=100000000309:18:30.200 -> Measure for 25s: Count=100000000009:18:57.238 -> Measure for 25s: Count=99999999609:19:24.222 -> Measure for 25s: Count=99999999509:19:51.273 -> Measure for 25s: Count=99999999509:20:18.276 -> Measure for 25s: Count=99999999309:20:45.266 -> Measure for 25s: Count=99999999109:21:12.196 -> Measure for 25s: Count=99999999209:21:39.217 -> Measure for 25s: Count=99999999209:22:06.214 -> Measure for 25s: Count=99999999309:22:33.240 -> Measure for 25s: Count=99999999009:23:00.236 -> Measure for 25s: Count=99999999009:23:27.256 -> Measure for 25s: Count=99999999109:23:54.255 -> Measure for 25s: Count=99999999209:24:21.274 -> Measure for 25s: Count=99999999309:24:48.190 -> Measure for 25s: Count=99999999409:25:15.208 -> Measure for 25s: Count=99999999409:25:42.214 -> Measure for 25s: Count=99999999209:26:09.224 -> Measure for 25s: Count=99999999309:26:36.260 -> Measure for 25s: Count=99999999609:27:03.279 -> Measure for 25s: Count=99999999909:27:30.284 -> Measure for 25s: Count=100000000409:27:57.178 -> Measure for 25s: Count=100000000409:28:24.215 -> Measure for 25s: Count=100000000409:28:51.213 -> Measure for 25s: Count=100000000309:29:18.224 -> Measure for 25s: Count=100000000109:29:45.220 -> Measure for 25s: Count=100000000309:30:12.228 -> Measure for 25s: Count=100000000209:30:39.266 -> Measure for 25s: Count=100000000109:31:06.250 -> Measure for 25s: Count=100000000109:31:33.176 -> Measure for 25s: Count=100000000309:32:00.180 -> Measure for 25s: Count=100000000409:32:27.185 -> Measure for 25s: Count=100000000209:32:54.235 -> Measure for 25s: Count=100000000109:33:21.247 -> Measure for 25s: Count=100000000209:33:48.251 -> Measure for 25s: Count=100000000109:34:15.263 -> Measure for 25s: Count=100000000009:34:42.262 -> Measure for 25s: Count=100000000109:35:09.194 -> Measure for 25s: Count=100000000009:35:36.219 -> Measure for 25s: Count=100000000109:36:03.222 -> Measure for 25s: Count=100000000109:36:30.243 -> Measure for 25s: Count=100000000109:36:57.246 -> Measure for 25s: Count=100000000309:37:24.265 -> Measure for 25s: Count=100000000209:37:51.284 -> Measure for 25s: Count=100000000209:38:18.163 -> Measure for 25s: Count=100000000209:38:45.183 -> Measure for 25s: Count=100000000109:39:12.187 -> Measure for 25s: Count=99999999909:39:39.226 -> Measure for 25s: Count=100000000009:40:06.252 -> Measure for 25s: Count=100000012809:40:33.226 -> Measure for 25s: Count=100000000009:41:00.272 -> Measure for 25s: Count=99999999909:41:27.269 -> Measure for 25s: Count=100000000009:41:54.167 -> Measure for 25s: Count=99999999909:42:21.171 -> Measure for 25s: Count=99999999709:42:48.210 -> Measure for 25s: Count=99999999809:43:15.223 -> Measure for 25s: Count=99999999809:43:42.210 -> Measure for 25s: Count=99999999709:44:09.225 -> Measure for 25s: Count=99999999909:44:36.266 -> Measure for 25s: Count=99999999709:45:03.163 -> Measure for 25s: Count=99999999809:45:30.174 -> Measure for 25s: Count=99999999709:45:57.172 -> Measure for 25s: Count=99999999809:46:24.238 -> Measure for 25s: Count=99999999809:46:51.207 -> Measure for 25s: Count=99999999909:47:18.219 -> Measure for 25s: Count=100000000009:47:45.265 -> Measure for 25s: Count=100000000009:48:12.272 -> Measure for 25s: Count=100000000009:48:39.154 -> Measure for 25s: Count=100000000009:49:06.187 -> Measure for 25s: Count=99999999909:49:33.169 -> Measure for 25s: Count=99999999909:50:00.193 -> Measure for 25s: Count=99999999909:50:27.244 -> Measure for 25s: Count=99999999909:50:54.248 -> Measure for 25s: Count=99999999809:51:21.235 -> Measure for 25s: Count=99999999609:51:48.270 -> Measure for 25s: Count=99999999409:52:15.183 -> Measure for 25s: Count=99999999609:52:42.203 -> Measure for 25s: Count=99999999709:53:09.175 -> Measure for 25s: Count=99999999609:53:36.215 -> Measure for 25s: Count=99999999609:54:03.208 -> Measure for 25s: Count=99999999709:54:30.230 -> Measure for 25s: Count=99999999809:54:57.245 -> Measure for 25s: Count=99999999909:55:24.289 -> Measure for 25s: Count=100000000009:55:51.156 -> Measure for 25s: Count=100000000109:56:18.199 -> Measure for 25s: Count=100000000009:56:45.229 -> Measure for 25s: Count=99999999909:57:12.200 -> Measure for 25s: Count=99999999709:57:39.232 -> Measure for 25s: Count=100000000209:58:06.233 -> Measure for 25s: Count=100000000109:58:33.247 -> Measure for 25s: Count=100000000009:59:00.153 -> Measure for 25s: Count=99999999809:59:27.170 -> Measure for 25s: Count=99999999709:59:54.176 -> Measure for 25s: Count=99999999710:00:21.181 -> Measure for 25s: Count=99999999810:00:48.199 -> Measure for 25s: Count=99999999810:01:15.212 -> Measure for 25s: Count=99999999810:01:42.248 -> Measure for 25s: Count=999999998

author: iMo
author_rank: Super Contributor
timestamp: January 20, 2019, 08:05:09 am
content: QuoteWith 25 seconds gating time and 40MHz OCXO you get an "1 count" resolution of 40ms, that is an equivalent resolution of 10mHz with a 10MHz OCXO, that is an equivalent resolution of "1ns" time interpolator with a 10MHz OCXO.In other words, you will not detect any drift of your 40MHz OCXO which is smaller than 40mHz between two measurements (25 seconds in your case). Also mind the 25sec long measurement works as an "integrator" - that means during that time the OCXO may fluctuate a lot but you may get an average below 40mHz.

author: intabits
author_rank: Frequent Contributor
timestamp: January 20, 2019, 01:01:06 pm
content: Quote from: imo on January 20, 2019, 08:05:09 amI'm happy with that!I thank you for taking the trouble to explain this stuff to me, but I'm afraid it has mostly just confused me.I am new to this GPSDO stuff, so it's almost certain that some of the finer points will be lost on me. (Or maybe I'm just a bit thick - Nah, can't be that)But what I think is most likely, is that we are talking at cross purposes.Correct me if I'm wrong, but I get the impression that you are talking about an oscillator whose phase difference from some hypothetical rock solid reference source is very stable, always staying within 1nS (for 10MHz). That would be great, but is not my main aim.I'm simply building the same oscillator as the Silicon Chip project mentioned in my first post, but with a different measurement implementation, although based on the same theory. It's purpose is to provide an accurate and stable frequency reference. And while there's no accounting for anything like the phase delay mentioned above, hopefully one begets the other.I'm assuming that consistently counting 400,000,000 cycles over 10 PPS pulses, means that I have a very stable 40MHz oscillator. Yes, its frequency could be wavering slightly during that time, but isn't that unlikely if the count is always the same? (just BTW: the magazine firmware averages over 1000 PPS pulses)I've insulated the oscillator (it's not the proper cover) and turned on the heating.But with only a crude frequency control for now. I need to add some resistors in the DAC before I can use a proper PI algorithm.But after settling down:-23:40:09.556 -> Measure 10s: Count=399999997 FreqDrive=2931:2101 Ambient: 27.19 Oven: 35.00 HeatDrive: 212823:40:21.527 -> Measure 10s: Count=399999997 FreqDrive=2931:2102 Ambient: 27.19 Oven: 35.00 HeatDrive: 212823:40:33.601 -> Measure 10s: Count=399999997 FreqDrive=2931:2103 Ambient: 27.25 Oven: 35.00 HeatDrive: 212823:40:45.573 -> Measure 10s: Count=399999997 FreqDrive=2931:2104 Ambient: 27.25 Oven: 35.00 HeatDrive: 212823:40:57.543 -> Measure 10s: Count=399999997 FreqDrive=2931:2105 Ambient: 27.25 Oven: 35.00 HeatDrive: 212823:41:09.607 -> Measure 10s: Count=399999997 FreqDrive=2931:2106 Ambient: 27.25 Oven: 35.06 HeatDrive: 212723:41:21.577 -> Measure 10s: Count=399999998 FreqDrive=2931:2107 Ambient: 27.19 Oven: 35.00 HeatDrive: 212723:41:33.519 -> Measure 10s: Count=399999997 FreqDrive=2931:2108 Ambient: 27.19 Oven: 35.06 HeatDrive: 212623:41:45.609 -> Measure 10s: Count=399999997 FreqDrive=2931:2109 Ambient: 27.19 Oven: 35.06 HeatDrive: 212523:41:57.579 -> Measure 10s: Count=399999997 FreqDrive=2931:2110 Ambient: 27.19 Oven: 35.00 HeatDrive: 212523:42:09.548 -> Measure 10s: Count=399999997 FreqDrive=2931:2111 Ambient: 27.19 Oven: 35.00 HeatDrive: 212523:42:21.588 -> Measure 10s: Count=399999997 FreqDrive=2931:2112 Ambient: 27.25 Oven: 35.00 HeatDrive: 212523:42:33.561 -> Measure 10s: Count=399999996 FreqDrive=2931:2113 Ambient: 27.19 Oven: 35.00 HeatDrive: 212523:42:45.533 -> Measure 10s: Count=399999997 FreqDrive=2931:2114 Ambient: 27.19 Oven: 35.00 HeatDrive: 212523:42:57.608 -> Measure 10s: Count=399999996 FreqDrive=2931:2115 Ambient: 27.19 Oven: 35.00 HeatDrive: 212523:43:09.578 -> Measure 10s: Count=399999997 FreqDrive=2931:2116 Ambient: 27.19 Oven: 35.00 HeatDrive: 212523:43:21.533 -> Measure 10s: Count=399999996 FreqDrive=2931:2117 Ambient: 27.19 Oven: 35.00 HeatDrive: 212523:43:33.607 -> Measure 10s: Count=399999996 FreqDrive=2931:2118 Ambient: 27.19 Oven: 35.00 HeatDrive: 2125When I've finalized what I'm trying to do here, Ill do new PCBs and make two identical independent units, and watch both outputs on a scope for a few hours...Maybe one of the time-nuts here could borrow them for evaluation against their best standard?

author: 1001
author_rank: Contributor
timestamp: January 23, 2019, 06:33:39 pm
content: u3 u4 u5 u6 u7 and u8 could be replaced with a single ic like SN74LV8154. or am I wrong?are you sure the 74hc590 works well at 40mhz? nexperia and TI do not ensure that it works well at this frequency.Quote from: intabits on January 19, 2019, 03:53:44 am

author: intabits
author_rank: Frequent Contributor
timestamp: January 24, 2019, 10:21:30 pm
content: Quote from: 1001 on January 23, 2019, 06:33:39 pmThat's an interesting chip, I must get some, I didn't know it existed. (I didn't even know that 7400 series could have 4 digit suffixes)U8 would still be needed (parallel to serial) because of the limited number of Arduino I/O pins. (I'm going to do similar with a 74595 for outputs on my next version)Thanks for the tip.QuoteIt's borderline for sure. Typical @4.5v and 25C is 52MHz, but worst case is only 33MHz.But I'm running everything at 3.3v (including an Arduino Nano hacked for 3.3v) .So not surprisingly, it's flakey. It counts properly for 10 minutes, then nonsense for 10 mins, then OK for a while...I used 3.3v because of the oscillator/oven, but if I use 4 level converters to talk to that, everything else can run at 5v.Which I'm hoping will be OK, though not ideal. (the SN74LV8154 looks to be borderline at 40MHz as well)Maybe 1 or 2 flip-flops as a prescaler before the counter is the answer.

author: intabits
author_rank: Frequent Contributor
timestamp: February 02, 2019, 03:35:04 am
content: So believing that the flakiness in the values read out of the counter was probably due to running it at 3.3v, where it is not spec'd to count at 40MHz, I rebuilt my breadboard development rig on a PCB, and ran most of it at 5v.Only the DACs in the oscillator/oven needed to run at 3v3 (the to-be-added frequency synthesizer does also, but that is peripheral to the main oscillator function). And with everything running at 3v3, I also had to hack the Arduino Nano to become a 3v3 device.But now all the digital parts are running at 5v, including a new Nano. And the DACs are connected via 4 level translators. I also added a 74HC595 shift register as an output expander, freeing up enough I/O pins on the Nano to interface to an LCD display, and to communicate with the GPS module via its serial interface.However, when I fired it up, I was not surprised to see the flakiness was still there. This is because while building the new PCB, I had begun to suspect that the errors were not due to running the counter too fast, but rather some systemic problem. It had after all, worked properly when I first made it, and the count errors seemed to come and go in waves. It worked for 2 minutes, the went bad for 5, and repeated. I would have expected something more continuous or random if it was just because of the clock speed being too high.And it turned out to be a software problem, to do with the timing of when the counter value was being latched into its output registers.It now seems to be running very solidly.With very little "tuning" of the frequency control algorithm done yet, it quickly converges, and is nearly always showing 40,000,000.00Hz.That is done with samples taken over 10 PPS pulses, and then averaging groups of 5 sample periods.The PI algorithm makes its adjustments based on the frequency measured for a group of samples.I've written a program to monitor and control the device, allowing me to fiddle with all the control values. It will also log and plot long term information.Development rig MKII - Top viewDevelopment rig MKII - UndersideDevelopment rig MKII - Oven/Oscillator removed, Oven underside, Arduino Mega2560 for future version, Alternative GPS moduleBeginnings of control software, showing precisely 2 billion cycles counted over 5 x 10 second samples