Using the Teensy 3.1 Real Time Clock (RTC)

One of my interests in the Teensy is the built-in RTC. Especially since the RTC module I was using last summer with an arduino ended up loosing time pretty quick (as I recall it would loose an hour a week).

PJRC’s information on time and Teensy can be found here:

http://www.pjrc.com/teensy/td_libs_Time.html#teensy3

Setting up the Hardware

True to form, I didn’t really research the Teensy, I just bought it. So once I got it I found it doesn’t have RTC ability until you solder a crystal onto the board.

The recommended crystal is Citizen part CFS-206, Digikey part 300-8303-ND, 300-8762-ND, 300-8763-ND, or 300-1002-ND. I noticed Jameco sells a 32.768 kHz, 12.5 pF crystal as well. Since I already needed some parts from Jameco, I bought the crystal there.

It appears the Jameco crystal ended up being just a smidge too long to solder into place with the headers I already soldered into place. I placed the crystal on top, standing upright. That works so-so for me since some of the headers are about that tall as well. Next time I’ll order the right crystal.

Setting Up Software

Before soldering the crystal into position, I first tested the Teensy RTC. I did so using the TimeTeensy3 program found in File | Examples | Time.

Hello!? That was weird, the RTC was just a few minutes off from the real-time. Now how could that possibly be? The code waits for serial input and if it see ‘T’ <integer> it uses that to set the RTC. Evidently the teensy loader initially sent this data because there is no way I would have accidently typed in the correct 32bit unix time stamp. That’s my theory anyway.

I removed the code that gets the clock from PC and was able to see every time I rebooted the Teensy, it would start at the same date & time. Not 1972 like you would think, but the initial time it evidently retrieved from the PC.

At this point, I soldered on the crystal and hooked up the battery. I altered the TimeTeensy3 program to accept a time from the keyboard only if <CR> is pressed, and a prompt is sent to identify what is going on.

This program works fine. The Teensy starts up, setting the system clock from the Teensy RTC. The user can change the time using the serial port by simply pressing <CR>. To set the time, you need to know the current unix type stamp. This website will help you calculate that:

http://www.unixtimestamp.com/

Here is the source to the program I have running:

#include <Time.h>  

void setup()  {

  Serial.begin(9600);
  delay(100);

  Serial.println("Waiting for high DTR");
  while (!Serial.dtr()) {}

  setSyncProvider(getTeensy3Time);
  if (timeStatus()!= timeSet) {
    Serial.println("Unable to sync with the RTC");
    } 
  else {
    Serial.println("RTC has set the system time");
    digitalClockDisplay();
    Serial.println();
    }
  }

void loop() {
  
  time_t t;
  
  if (Serial.available()) {
    if (Serial.read() == '\r') {
      Serial.setTimeout(5000);
      Serial.print("Enter unix time stamp(input is not echoed):");
      t = Serial.parseInt();
      Serial.print("read: ");
      Serial.println(t);
      if (t != 0) {
        Serial.println("Setting RTC");
        Teensy3Clock.set(t);
        delay(100);
        setTime(Teensy3Clock.get());
        }
      }
    }

  digitalClockDisplay();  

  delay(1000);
  }

void digitalClockDisplay() {
  char s[40];
  
  snprintf(s,sizeof(s),"%02d/%02d/%02d %02d:%02d:%02d", 
    month(), day(), year(), hour(), minute(), second());
    
  Serial.println(s);    
  
  }

time_t getTeensy3Time() {
  return Teensy3Clock.get();
  }

Battery Power Loss

What happens if the battery is disconnected while the Teensy is off?

Noted the time on the Teensy, then cut power to it. 10 secs later I disconnected the battery. I then waited 1 minute to restore the power to the battery and another minute to restore power to the Teensy.

I would expect that either the time comes back as Jan 1, 1972 (time stamp of 0) or the time power was removed from the battery. Neither. The time came back as several minutes before I cut power to the Teensy.

