Teensy 3.1 time accuracy

Status
Not open for further replies.
I'm doing a GPS light display based project with the Teensy 3.1, FastLED, and without an RTC. The idea is to calculate sunrise and sunset, and turn the lights on and off based on time of day. This works great. However, one of my light displays (Christmas) is very timing sensitive, and it gets a bit choppy if I pop off to read the GPS receiver every now and then. I can probably optimize a bit, but the easier answer is to just let the Teensy keep time on it's own for the 4-6 hours the display will be on. I really haven't tested this yet, and thought I would ask first as the test takes time to run. After the display is over, I fall back to sync'ing to GPS time. So, the question is, will the Teensy without an RTC keep time fairly accurately so that I can turn the lights off and be within a few minutes of the target off time? Or, do I need to add an RTC for this specific scenario?

Thanks for any help.
 
My Teensy crystals are all within 20 ppm of the correct frequency, and the drift with temperature (near 20 C ambient) is less than 0.5 ppm / deg. C
In 6 hours, a 20 ppm error is less than 1/2 second, so it might be off by one second after 14 hours, or about one minute over a month.
 
Yeah, if you resync to GPS every 6 hours, I'm pretty sure you'll be happy with the accuracy of the crystal on Teensy.
 
You don't need a RTC but you will need some time and measurements. If you temperature compensate your RTC you can get it below 1PPM error within -10 to 40*C. But you have to use the GPS to measure error across a wide range of temperatures. Search for the TXCO hilarity thread to see what I mean

For most users, something like the Chronodot is the best response. Much less time needed to get it going and better than 2ppm performance across a very wide range of temperatures. That equates to about a minute a year in worst case.

As to which method to use, what is your time worth? For a single application, a Chronodot or eqv. makes much more sens.
 
Last edited:
I have been researching frequency/timing/crystal accuracy for 6 months now, so your question on Teensy 3.1 crystal accuracy prompted me to measure mine. Attached are two pictures of my frequency measurement taken two minutes apart Pic001.jpgPic002.jpg. Ambient is 24 deg C. The crystal module is 16 MHz and is multiplied internally by the mcu with a factor of 6 to 96 MHz. These pictures are made using Software Defined Radio (HDSDR) with a Funcube Pro+ USB receiver module. I calibrate my HDSDR display regularly using a number of freq standards, so I know it is accurate to around 1 Hz.

If you look at the first picture and the lower right spectrum window, you can see the Teensy 3.1 signal at the 700 marker - if I disconnect Teensy from USB power this disappears and reappears the instant I reconnect. The signal at 673 Hz is a "spur" from a local FM station transmitting on 96 MHz - it does not disappear when Teensy is disconnected. This first picture shows Teensy clock operating at 95,999,556 Hz - so that's accurate to 443 parts (Hz) @ 96 million = approx 5 ppm at the instant I made the picture.

The second picture is taken exactly 2 minutes later and you can now see Teensy clock has drifted to 695 Hz - the spur has not moved from 673 Hz. The drift downwards is due to the crystal still warming up after being powered up for 30 minutes. I measured again an hour afterwards and the Teensy clock was wandering around the 675 Hz mark. If I waved my hand over the crystal to make a breeze, I could easily make it rise by 10 Hz. It went back again a few minutes later.

These figures give you ball park expectations of Teensy 3.1 accuracy.
 
Teensy LC crystal stability

Here's my plot of frequency error vs temperature over 4 days for my beta version of Teensy LC. This particular unit runs about 17 ppm fast, with a temperature coefficient around -0.3 ppm/deg.C just based on the indoor temperature variation over the day.

TLC-ppm-vs-degC.jpgTLC-time.jpg

Here is the code which generated the data (needs a Teensy, a 1-PPS signal input from GPS, and LM35 temperature sensor). You should change to #define VREF (1.200) if you use Teensy 3.0/3.1 instead of Teensy LC.


Code:
// based on PaulS's FreqMeasure for Teensy example
// Digital Input: 1 PPS signal : on Teensy LC: Pin 16  on Teensy 3/3.1: Pin 3
//  Analog Input: 10 mV/degC temp from LM35 : Analog 1

#include <FreqMeasure.h>

#define TEMP_IN A1           // analog input with 10 mV/deg.C from LM35 temp sensor
#define AVERAGES 30          // how many input pulses to integrate over
#define VREF (3.316)         // Teensy LC ADC reference voltage (= Vdd power supply)
//#define VREF (1.200)         // Teensy 3.0/3.1 ADC internal reference voltage
#define ADCMAX (65535)       // maximum possible reading from ADC
#define NOMCOUNT (48000000)  // nominal oscillator frequency count
#define NOMCM (48)           // nominal count divided by 1E6 (for ppm calculation)

