More hilarity re: creating a TXCO

Status
Not open for further replies.

Constantin

Well-known member
This weekend, I had some time to run the Teensy RTC through it's paces. Here is some output, looks like sub-2PPM performance is possible. The sensor is a HTU21, I've also had good luck with the Si7021 sensor for humidity and temperature measurements. One of the key things is characterizing the performance of the crystal, and doing so slowly, so the sensor and the crystal are at the same temperature.

FWIW, I am manipulating the RTC_TCR register directly, seeking exhaustively for the solution with the smallest PPM error.

Welcome. Prepare to wait 18 seconds for CIC register to run out.

The predicted RTC error @ 28.33*C is: 3.6645PPM.
Best Combination: time constant divisor = 25, and PPM multiplier (j) =-3
Over a 76 second interval, Error measured: 14.13PPM for the MCU and 13.59PPM for the RTC, i.e. 0.54PPM.

The predicted RTC error @ 28.33*C is: 3.6645PPM.
Best Combination: time constant divisor = 25, and PPM multiplier (j) =-3
No change needed for RTC multiplier or time constant.
Over a 76 second interval, error measured: 14.13PPM for the MCU and 13.63PPM for the RTC, i.e. 0.50PPM.

The predicted RTC error @ 28.33*C is: 3.6645PPM.
No change needed for RTC multiplier or time constant.
Over a 76 second interval, error measured: 14.12PPM for the MCU and 13.76PPM for the RTC, i.e. 0.36PPM.

The predicted RTC error @ 28.59*C is: 3.5495PPM.
Best Combination: time constant divisor = 43, and PPM multiplier (j) =-5
Over a 130 second interval, error measured: 14.05PPM for the MCU and 13.57PPM for the RTC, i.e. 0.48PPM.

The predicted RTC error @ 28.54*C is: 3.5739PPM.
Best Combination: time constant divisor = 77, and PPM multiplier (j) =-9
Over a 232 second interval, error measured: 14.15PPM for the MCU and 13.26PPM for the RTC, i.e. 0.89PPM.

The predicted RTC error @ 24.33*C is: 4.8032PPM.
Best Combination: time constant divisor = 19, and PPM multiplier (j) =-3
Over a 58 second interval, error measured: 15.12PPM for the MCU and 14.66PPM for the RTC, i.e. 0.47PPM.

The predicted RTC error @ 22.99*C is: 4.9120PPM.
Best Combination: time constant divisor = 56, and PPM multiplier (j) =-9
Over a 169 second interval, error measured: 15.51PPM for the MCU and 15.52PPM for the RTC, i.e. -0.01PPM.

The predicted RTC error @ 19.81*C is: 4.6213PPM.
Best Combination: time constant divisor = 33, and PPM multiplier (j) =-5
Over a 100 second interval, error measured: 16.10PPM for the MCU and 16.08PPM for the RTC, i.e. 0.02PPM.

The predicted RTC error @ 18.29*C is: 4.2126PPM.
Best Combination: time constant divisor = 29, and PPM multiplier (j) =-4
Over a 88 second interval, error measured: 16.39PPM for the MCU and 16.32PPM for the RTC, i.e. 0.07PPM.

The predicted RTC error @ 17.20*C is: 3.8083PPM.
Best Combination: time constant divisor = 8, and PPM multiplier (j) =-1
Over a 25 second interval, error measured: 16.56PPM for the MCU and 16.12PPM for the RTC, i.e. 0.44PPM.

The predicted RTC error @ 16.92*C is: 3.6907PPM.
Best Combination: time constant divisor = 58, and PPM multiplier (j) =-7
Over a 175 second interval, error measured: 16.67PPM for the MCU and 16.91PPM for the RTC, i.e. -0.25PPM.

The predicted RTC error @ 15.33*C is: 2.9082PPM.
Best Combination: time constant divisor = 21, and PPM multiplier (j) =-2
Over a 64 second interval, Error measured: 16.92PPM for the MCU and 16.67PPM for the RTC, i.e. 0.25PPM.

The predicted RTC error @ 14.82*C is: 2.6132PPM.
Best Combination: time constant divisor = 35, and PPM multiplier (j) =-3
Over a 106 second interval, error measured: 17.00PPM for the MCU and 16.87PPM for the RTC, i.e. 0.13PPM.

The predicted RTC error @ 14.14*C is: 2.1953PPM.
Best Combination: time constant divisor = 139, and PPM multiplier (j) =-10
Over a 418 second interval, error measured: 17.15PPM for the MCU and 17.54PPM for the RTC, i.e. -0.39PPM.

