TimeTeensy3 example -> Time chosen is not permanent

Status
Not open for further replies.

Pedrucius

Member
Hello all,

I need to set the Date and Time of my system. So, I've followed this example: https://github.com/PaulStoffregen/Time/blob/master/examples/TimeTeensy3/TimeTeensy3.ino
I've used Processing, to send the data through Serial port.

The function digitalClockDisplay() (found in the example) show that the previous time (compilation time) is correct and the time sent through Serial is also correct. But when I turn off the system, the RTC reset to the previous value (compilation time).

Do I need to change the RTC init code? https://github.com/PaulStoffregen/cores/blob/master/teensy3/mk20dx128.c#L1098

TL;DR: How do I overwrite RTC value, defined in compilation?

Thank you.
 
Does this teensy have a battery and RTC crystal fitted? You need both to hold time while power is out.

Yes. The fact is that it hold the compilation time, but when I change it using the example code and turn it off, the time reset to the compilation one.

Maybe I should put the special flag on the VBAT register after the Teensy3Clock.set(t): *(uint32_t *)0x4003E01C = 0x5A94C3A5; (as seen in the core code).
 
Which teensy are you using? maybe a photo of how your crystal and battery are attached.

I just confirmed that T3.6 with 3v3 power to VBAT, and gnd to GND running Examples>Time>TimeTeensy3 retains RTC time after I pull the USB cable. The T3.6 comes with 32khz RTC crystal. I'm running Arduino 1.8.3 and teenysduinio 1.37

The RTC can be set by the time-of-compile default, or using processing, or NTP, or GPS, or manually with
setTime(10,10,10,11, 12, 2017);
Teensy3Clock.set(now());



https://www.pjrc.com/teensy/td_libs_Time.html
 
Last edited:
Which teensy are you using? maybe a photo of how your crystal and battery are attached.

I just confirmed that T3.6 with 3v3 power to VBAT, and gnd to GND running Examples>Time>TimeTeensy3 retains RTC time after I pull the USB cable. The T3.6 comes with 32khz RTC crystal. I'm running Arduino 1.8.3 and teenysduinio 1.37

The RTC can be set by the time-of-compile default, or using processing, or NTP, or manually with
setTime(10,10,10,11, 12, 2017);
Teensy3Clock.set(now());

Hello manitou, how are you?

Thanks for the reply. Actually, I'm using an adapted board, made for a specific project here in my university. I'll have these specifications (how battery and crystal are connected) maybe monday or tuesday.

Nevertheless, I think it's strange that the time-of-compile is recorded, but the Processing one, not.

I don't know if it is relevant, but I'm using PlatformIO as my IDE.
 
one other thing to try is adding Serial.println(Teensy3Clock.get()); to your loop(). If that value isn't changing then your 32khz crystal isn't working. if the values are changing but RTC still goes back to time-of-compile setting after cycling power, then your battery isn't powering the 32khz crystal ....

Nevertheless, I think it's strange that the time-of-compile is recorded, but the Processing one, not.
If a battery is not providing power to the RTC when the teensy is powered down, then any RTC settings will be lost. When the teensy is powered up, the core software checks the TIF bit in the RTC_SR. If TIF is set (nothing was powering the RTC), then the RTC time is invalid, and the core software uses the time-of-compile to set the RTC.

https://github.com/PaulStoffregen/cores/blob/master/teensy3/mk20dx128.c#L1097
 
Last edited:
Hello, @manitou

The problem was my battery, after all. It was a bad connection that was causing the problem.

Thank you for your help!
 