void setup() {
  pinMode(TEMP_IN,INPUT);   
  analogReference(INTERNAL);  // set analog reference to internal ref
//  analogReference(EXTERNAL);  // set analog reference to external
  analogReadRes(16);          // Teensy: set ADC resolution to this many bits
  analogReadAveraging(16);    // average this many readings
 
  Serial.begin(115200);
  FreqMeasure.begin();
}

double sum=0;
double ppm;  // frequency error in ppm
int count=0;
unsigned long lastT = 0;
unsigned long deltaT;
unsigned long newT;
unsigned long reading = 0;  // how many measurements we've reported
boolean firstTime = true;
double x=0; // analog temperature reading (LM35)
unsigned long tsamp=0;  // how many temperature readings we've done
long fcount;  // raw frequency count value

void loop() {
  if (FreqMeasure.available()) {
    newT = micros();
    fcount = FreqMeasure.read();
    sum = sum + (fcount - (NOMCOUNT));
    count = count + 1;
    if (count >= AVERAGES) {
      deltaT = newT - lastT;
      lastT = newT;
      if (firstTime) {
        firstTime = false;
        Serial.println("Rdg , degC , ppm");
      } else {
        ppm = sum / (NOMCM * AVERAGES);
        x /= tsamp;
        float degC = 100 * (VREF/ADCMAX)*x; // LM35 temp sensor = 10 mV/C
        reading++;
        Serial.print(reading);       Serial.print(" , ");
        Serial.print(degC,4);        Serial.print(" , ");
        Serial.print(ppm,3);
        Serial.println();
      }
      sum = 0;
      count = 0;
      x = 0;
      tsamp = 0;
    }
  } else {
    x += analogRead(TEMP_IN); 
    tsamp++;
  }
} // end loop()
 
Jbeale, just for clarification: the crystal on your beta LC has the following markings, yes?
16.000 TB 24 90
in other words it is the NX3225SA-16.000M-STD-CSR-1 as also used on Teensy (2.0, ++2.0, 3.0, 3.1, betaLC) up to at least March 2015. That crystal had the following specs:
Frequency Tolerance ± 15 x 10-6 max. ( +25 °C )
Frequency vs Temperature ± 15 x 10-6 max. ( -10 ~ +75 °C )
Temp range -10 to +75 °C

I mention this for the help of people finding this thread later, and drawing conclusions about the crystal on their board; it may have switched to another one at that point.

We're actually switching to an Epson crystal that's rated for 18 ppm, but with a wider temperature range.

My guess (based on "Epson" and "wider temp range" and "18ppm" plus the same size of 3.2x2.5mm, similar resistance and capacitance requirements), is that this will be the EPSON TSX-3225 16.0000MF18X-AC3 which has
Frequency Stability ±18ppm
Frequency Tolerance ±10ppm
Ageing ±2 x 10-6 / year Max
Temp range -40 to +85 °C
 
The crystal on my Teensy LC is marked only "6360 T 4Y02" with no logo. It's a green beta board, quite possibly not what will be on the standard one.
The crystals on some recently purchased (last week) T3.1 from OSH Park are marked "16.000 46 41 30" with a logo that looks like a triangle wave inside a box.
 
FWIW, i have measured crystal ppm for various MCU's and TCXOs using GPS and NTP. As noted, age, voltage, capacitance, and temperature can effect frequency. anecdotal data is here
https://github.com/manitou48/crystals/blob/master/crystals.txt

it's probably worth measuring the drift on your teensy in their operating environment to see how often you need to correct or possibly account for the drift in your time calculation (as NTP does on linux systems). You could use GPS, TCXO, or an NTP host to calculate drift.
 
FWIW, I was quite impressed with the ability of the NX2520SA-16MHZ crystal on the Teensy 3.1 to survive restarts at -40*C, ie well outside its stated operating range. For my clock applications, the quality of the MCU crystal was 'only' important while trying to measure the temperature response of the RTC crystal, ie I'd rely in part on the MCU as well as a GPS PPS signal to determine drift.

But, by measuring the two together, one can come up with a pretty good correction formula. If I were at home this week I'd be playing with the LC to see if I could get the RTC function to be happy. The LC would likely make a very good MCU for a simple clock or even a thermostat.

In fact, I wish I could reverse engineer the interfaces on my Honeywell thermostats to perform a Teensy transplant and drive the TFT display, etc while putting open hardware in the back.
 
Last edited:
Status
Not open for further replies.
Back
Top