The predicted RTC error @ 12.89*C is: 1.3270PPM.
Best Combination: time constant divisor = 23, and PPM multiplier (j) =-1
Over a 70 second interval, Error measured: 17.30PPM for the MCU and 16.91PPM for the RTC, i.e. 0.39PPM.

The predicted RTC error @ 12.73*C is: 1.2070PPM.
Best Combination: time constant divisor = 177, and PPM multiplier (j) =-7
Over a 532 second interval, error measured: 17.33PPM for the MCU and 17.20PPM for the RTC, i.e. 0.12PPM.

The predicted RTC error @ 12.40*C is: 0.9528PPM.
Best Combination: time constant divisor = 32, and PPM multiplier (j) =-1
Over a 97 second interval, error measured: 17.37PPM for the MCU and 16.95PPM for the RTC, i.e. 0.42PPM.

The predicted RTC error @ 12.31*C is: 0.8858PPM.
Best Combination: time constant divisor = 241, and PPM multiplier (j) =-7
Over a 724 second interval, error measured: 17.38PPM for the MCU and 17.05PPM for the RTC, i.e. 0.32PPM.

The predicted RTC error @ 12.37*C is: 0.9361PPM.
Success: time constant divisor (k)=163, and PPM multiplier (j) =-5
Over a 490 second interval, error measured: 17.38PPM for the MCU and 16.98PPM for the RTC, i.e. 0.40PPM.

The predicted RTC error @ 12.47*C is: 1.0109PPM.
Best Combination: time constant divisor = 151, and PPM multiplier (j) =-5
Over a 454 second interval, Error measured: 17.37PPM for the MCU and 16.93PPM for the RTC, i.e. 0.44PPM.

The predicted RTC error @ 12.61*C is: 1.1178PPM.
Best Combination: time constant divisor = 191, and PPM multiplier (j) =-7
Over a 574 second interval, error measured: 17.34PPM for the MCU and 16.87PPM for the RTC, i.e. 0.47PPM.

The predicted RTC error @ 12.84*C is: 1.2872PPM.
Best Combination: time constant divisor = 166, and PPM multiplier (j) =-7
Over a 499 second interval, error measured: 17.31PPM for the MCU and 16.87PPM for the RTC, i.e. 0.45PPM.

The predicted RTC error @ 12.99*C is: 1.3981PPM.
Best Combination: time constant divisor = 131, and PPM multiplier (j) =-6
Over a 394 second interval, error measured: 17.29PPM for the MCU and 16.85PPM for the RTC, i.e. 0.44PPM.

The predicted RTC error @ 13.09*C is: 1.4762PPM.
Best Combination: time constant divisor = 62, and PPM multiplier (j) =-3
Over a 187 second interval, error measured: 17.28PPM for the MCU and 16.85PPM for the RTC, i.e. 0.43PPM.

The predicted RTC error @ 13.08*C is: 1.4684PPM.
Best Combination: time constant divisor = 187, and PPM multiplier (j) =-9
Over a 562 second interval, error measured: 17.27PPM for the MCU and 16.80PPM for the RTC, i.e. 0.47PPM.

The predicted RTC error @ 24.70*C is: 4.7500PPM.
Best Combination: time constant divisor = 45, and PPM multiplier (j) =-7
Over a 136 second interval, Error measured: 14.93PPM for the MCU and 15.06PPM for the RTC, i.e. -0.13PPM.

The predicted RTC error @ 26.36*C is: 4.3787PPM.
Best Combination: time constant divisor = 7, and PPM multiplier (j) =-1
Over a 22 second interval, error measured: 14.64PPM for the MCU and 14.41PPM for the RTC, i.e. 0.23PPM.

The predicted RTC error @ 26.58*C is: 4.3121PPM.
Best Combination: time constant divisor = 71, and PPM multiplier (j) =-10
Over a 214 second interval, error measured: 14.45PPM for the MCU and 14.43PPM for the RTC, i.e. 0.02PPM.

The predicted RTC error @ 28.23*C is: 3.7109PPM.
Best Combination: time constant divisor = 74, and PPM multiplier (j) =-9
Over a 223 second interval, error measured: 14.10PPM for the MCU and 13.79PPM for the RTC, i.e. 0.30PPM.

The predicted RTC error @ 29.27*C is: 3.2235PPM.
Best Combination: time constant divisor = 85, and PPM multiplier (j) =-9
Over a 256 second interval, error measured: 13.86PPM for the MCU and 13.39PPM for the RTC, i.e. 0.47PPM.