I wondered if setting the RTC might change this initial value that is restored when the battery is restored. So I set the RTC on every second.

That had the curious effect of the Teensy starting with a future time.

So as far as I can tell, there is no rhyme nor reason to what the initial RTC will be set to when power is applied.

Battery Power Drain

My last question is to guesstimate the lifetime of the CR2032 battery.

If the Teensy has power, it doesn’t drain the battery. So if the Teensy is designed to run continuously, then the CR2032 battery is only used during power interruptions.

Connecting it to an ammeter, I find that when the Teensy has no power, it is consuming about 1.6 uA from the CD2032.

Energizer rates their CR2032 at 240mAh. Well, that comes in at 150,000 hours or 17 years. I’m sure that is overly optimistic, but it will certainly last for a couple of years.

Is it Accurate?

I will leave this project assembled and let it run for a while, then update this blog entry. I checked after about 12 hours and it looks like it is a few seconds slow, but I’ll let it run longer and see how it goes.

Update

I’ve spent the last couple of weeks playing with the clock to check its accuracy. Without touching it, it is not too bad. After 7 days I had lost 7 secs. This is pretty good to me. It would take 8.5 weeks before I had lost a minute. But we can make it better.

Looking at the docs for Teensy3Clock.compensate function, you provide it with a corrected PPM/8, PPM being parts per million.

Calculating this is not too difficult. If I lost 7 secs in 7 days, that is 7 secs in 604800 secs. The ratio would be 7:604800. To then get the PPM, multiply by 1M. So the error is 7/604,800 X 1,000,000 or 11.57PPM. Since the compensate function is ppm/8 I need to multiply 11.57PPM by 8 to get 92.59, rounded to an integer is 93 and that is my correction:

Teensy3Clock.compensate(93);

Note that I am using +93 because I need to speed the clock up. If I needed to slow it down 7 secs/week I would use -93.

 

This entry was posted in c-tinys and tagged , . Bookmark the permalink.

