Teensy3.compensate - Does it still exist?

Status
Not open for further replies.

Talkiet

Well-known member
I'm having a nightmare trying to get an accurate clock working on my T3.5... The most frustrating bit is that there is apparently an ideal function that will do exactly what I need but I can't make it work...

Teensy3.compensate(x)

Whatever I do, I can't get this to work. I have modified one of the example RTC programs and am using a scope to watch the variance between the GPS PPS and the software generated PPS... Whatever I set the compensate to, and however long I wait, the software PPS keeps marching off at a consistent rate of around -20ppm.

Is it still supported to use the compensate function to slightly change the speed of the RTC? The last time "teensy3clock.compensate" appeared on this forum according to a google search is in 2013 (https://forum.pjrc.com/threads/24149-Teensy-3-0-RTC-drift)

I note that compensate doesn't show up here - https://github.com/PaulStoffregen/Time

Here's the code with the command apparently compiling, but having no effect.

Code:
/*
   TimeRTC.pde
   example code illustrating Time library with Real Time Clock.

*/

#include <TimeLib.h>

void setup()  {
  pinMode(14, INPUT);
  pinMode(24, OUTPUT);
  // set the Time library to use Teensy 3.0's RTC to keep time
  setSyncProvider(getTeensy3Time);
  setSyncInterval(2);
  Teensy3Clock.compensate(10000);
  Serial.begin(115200);
  while (!Serial);  // Wait for Arduino Serial Monitor to open
  delay(100);
  if (timeStatus() != timeSet) {
    Serial.println("Unable to sync with the RTC");
  } else {
    Serial.println("RTC has set the system time");
  }
}

void loop() {
  if (Serial.available()) {
    time_t t = processSyncMessage();
    if (t != 0) {
      Teensy3Clock.set(t); // set the RTC
      setTime(t);
    }
  }
  digitalClockDisplay();
  delay(1000);
}

void digitalClockDisplay() {
  digitalWriteFast(24, HIGH);


  // digital clock display of the time
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.print(" ");
  Serial.print(day());
  Serial.print(" ");
  Serial.print(month());
  Serial.print(" ");
  Serial.print(year());
  Serial.println();
  delay(1);
    digitalWriteFast(24, LOW);
}

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

/*  code to process time sync messages from the serial port   */
#define TIME_HEADER  "T"   // Header tag for serial time sync message

unsigned long processSyncMessage() {
  unsigned long pctime = 0L;
  const unsigned long DEFAULT_TIME = 1357041600; // Jan 1 2013

  if (Serial.find(TIME_HEADER)) {
    pctime = Serial.parseInt();
    return pctime;
    if ( pctime < DEFAULT_TIME) { // check the value is a valid time (greater than Jan 1 2013)
      pctime = 0L; // return 0 to indicate that the time is not valid
    }
  }
  return pctime;
}

void printDigits(int digits) {
  // utility function for digital clock display: prints preceding colon and leading 0
  Serial.print(":");
  if (digits < 10)
    Serial.print('0');
  Serial.print(digits);
}

Cheers -N
 
I note that compensate doesn't show up here - https://github.com/PaulStoffregen/Time

No, of course not. The Time library keeps track of time using ordinary Arduino timing functions. It's meant to "sync" with other libraries, like GPS or a NTP server somewhere on the internet. The concept is those time sources might not always be available or might involve significant delay to obtain the current time. So the Time library keeps track itself and lets you query the current time very quickly & efficiently, and it tries to keep its time in sync with another source. When that other source is a built-in RTC, this might seem counter-intuitive or overkill. Just keep in mind the usage model is ability to sync to something like GPS where new info arrives infrequently and the antenna might be blocked sometimes.

So the time adjust is part of the Teensy core library, not the Time library which knows nothing of the many things it can sync to, only how to sync to them.
 
Ok - I think I get that now... I have written what I hope is a simple program to illustrate what I am clearly not understanding. I had hoped while clearing out the other rubbish I would find what I was missing but nope!

The following program exhibits almost the precise predicted drift (-20.5ppm) - in that after running for 5 minutes, the second() as referenced in void loop() is 6.276ms slow.

When I run the sketch again with " Teensy3Clock.compensate(171);" uncommented, I still observe the same drift from the second() in void loop(). (6.260ms measured slow)

I have reviewed this thread - https://forum.pjrc.com/threads/24563-Question-re-RTC-compensation-function?styleid=1 and it looks like while it got solved there, I just can't derive from the details in the thread what I am missing/doing wrong.

Surely it's something obvious/stupid. I have left the sketchs running for 30 minutes with no changes to the rate of drift (my sketches and the one from the thread linked above).

Code:
#include <TimeLib.h>
int32_t oldsecond;

void setup()  {
  Serial.begin(115200);
  pinMode(14, INPUT); //PPS from Neo6M GPS
  pinMode(24, OUTPUT); // Generates a pulse on new second to compare on scope
  setSyncProvider(getTeensy3Time);
  setSyncInterval(5); // This is calling every 5 _seconds_(?) to update the Time set in time library where seconds() comes from?
  while (digitalReadFast(14) == HIGH);
  while (digitalReadFast(14) == LOW); // Wait for the start of a fresh PPS pulse
  Teensy3Clock.set(1612051200); // Set a specific time on the RTC
  setTime(Teensy3Clock.get());  // And set the Time library time to the RTC
  //Teensy3Clock.compensate(171); // So far I am unable to observe a difference in drift whatever this number
}

void loop() {
  if (second() != oldsecond) { // On first iteration after ticking over to new Time library second
    oldsecond = second();
    digitalWriteFast(24, HIGH); // Pulse to compare with GPS PPS on
    digitalClockDisplay();
    digitalWriteFast(24, LOW);  // and off
  }
}

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

void digitalClockDisplay() {
  // digital clock display of the time
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.print(" ");
  Serial.print(day());
  Serial.print(" ");
  Serial.print(month());
  Serial.print(" ");
  Serial.print(year());
  Serial.println();
}

void printDigits(int digits) {
  // utility function for digital clock display: prints preceding colon and leading 0
  Serial.print(":");
  if (digits < 10)
    Serial.print('0');
  Serial.print(digits);
}

Thanks for your patience.
Cheers - Neil G
 
Status
Not open for further replies.
Back
Top