The predicted RTC error @ 30.04*C is: 2.8084PPM.
Best Combination: time constant divisor = 87, and PPM multiplier (j) =-8
Over a 262 second interval, error measured: 13.70PPM for the MCU and 13.04PPM for the RTC, i.e. 0.66PPM.

The predicted RTC error @ 30.44*C is: 2.5774PPM.
Best Combination: time constant divisor = 71, and PPM multiplier (j) =-6
Over a 214 second interval, error measured: 13.61PPM for the MCU and 12.91PPM for the RTC, i.e. 0.71PPM.

The predicted RTC error @ 30.72*C is: 2.4012PPM.
Best Combination: time constant divisor = 89, and PPM multiplier (j) =-7
Over a 268 second interval, error measured: 13.55PPM for the MCU and 12.76PPM for the RTC, i.e. 0.79PPM.

The predicted RTC error @ 30.90*C is: 2.2938PPM.
Best Combination: time constant divisor = 133, and PPM multiplier (j) =-10
Over a 400 second interval, Error measured: 13.52PPM for the MCU and 12.65PPM for the RTC, i.e. 0.87PPM.
 
Last edited:
FWIW, it may make sense to take a hybrid approach where the intervals are shortened (to ensure better temperature control) while also accounting for the 'leftovers' ie the remaining ppm error by accumulating it and then adding it to the error calculated in the next round of revisions.
 
OK, had some more fun turning the time & temperature functions into a single library.

Ran some tests this afternoon. Varied the temperatures that the crystal and the DS18B20 are exposed to… and happiness… over a 112 minute period of varying temperatures, the RTC offset vs. the PPS signal from the GPS receiver varied 6076us, which is good for 0.91PPM, 9-fold improvement over the default 10.2PPM this particular crystal exhibited at typical room temperatures. More importantly, the system now can compensate actively for varying temperatures.

I found some issues with the original library code, so I'll have another look at getting the curves characterized…. [Edit OK, done with that]

Each of the following runs is the compensation system running 100 rounds each and finding suitable combinations of PPM error compensation and time intervals to apply them over. Overnight results as follows:

Over a 1150s time period, the RTC-PPS offset changed by -595us or -0.52PPM. Onboard Temp. is approx. 26.94*C and 1157s of Time Constants.
Over a 1168s time period, the RTC-PPS offset changed by -632us or -0.54PPM. Onboard Temp. is approx. 27.12*C and 1165s of Time Constants.
Over a 916s time period, the RTC-PPS offset changed by -626us or -0.68PPM. Onboard Temp. is approx. 27.62*C and 913s of Time Constants.
Over a 847s time period, the RTC-PPS offset changed by -1113us or -1.31PPM. Onboard Temp. is approx. 31.56*C and 846s of Time Constants.
Over a 825s time period, the RTC-PPS offset changed by -1173us or -1.42PPM. Onboard Temp. is approx. 31.94*C and 825s of Time Constants.
Over a 645s time period, the RTC-PPS offset changed by -621us or -0.96PPM. Onboard Temp. is approx. 30.12*C and 647s of Time Constants.
Over a 645s time period, the RTC-PPS offset changed by -621us or -0.96PPM. Onboard Temp. is approx. 30.12*C and 647s of Time Constants.
Over a 510s time period, the RTC-PPS offset changed by -355us or -0.70PPM. Onboard Temp. is approx. 25.94*C and 509s of Time Constants.
Over a 556s time period, the RTC-PPS offset changed by 50us or 0.09PPM. Onboard Temp. is approx. 20.12*C and 555s of Time Constants.
Over a 537s time period, the RTC-PPS offset changed by 272us or 0.51PPM. Onboard Temp. is approx. 16.37*C and 539s of Time Constants.
Over a 545s time period, the RTC-PPS offset changed by 372us or 0.68PPM. Onboard Temp. is approx. 13.88*C and 546s of Time Constants.
Over a 717s time period, the RTC-PPS offset changed by 670us or 0.93PPM. Onboard Temp. is approx. 12.13*C and 717s of Time Constants.
Over a 642s time period, the RTC-PPS offset changed by 850us or 1.32PPM. Onboard Temp. is approx. 11.25*C and 642s of Time Constants.
Over a 525s time period, the RTC-PPS offset changed by 778us or 1.48PPM. Onboard Temp. is approx. 10.69*C and 525s of Time Constants.
Over a 400s time period, the RTC-PPS offset changed by 527us or 1.32PPM. Onboard Temp. is approx. 9.94*C and 395s of Time Constants.
Over a 439s time period, the RTC-PPS offset changed by 756us or 1.72PPM. Onboard Temp. is approx. 13.69*C and 441s of Time Constants.
Over a 544s time period, the RTC-PPS offset changed by 379us or 0.70PPM. Onboard Temp. is approx. 18.69*C and 541s of Time Constants.
Over a 525s time period, the RTC-PPS offset changed by 55us or 0.10PPM. Onboard Temp. is approx. 20.87*C and 525s of Time Constants.
Over a 647s time period, the RTC-PPS offset changed by -142us or -0.22PPM. Onboard Temp. is approx. 22.37*C and 647s of Time Constants.
Over a 735s time period, the RTC-PPS offset changed by -148us or -0.20PPM. Onboard Temp. is approx. 23.31*C and 738s of Time Constants.
Over a 667s time period, the RTC-PPS offset changed by -110us or -0.16PPM. Onboard Temp. is approx. 23.94*C and 667s of Time Constants.
Over a 585s time period, the RTC-PPS offset changed by -77us or -0.13PPM. Onboard Temp. is approx. 24.56*C and 585s of Time Constants.
Over a 455s time period, the RTC-PPS offset changed by -91us or -0.20PPM. Onboard Temp. is approx. 25.06*C and 455s of Time Constants.
Over a 375s time period, the RTC-PPS offset changed by -107us or -0.29PPM. Onboard Temp. is approx. 25.37*C and 375s of Time Constants.
Over a 330s time period, the RTC-PPS offset changed by -182us or -0.55PPM. Onboard Temp. is approx. 25.56*C and 325s of Time Constants.