10 Responses to Using the Teensy 3.1 Real Time Clock (RTC)

  1. Sean Straw says:

    I have several RTC modules I purchased from different vendors via Aliexpress. These have an I2C RTC chip, an I2C flash (32kbit – 4KB), crystal, battery holder, a few supporting capacitors and resistors, and an LIR-2032 battery cell. That’s a 3.6V Lithium-Ion sized to a 2032 package. I got these for less than US$1 apiece – WITH THE RECHARGEABLE BATTERY. As designed, the circuit is all set up to charge the battery whenever there is an external power source available (such as the device is powered sufficiently that you can comm with it). I found that the modules with battery could be had cheaper than I could find the batteries alone for – in your case, they may be a suitable source for the battery holder, the rechargeable battery cell, and the 32K crystal (assuming it is in a package compatible with the teensy).

    In the RTC library I was using with the modules, I found that when it initialized, it would attempt to comm with the clock, and if unsuccessful, would simply emulate an RTC from there on out (tracking time only so long as the uC was powered). The silly library did not expose whether or not it was running a real RTC, or the emulated one.

    I have yet to take the time to do it, but I was contemplating adding characterization code to the RTC library to attempt to compensate for drift as the battery voltage drops. Basically, read the battery voltage before powering up the RTC subsystem (something that can be done with the standalone RTC module – I don’t know about the Teensy), and compute the effect that would have on the RTC based on when the RTC was last used (this RTC has 56 bytes of internal NVRAM, so one could store a timestamp). However, even if I compute a coefficient for the effect of the voltage on the RTC, temperature could have a significant effect, and that would have to be monitored frequently in order to have an effective RTC compensation, and to do that would largely negate the utility of having the RTC running off of a backup battery.

    I presume the teensy RTC is built-in to the uC. All the RTCs I’ve dealt with, on AVR projects as well as ARM, have been external ICs, and checking datasheets for them, one finds that they have a state for the crystal oscillation having failed, which is what one would use to determine that any date value you might read is suspect. Poorly written libraries may ignore this state and fail to return it or even use it internally.

    If your teensy project is networked, you could set it up to periodically attempt to reset its clock via the old time protocol – tcp or udp port 37. If you have a linux box, the following may return 4 bytes (32 bits) of time information:

    nc localhost 37 | hexdump -C

    That’s a seconds-since-January 1st 1900 (NOT 1970!) epoch. No adjustment for clock skew or network latency, no host authentication, etc, but fairly hands-off and very low overhead to implement (and you can use UDP or TCP). Of course, it also presumes you have a host that still reports time in this way (or can set one up to).

    See here for a thread on the epoch time differences: http://stackoverflow.com/questions/8805832/number-of-seconds-from-1st-january-1900-to-start-of-unix-epoch

  2. defacato says:

    Thanks Dan. Very helpful. We’re doing a project using Teensy 3 boards to play Shakespeare quotes when triggered by movement (PIR sensors) in Senate House library in London. I’ve got the crystals for the RTC and now just need to get the batteries and holders. Your post has helped immensely. Thanks again. Steve & Hannah.

  3. Steven C says:

    You said: “Evidently the teensy loader initially sent this data because there is no way I would have accidentally typed in the correct 32bit unix time stamp. That’s my theory anyway.”
    Did you confirm that this is the case? I too was confused how the RTC has the correct time.

    • Dan TheMan says:

      Per Paul Stroffregen, creator of the Teensy:

      On my TO-DO list is a patch for Arduino to automatically define TIME_T to the time the program was compiled, and use that instead of a fixed date. The idea is the RTC would be automatically initialized to within a second or two of your computer’s time, if the crystal is present and it’s not previously been initialized. Of course, if you ever remove the Vbat power and reboot without reprogramming, the new default init time would be the moment when you compiled the program…. but at least it would give a nice “out of the box” initialization for working on projects.

      I assume this to-do was completed as that seems to make sense as to what we are seeing.

      • Steven C says:

        Ah, that makes more (engineering) sense. I couldn’t imagine the Teensy loader sending a “T” command every time – how would it know to do it or not? Thanks for the speedy response!

  4. Jerome B says:

    I’m playing with the Teensy 3.5 and the RTC clock is killing me, as the results from running the teensytime sample are different with and without the 3V Lithium battery connected.

    1) If you unplug the RTC battery and upload a teensytime sketch, the time will be auto-set (about 6 seconds behind laptop time, presumably from the sketch build) WORKS AS EXPECTED

    2) If you leave the RTC battery connected with the wrong time previously set and run the SAME sketch, it will refuse to set/show the current time, but WILL show whatever time is still running in the RTC.

    In the background, it will set the current PC time from time of build/upload into the memory somewhere, so that if you disconnect the RTC battery and reconnect when off, the Teensy will magically show the PC time at time of upload/build and run from there if you reconnect the RTC battery.

    If anyone knows how to force the PC auto time update during the sketch load process, please let me know, as I’m assuming it is hidden in the TimeLib.h somewhere

    3) Additionally, if you manually set the Teensy time using a Serial input of Unix time, such as T1502744541. The Teensy RTC will refuse to auto-update to the PC time during any future teensytime sketch upload until the RTC battery is disonnected. (Quite frustrating)

    The Teensy is a super Awesome device, just this little issue is beating me. Thanks.

  5. Dan TheMan says:

    I suggest posting this to the prjc forum.

    https://forum.pjrc.com/forum.php

    The teensy creator monitors that forum and either he, so someone with lots of Teensy experience will probably respond.

    I’ve been using teensy 3.2s almost exclusively for the past 2 years, but I haven’t needed the RTC so I don’t have any insight to offer.

  6. Anders Strand says:

    I am very interested in the power usage when using RTC. You write that you measure a current draw of 1.6 uA when running your code. This seems extremely low to me, as (as far I can see), your code does not put the teensy to sleep. Do you have any insights on how you achieve such a low current consumption?

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.