White flag :(

I have read many threads include this but I don't know what I still can do.

I have a T4 with coin battery CR2032 soldered on VBAT-GND pins. (I have tried 2 different batteries for my safety).

I adjust date and time at runtime with four buttons (+1 hour, -1 hour, +1 minute, -1 minute)
but when I power off and restart I see the time without any modification, but it works because it keep in memory the time.
es. if I power on after 1 day, I can see the right date and time, but if I add +2 hours to compensate the UTC + 2....nothing, it cames back with his settings.

Code:
#include <TimeLib.h>            // https://github.com/PaulStoffregen/Time

time_t clock; 

void setup
{
     Serial.begin(115200);
     while (!Serial) ;

     // set the Time library to use Teensy 4.0's RTC to keep time
     setSyncProvider(getTeensy3Time);
     setSyncInterval(60);
     if (timeStatus()!= timeSet) Serial.println("Init: RTC -> Unable to sync with the RTC");
     else Serial.println("Init: RTC has set the system time");
}

void loop
{
      check_btn(); // read which button has been pressed

      if (i==1)  RTC_Time_set(60); // + 1 minute
      if (i==2)  RTC_Time_set(-60); // - 1 minute
      if (i==3)  RTC_Time_set(+3600); // + 1 hour
      if (i==4)  RTC_Time_set(-3600); //  - 1 hour

      display_time();  // show time on screen
}

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

void RTC_Time_set(int x)  // add x seconds
{
    clock = now();
    setTime(clock + x); 
    delay(100);
    Teensy3Clock.set(now());  
}
 
I copied your code into Arduino, but it does not compile. Both loop and setup are syntax errors. If I fix those, it still cant be used because check_btn() and display_time() are missing.

Please, spend a few minutes to compose a small but complete stand-alone program which demonstrates the problem. We can help you much better that way.
 
Ok Paul!
Thanks for your reply.

I will do a small sketch with serial input and output because the two functions use other hardware.
 
This is a complete sketch
Code:
#include <TimeLib.h>            // https://github.com/PaulStoffregen/Time

time_t clock; 

int i = 0;

void setup()
{
     Serial.begin(115200);
     while (!Serial) ;

     // set the Time library to use Teensy 4.0's RTC to keep time
     setSyncProvider(getTeensy3Time);
     setSyncInterval(60);
     if (timeStatus()!= timeSet) Serial.println("Init: RTC -> Unable to sync with the RTC");
     else Serial.println("Init: RTC has set the system time");
}

void loop()
{
      i = check_btn(); // read which button has been pressed

      if (i==1)  RTC_Time_set(60); // + 1 minute
      if (i==2)  RTC_Time_set(-60); // - 1 minute
      if (i==10)  RTC_Time_set(+3600); // + 1 hour
      if (i==20)  RTC_Time_set(-3600); //  - 1 hour

      display_time();  // show time on screen
}

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

void RTC_Time_set(int x)  // add x seconds
{
    clock = now();
    setTime(clock + x); 
    delay(100);
    Teensy3Clock.set(now());  
}

int check_btn()
{
    if (Serial.available() > 0)
        {
            String data = "";
            char x;
            while (Serial.available())
              {
                  x = Serial.read();
                  
                  if (isDigit(x)) 
                      data += x - '0';
              }
            return data.toInt();   
        }
}

void display_time()
{
    char s[10];
    sprintf(s, "%02d:%02d:%02d", hour(), minute(), second());
    Serial.println(s);
    delay(1000); 
}


Serial Monitor:
Code:
Init: RTC has set the system time
19:35:07
19:35:08
19:35:09
19:35:10
19:35:11
19:35:12
19:35:13
19:35:14
19:35:15
19:35:16
19:35:17
18:35:18      [COLOR="#FF0000"]// -1 hour[/COLOR]
18:35:19
18:35:20
19:35:21      [COLOR="#FF0000"]// +1 hour[/COLOR]
20:35:22      [COLOR="#FF0000"]// +1 hour[/COLOR]
20:35:23
20:35:24
20:35:25
20:35:26
20:35:27
20:35:28
21:35:29      [COLOR="#FF0000"]// +1 hour[/COLOR]
21:35:30
21:35:31
21:35:32
21:35:33
21:35:34
21:35:35

Power off -> wait a few minutes -> power on
Code:
Init: RTC has set the system time
19:39:32
19:39:33
19:39:34
19:39:35
19:39:36
 
In the Teensy 4, Teensy3Clock.set(x) only sets the RTC, not the SRTC. The SRTC is the clock that is maintained by the coin battery on Vbat. The SRTC is set by the loader. When your program starts up, it sets the RTC from the SRTC. So you can change the RTC in your program, and that works as long as you don't interrupt the power. As soon as you do that, on startup the RTC is set from the SRTC again, which has been counting away in the background from the time that was set by the loader.

The solution I've come up with is to modify the routine that Teensy3Clock.set(x) calls to set the SRTC rather than the RTC, and then re-sync the RTC from the SRTC. Replace the rtc_set() routine in cores/teensy4/rtc.c with the following code:

Code:
void rtc_set(unsigned long t)
{
   // stop the RTC
   SNVS_HPCR &= ~(SNVS_HPCR_RTC_EN | SNVS_HPCR_HP_TS);
   while (SNVS_HPCR & SNVS_HPCR_RTC_EN); // wait
   // stop the SRTC
   SNVS_LPCR &= ~SNVS_LPCR_SRTC_ENV;
   while (SNVS_LPCR & SNVS_LPCR_SRTC_ENV); // wait
   // set the SRTC
   SNVS_LPSRTCLR = t << 15;
   SNVS_LPSRTCMR = t >> 17;
   // start the SRTC
   SNVS_LPCR |= SNVS_LPCR_SRTC_ENV;
   while (!(SNVS_LPCR & SNVS_LPCR_SRTC_ENV)); // wait
   // start the RTC and sync it to the SRTC
   SNVS_HPCR |= SNVS_HPCR_RTC_EN | SNVS_HPCR_HP_TS;
}
 
Perfect!

i confirm the correct solution of Silverlock.

Thanks

Me too.

Just put it in my sketch instead of calling Teensy3Clock.set(now()); I called the renamed :: Rrtc_set(now());

Two things of note:
1 > TeensyLoader pushes new PC time on any/all upload
-> problem when the device time is not local time.
-> prior compile time was only written when RTC reported 'time not set'

2 > TeensyLoader gets PC time and with TD 1.52b2 is always setting time BACK one hour from actual time reported by the PC.

<edit>: Note added to the TD 1.52beta2 thread
 
This little sketch fetches the T4 RTC time and uses it to set the teensy now() time. The RTC time is being set from the last upload time for the sketch, and i verified that 3.3v on VBAT keeps the RTC running when USB power is removed from the T4. As others have noted, the upload time is off by one hour, but the bootloader is setting the proper RTC register for retention by VBAT power. Arduino 1.8.11, 1.52-beta2
Code:
#include <time.h>
#include <Time.h>

void setup() {
  while (!Serial);
  time_t tt = rtc_get();
  Serial.printf("RTC: %s", ctime(&tt));
  setTime(tt);
  tt = now();
  Serial.printf("now: %s", ctime(&tt));

}

void loop() {
}
This sketch won't compile on Windows or MAC.

I also confirmed your changes fix core rtc_set().

the off by one hour applies to Windows and linux but not MAC?
 
Last edited:
I've ran into the same issue as the OP. I ran the timeTeensy3 code and it set the RTC but it keeps reporting the compiled time from the sketch. I have access to a nice o-scope and I can see the output from the 16Mhz crystal but can not see the 32Khz from the little crystal next to it. I do have a 3.3V source powering the Vbat and ground header. What model/part number is used for the crystal on the T3.6?

Thanks Ryan
 
The T_3.6 uses no external crystal - RTC support is built in when the Teensy is powered - when powered the RTC gets proper power as needed.

The vBat pin specifies 3V coin cell - not sure putting 3.3V on that is right - and not needed except for battery backup when Teensy loses power.
 
Most charged coin cells start out around 3.3ish volts and settle in around 3.1 with a small load. I've been measuring the one I have wired in over the past few days.
 
mojato and Silverlock: thanks so much for this thread! I was running into the same problem as mojato where I had battery backup for the RTC and I was using a touchscreen to set the time, but the changes that I made using the touchscreen were always lost after power cycling the Teensy 4.0. This problem has had me scratching my head for some time, so really glad that the fix is rolled into the latest teensy release.
 
Status
Not open for further replies.
Back
Top