What I am measuring is the time difference (in micros()) between the PPS signal from the GPS receiver ticking over and the same for the internal RTC_TSR register (which is what I am adjusting over time). The above data is about 4.4 hours worth of time over which the RTC drifted a total of about -1900us. The average drift (up or down) across temperatures ranging from 30*C to 10*C and back up was less than 2PPM. As you can see from the data, the drift is dependent on the temperature, with temperatures below the inflection point causing error in one direction and vice versa.

Assuming the temperature of the MCU is relatively stable, is this a valid way to measure the ability of the Teensy to keep time? (i.e. the time delta between the PPS signal and the RTC register tick over when the register has been adjusted 100 times for thermally-induced drift)

Even if it is, this small sample is by no means representative. FWIW, if the teensy is kept at or around room temperature, you may even be able to take a 'set and forget' approach by adjusting the RTC_TCR register once and still achieve +/-3PPM performance from about 10-30*C (at least with this particular CFS206 crystal).

The process illustrated a few things for me:
1) It's important to characterize the RTC crystal well (250+ data points - see below), ideally over a wide range of temperatures but especially around the temperatures you intend to use the teensy at.
2) Change the temperature very slowly (~0.2*C/step or less) to allow both components to reach the same temperature every time.
3) If you desire to actively compensate for temperature-induced error of the RTC, the RTC crystal and the temperature measurement device have to be thermally bonded OR the environment they operate in has to be well-insulated (to assure a similar temperature for both). For production, the two will be mounted on the same PCB, close to each other and they will be thermally epoxied to each other.
4) Do not rely on long correction periods to achieve perfection re: the compensation function. You're better off correcting every 10s and carrying over any error from one calculation to the next (i.e. the delta of the correction vs. the calculated error).

Screen Shot 2014-09-21 at 6.41.14 AM.png

Next step: Mount a LCD on the breadboard and then output cumulative results to the LCD so it can be standalone and run for months.
 
Last edited:
OK, re-ran the tests with a new compensation function and perhaps more importantly, a RTC crystal that is epoxied to a DS18B20. Just 40 measurements were used to characterize the crystal PPM error (Y axis) vs. temperature (*C). The blue dots are the measured results. In this instance, Excel added the polynomial that describes the data pretty well. The Teensy RTC library also does a least squares polynomial curve fit that matches the one calculated by Excel.

Due to lack of ice access at the moment, I cannot easily include low temp data. I also discovered a unintended side-effect of low-temp logging, i.e. the need for tight air exclusion or you risk condensation followed by corrosion if the board is not conformal coated.

RTC.jpg

Anyhow, this approach of bonding a DS18B20 to a RTC crystal seems promising, even if it seems counterintuitive to put a digital device close to a crystal. However, the DS18B20 seems to radiate so little EMI that the crystal seems completely unbothered by it. FWIW, I have the DS18B20 mounted at a right angle to the RTC crystal with the flat top running alongside the length of the RTC crystal metal body can.

The two are thermally bonded to each other and the underlying PCB using a thermal epoxy I purchased. That likely improves not only the accuracy of the RTC temperature being measured, it also ensures that the MCU crystal and the RTC crystal are relatively 'close' in terms of their respective temperatures.

In conclusion, compensated error is pretty good… for ~ 100 'corrected' measurements (red dots) only one exceeded 1PMM. The average was 0.3 PPM. There is some improvement potential as the remaining error is not evenly positive and negative, suggesting a small positive offset.

But, this library may be done as far as the basics. Documentation has to follow to make it more useful. Going forward, it would be interesting to compare the results of the epoxy-bonded RTC crystal vs. using the internal MCU temperature probe. Assuming the ADC is set up properly (external components, lots of averaging, good decoupling to prevent USB transmissions from influencing the ADC and all that), this may be the least expensive, sub-2PPM error for 10-30*C approach possible. That is, if your MCU has lots of spare time to do lots of analog reads re: its internal temperature sensor.

One likely limitation of the MCU-temperature measurement approach is the internal voltage reference, i.e. it's rate of drift as a function of temperature. So it would be good to understand that well. For me, the DS18B20 approach makes much more sense due to the low cost of these sensors and their relative ease of implementation.
 
Last edited:
A couple more observations:

I noticed 'glitches' in the data being produced as I verified sub-1PPM performance. Every once in a while, the data would jump. Being the slow guy I am it took me a few hours to figure it out... You, the reader are likely shaking your head in dismay, of course the issue is with shaking the RTC crystal itself.

In my setup, the outer can of the RTC crystal has been bonded to the PCB and the 1-Wire sensor with a thermal epoxy, so it makes sense that it'll perhaps become sensitive to movement. I'll have to verify this with a 'free-hanging' can but assume the behavior is similar but less trouble.

At 24.69*C, RTC drift this round = -2us over 15s period (i.e. -0.13PPM). Total Offset = -829us over a 2751s period (i.e. -0.30 PPM).
At 24.69*C, RTC drift this round = -1us over 15s period (i.e. -0.07PPM). Total Offset = -830us over a 2766s period (i.e. -0.30 PPM).
At 24.69*C, RTC drift this round = -2us over 15s period (i.e. -0.13PPM). Total Offset = -832us over a 2781s period (i.e. -0.30 PPM).
At 25.06*C, RTC drift this round = -96us over 4s period (i.e. -24.00PPM). Total Offset = -928us over a 2796s period (i.e. -0.33 PPM).
At 25.31*C, RTC drift this round = -3us over 4s period (i.e. -0.75PPM). Total Offset = -931us over a 2800s period (i.e. -0.33 PPM).
At 25.62*C, RTC drift this round = -4us over 4s period (i.e. -1.00PPM). Total Offset = -935us over a 2804s period (i.e. -0.33 PPM).
Any guesses when I moved the PCB? :p

Also evident are what I believe to be thermal stresses leading to spikes of unhappiness re: the crystal as I thermally cycle the PCB with everything on it. Interestingly, sometimes i can move around the PCB and nothing happens, at other times, even slight movements cause a rather large deviation. It's possible, I suppose, that built up thermal stresses due to the epoxy are being released more readily whenever the PCB is undergoing thermal changes.

Glitches like the below also occur during changes in temperature on their very own. No external force required... so I'll have hundreds of normal readings at steady state and then as the board thermally cycles, these deviations show up.

At 30.69*C, RTC drift this round = -3us over 11s period (i.e. -0.27PPM). Total Offset = -1248us over a 3458s period (i.e. -0.36 PPM).
At 30.50*C, RTC drift this round = -4us over 11s period (i.e. -0.36PPM). Total Offset = -1252us over a 3469s period (i.e. -0.36 PPM).
At 30.31*C, RTC drift this round = -5us over 11s period (i.e. -0.45PPM). Total Offset = -1257us over a 3480s period (i.e. -0.36 PPM).
At 30.19*C, RTC drift this round = 24us over 16s period (i.e. 1.50PPM). Total Offset = -1233us over a 3491s period (i.e. -0.35 PPM).
At 30.00*C, RTC drift this round = -68us over 5s period (i.e. -13.60PPM). Total Offset = -1301us over a 3507s period (i.e. -0.37 PPM).
At 29.94*C, RTC drift this round = -1us over 5s period (i.e. -0.20PPM). Total Offset = -1302us over a 3512s period (i.e. -0.37 PPM).
At 29.87*C, RTC drift this round = -2us over 5s period (i.e. -0.40PPM). Total Offset = -1304us over a 3517s period (i.e. -0.37 PPM).
At 29.87*C, RTC drift this round = -1us over 5s period (i.e. -0.20PPM). Total Offset = -1305us over a 3522s period (i.e. -0.37 PPM).

My plan going forward will be to not to thermally bond the DS18B20 and the RTC crystal can to the PCB and compare the performance. Removing the epoxy likely carries too much destructive risk.

Lastly, a 'one-sided' approach to determining the ideal RTC-Error thermal-drift compensation formula is not something I can recommend after some further testing. At low temperatures, there is significant error. I added some more data at the low end and the combined hot/cold data set produced a compensation formula which is somewhat similar to the one-sided version but different enough to also work well at low temperatures.

Some 2400 measurements later, I had some pretty good results. As you can see, the data is not entirely evenly distributed. But about 95% of the data points had an error of 1 PPM or less and 98% were below 5PPM. Overall, it seems quite likely that +/-1PPM accuracy is attainable for a range from about 0-40*C.

Chart.jpg
Note, the range here has been compressed, only shows the 95th percentile of the data. Some skewing is visible, suggesting that the curve fit is not perfect. Individually, the hot-side curve and the cold-side curve achieve an R^2 of ~0.9999 for their respective data sets but together they only make it to 0.999.
 
Last edited:
So I applied the correction factor suggested by the above to the original compensation function and let it run inside and outside the house for a while. Though there still were occasional glitches (most likely due to the epoxy applied to the legs / body of the RTC crystal) the overall function seemed to be quite stable with few errors over 0.5PPM. Here is a sample of three entries.

At 25.56*C, RTC drift this round = 1us over a 15s period (i.e. 0.07PPM). Total Offset = 69us over a 4787s period (i.e. 0.01 PPM).
At 25.56*C, RTC drift this round = 0us over a 15s period (i.e. 0.00PPM). Total Offset = 69us over a 4802s period (i.e. 0.01 PPM).
At 25.62*C, RTC drift this round = 2us over a 15s period (i.e. 0.13PPM). Total Offset = 71us over a 4817s period (i.e. 0.01 PPM).

The limited data I've collected (2 Teensies plus a couple of thousand data points) suggests that the CFS206 + DS18B20 combination can result in sub 0.5PPM error across a wide range of temperatures, assuming that care has been taken in measuring the crystal / temperature drift response first.
 
Now for "real world testing" of your TXCO ....
Take your TXCO "outside" in freezing temperatures and see if you still get +- 2 PPM :cool:
 
I did. See the chart above... :p ...that chart allowed me to further refine the correction curve, hence the latest results. After some 2000 seconds of outdoor cooling, I had the following feedback:

At 6.31*C, RTC drift this round = -9us over a 20s period (i.e. -0.45PPM). Total Offset = -566us over a 2067s period (i.e. -0.27 PPM).
At 6.37*C, RTC drift this round = -9us over a 21s period (i.e. -0.43PPM). Total Offset = -575us over a 2087s period (i.e. -0.28 PPM).
At 6.25*C, RTC drift this round = -7us over a 19s period (i.e. -0.37PPM). Total Offset = -582us over a 2108s period (i.e. -0.28 PPM).
Where offset = delta from initial RTC vs. PPS signal in micro seconds. Thus, Total Offset measures the drift of the RTC over a given time period.

Here is a chart to show the initial results today:
Chart.jpg

I then brought the Teensy back into the house. As it warmed, it experienced a few glitches but after 6000 seconds, the thermal drift was still OK for the vast majority of data points. The following chart has been limited to +/- 2PPM, where 96% of results were.
Chart2.jpg

The occasional glitch made the data move out of the usual sub-0.5ppm zone, but these glitches usually cancel each other out, i.e. a positive 4PPM excursion will be followed by a -4PPM excursion and so on. Here are the last three entries from that data set.

At 24.75*C, RTC drift this round = 1us over a 11s period (i.e. 0.09PPM). Total Offset = -855us over a 6059s period (i.e. -0.14 PPM).
At 24.69*C, RTC drift this round = 0us over a 11s period (i.e. 0.00PPM). Total Offset = -855us over a 6070s period (i.e. -0.14 PPM).
At 24.69*C, RTC drift this round = 1us over a 11s period (i.e. 0.09PPM). Total Offset = -854us over a 6081s period (i.e. -0.14 PPM).

Good enough for me at the kinds of temperatures I expect my units to be used at. Across a wider range of temperatures (i.e. -20*C or above 50*C) it's entirely likely that the error would increase into the 2PPM range. However, as my system is intended for indoor application, I consider the necessary operating range somewhere between 10-40*C, which this RTC seems to fulfill just fine.

As mentioned in the thread above, this sort of customization takes time, a PPS reference signal, and a wide range of temperatures to test across. For most hobbyists seeking a accurate, temperature-compensated clock using a DS3231 or eqv makes more sense. Besides keeping good time (+/- 2PPM across a wide operating range) the DS3231 can continue to compensate temperature drift whenever VCC is pulled and only VBAT is there.

A Teensy3-based, temperature-compensated RTC may achieve similar performance, but only as long as the Teensy has power. Once power is pulled, the VBAT battery may allow the Teensy3 RTC to keep running but the drift constants won't be updated continuously. So if you want to run your project off a battery with extended sleep times or need the time to stay accurate whether the Teensy3 is powered or not, then an external temperature-compensated clock is likely a better option.

However, for those of us with the luxury of line power, using the RTC on the Teensy 3 can be pretty rewarding. Its performance (when used with a good crystal and temperature compensation) can be pretty impressive and the price of admission is low: A DS18B20 costs less than a buck and it only requires a ceramic cap and a resistor. It can even be powered right off a MK20 leg, if need be. FWIW, I chose this route because I want the MCU to do as little as possible re: temperature compensation, i.e. I can init a temperature conversion once a second and the DS18B20 does the rest. Once a second the temperature is read out and a new conversion is initialized.

An even lower-cost route that looked very promising when I looked into it is using the MCU temperature sensor itself. This method has the drawback that the MCU will be somewhat occupied doing the measurements (as averaging across many samples helps improve performance significantly). Plus, you have to pay more attention to keeping the analog section of the MK20 happy, noise free, and all that. But if you were planning on making a couple of analog measurements anyway, then the marginal cost is effectively zero. An obvious risk is whether the MCU will be at the same relative temperature as the RTC crystal all the time. Insulation may help in that case, i.e. slow the rate of temperature change and allow the RTC to be as close as possible to the temperature of the MCU.
 

Attachments

  • Chart2.jpg
    Chart2.jpg
    57.6 KB · Views: 136
Last edited:
Hi Constantin,

Nice work, I've been following along and am now preparing to follow in your footsteps but with a different set up. I have an ST Microelectronics M41T62 RTC and a Measurement Specialties MS5637 pressure/temperature sensor (and EEPROM and humidity sensor, but these don't play yet) on a small board that will be attached to the Teensy 3.1. The RTC has a calibration register that can be set to add or subtract clock ticks so as to maintain clock calibration and correct for drift due to pcb stresses, temperature or anything else.

My plan is to measure the 512 Hz output from the RTC and count falling edges with Freqmeasure, then convert this to a ppm error and use this datum to adjust the calibration register. The claim is the clock can achieve a 2 ppm accuracy, but I think it can do better. I will also map out the temperature dependence of the clock drift for fun using the on-board temperature, but my plan is to use the 512 Hz signal to continuously correct the RTC, maybe once every ten seconds or so.

My question for you is, when you are quoting ppm drift and offset in your RTC experiments, how is this measured? Are you using a GPS time base as a standard or are you using an internal method as I have proposed.

I know we discussed this in a previous thread; I am just getting back to this project so I am asking again!

Edit: I see, you are using the pps from a GPS unit as a reference. I prefer my method if it works and I also have a supercap on the board that allows the timer to function for at least 15 hours if the power turns off so I expect to be able to run the whole thing off of a battery and keep the RTC going and compensated despite periodic battery failures.
 
Last edited:
Hi OneHorse,

Yes, I prefer the PPS signal on account of that being derived from an atomic clock but I can see how your approach would at least allow you to get to 2PPM performance.

For my purposes, I wish there were a way towards higher resolution time delay measurements than micros(); - do you know of one?

I like your supercap approach - it certainly works well for the external board you are using. The above solution is tailored with a single-minded focus on accurate time measurement while on line power. That's all I care about. When the Teensy is offline, I'm not measuring power, so keeping accurate time is less important.

That MS5637 is a tasty component. Measurement specialities has been releasing some compelling hardware lately, I like their htu21 sensor as a substitute for the sht21 temp / humidity sensor from SENSIRION. Too bad that after a brief introductory period they've decided to price the htu21d out of reach for hobbyists, just like the sht21. So I use the si7021 instead.
 
Last edited:
a way towards higher resolution time delay measurements than micros();

I don't know of any more accurate method than counting clock pulses, but this assumes an accurate clock!

I love the MS5637; it is accurate, reliable, and sooo easy to solder mount. I looked at the HTU21 but decided the ST HTS221 (why do they all have the same name?!) was a better deal at Euro1.33 each from Rutronik. Moreover, ST is working on a combined pressure/humidity sensor in a small package that might be even better than the MS5637. I have used STs LPS25H pressure sensor and, while it offers a lot of features that the MS5637 doesn't, I don't think it is quite as good. But it (2.5 mm x 2.5 mm), like the HTS221 (2 mm x 2 mm) comes in a very small package, making integration on an appallingly small board straightforward.

I will try counting pulses and see how far I can get by calibrating the RTC this way. I also have an Adafruit GPS module so I can try it your way too. When I get something to work I will report.
 
Over the last two years the explosion of accurate, tiny, and cost-effective components to measure humidity, temperature, pressure, etc. has been pretty astounding. My guess is that the trend has been driven in part by the automotive industry and similar users that seek better combustion management plus demand from thermostat manufacturers for better indoor climate control. Here are some other observations from work:

  • Dehumidifiers still mostly use the bigger DHT-22 or -11 style humidity / thermal sensor combinations.
  • Some washers use MEMS-based vibration sensors used to optimize spin performance (aka "prevent the washer from walking across the laundry room due to an unbalanced load") which potentially reduces the cast-concrete requirements.
  • Boilers and furnaces have also started to make a transition to better combustion management via feedback loops based on Oxygen sensors in the flue stream, vs. relying on fixed air/fuel ratios (cheap but potentially problematic if your local utility decides to change the local gas mixture).
  • Dishwashers have been using turbidity sensors for a long time and some also measure the pressure on the filter element (initiating a flush cycle whenever the washer is overloaded with gunk).
  • Etc.

Three years ago when I started this hobby, I still had to rely on Honeywell HIH series of analog humidity sensors that were sold at outrageous prices of $20+. Nowadays you can get a small digital package that offers similar, if not better, performance at 1/5th the cost without all the issues associated with carrying a sensitive analog signal from the sensor to a MCU, providing a clean analog power supply, and so on.

The only downside is having to use either I2C or a proprietary derivative thereof, which might necessitate a local dedicated MCU like a Atmel 328P to handle the conversions, serial communication, etc. All depends on the distance of the sensor to the MCU.
 
Last edited:
I think the other huge market for these tiny devices is in smartphones. Most manufacturers are touting the location/position detection capabilities embedded in their phones, which also offer pedometry, health monitoring (whatever that is), etc. The push for tiny, low-power devices is partly (mostly, I think) for this convergence into a "smart" wearable (or portable) application.

Most of these sensors support SPI communication, but I frankly prefer I2C. It only takes two wires and you can gang a million (OK, 128) devices on the same bus. SPI takes four + one wires and the SPI devices often collide unpredictably. But I am using the sensors close to the MCU. For distance, I use radios, which have their own issues! As you note, two MCUs are required; one to send and one to receive. Although I note that the convergence trend has hit the radio market as well with the nRF51822 blue tooth with embedded Cortex M0 processor, the ESP8266 wifi with embedded (I don't know which kind of) processor, and the TI C3300(?) or some such. Anyway, now there are small, low-power combo radios/wifi with embedded MCUs that can replace simple AVR MCUs.

What a wonderful world for the tinkerers!
 
Last edited:
What a wonderful world for the tinkerers!

... I couldn't agree more with the caveat that the likes of Paul Stoffregen, the helpful community here, and 3rd parties like the embeddedxcode project make the hardware accessible. All those tasty functions would remain locked up in the hardware if the tools we are so generously provided would not enable us to frolic about.

Thank you to all!

PS: I agree that I2C is, in general, a much easier protocol to master than SPI. Unfortunately, chips with I2C interfaces are relatively rare for 'faster' applications like ADCs. Especially for energy metering a I2C based I/O could make sense on account of that interface limiting the number of data lines that have to isolated in case the end user wants to measure a shunt and/or line power directly. Oh well.

Fwiw, our friends at MCP have instituted some sort of two line SPI interface for the MCP3910 precisely to address that issue. Why they focused on this instead of fixing the idiotic pin layout of the TSSOP package is beyond me. As far as I am concerned, the MDAT pins are useless and should have been omitted to allow one side of the chip to only deal with analog measurements and power while the other side would interface digitally, get digital power, and so on.
 
Last edited:
Status
Not open for further replies.
Back
Top