Teensy 4.1 RTC reset

Status
Not open for further replies.

Johannes

Active member
I want to run my Teensy 4.1 on UTC or GPST for an astronomy project. In case of problems with the GPS (like testing indoors) I want to fallback to the RTC and have attached a Battery to VBAT/GND as described. With the battery Teensy 4.1 keeps the time with some moderate accuracy also when turned off, which is ok for me.

But: whenever I load a new version of my sketch (arduino-IDE) the time is gone! It is set to some weird time which is similar to my wallclock time even including daylight saving!
This time is not fit for astronomical calculations, and I want to have my GPST back! This is the reason I have installed a battery in the first place.

I get the impression that there is a strange mechanism at work that resets the Teensy RTC time every time I press the button on the Teensy and everytime I upload a sketch.
Even in my case, when I have attached the battery all the time without power failure.

Below is a sketch to demonstrate this behavior: With this sketch I can change the RTC time by pressing 2 buttons.
After powering off and on the RTC has faithfully remembered the changed time, but when uploading the sketch again the time is lost!

Please help me! This is quite annoying during development. What can I do? Is there a way to tell the teensy to leave my RTC clock as it is?

Yours,
Johannes

Code:
#include <LiquidCrystal.h>

const int rs = 27, en = 28, d4 = 29, d5 = 30, d6 = 31, d7 = 32;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

void DecomposeDay(int day,int &y,unsigned int &m,unsigned int &d) {
    // day.. number of days since 1970.01.01
  day += (5*(400*365+97) -(30*365+7) -(31+29));
    // number of days since 0000.03.01
  y = day / (400*365+97);
  day -= (400*365+97) * y;
  if (day < 0) {day += (400*365+97);--y;}
  y *= 400;
  {
    const int c = day / (100*365+24);
    y += 100 * c;
    if (c > 3) {
      m = 1;
      d = 28;
      return;
    }
    day -= (100*365+24) * c;
  }
  {
    const int h = day / (4*365+1);
    day -= (4*365+1) * h;
    y += 4 * h;
  }
  {
    const int h = day / 365;
    y += h;
    if (h > 3) {
      m = 1;
      d = 28;
      return;
    }
    day -= 365 * h;
  }
  if (day < 31+30+31+30+31+31)
    if (day < 31+30+31)
      if (day < 31)
        {m = 2; d = day;} // mar
      else
       if (day < 31+30)
         {m = 3; d = day-31;} // apr
       else
         {m = 4; d = day-(31+30);} // may
    else
      if (day < 31+30+31+30)
        {m = 5; d = day-(31+30+31);} // jun
      else
        if (day < 31+30+31+30+31)
          {m = 6; d = day-(31+30+31+30);} // jul
        else
          {m = 7; d = day-(31+30+31+30+31);} // aug
  else
    if (day < 31+30+31+30+31+31+30+31+30)
      if (day < 31+30+31+30+31+31+30)
        {m = 8; d = day-(31+30+31+30+31+31);} // sep
      else
        if (day < 31+30+31+30+31+31+30+31)
          {m = 9; d = day-(31+30+31+30+31+31+30);} // oct
        else
          {m = 10; d = day-(31+30+31+30+31+31+30+31);} // nov
    else
      if (day < 31+30+31+30+31+31+30+31+30+31)
        {m = 11; d = day-(31+30+31+30+31+31+30+31+30);} // dec
      else {
        if (day < 31+30+31+30+31+31+30+31+30+31+31)
          {m = 0; d = day-(31+30+31+30+31+31+30+31+30+31);} // jan
        else
          {m = 1; d = day-(31+30+31+30+31+31+30+31+30+31+31);} // feb
        ++y;
      }
}

void Time2String(time_t unix_time, char buff[]) {
  const int day = (unix_time / 86400) - ((unix_time < 0) ? 1 : 0);
  int y;
  unsigned int m,d;
  DecomposeDay(day,y,m,d);
  unsigned int s = unix_time - day*86400;
  unsigned int t = s / 60; const unsigned int second = s - t*60;
  s = t / 60; const unsigned int minute = t - s*60;
  sprintf(buff,"%+05d%02u%02u_%02u%02u%02u",
          y,m+1,d+1,s,minute,second);
}

const int pin_plus = 14;
const int pin_minus = 15;

void setup()  {
  lcd.begin(16, 2);
  pinMode(pin_plus,INPUT_PULLUP);
  pinMode(pin_minus,INPUT_PULLUP);
}

unsigned int pressed_plus = 0;
unsigned int pressed_minus = 0;

void loop() {
  time_t t = Teensy3Clock.get();

  unsigned int m = millis();
  int offset = 0;
  if (digitalRead(pin_plus) == LOW) {
    if (pressed_plus == 0) {
      pressed_plus = m;
      offset = 1;
    } else {
      if (m > pressed_plus+1000) {
        // long press
        unsigned int h = (m-pressed_plus)/1000;
        offset = h*h;
      }
    }
  } else {
    pressed_plus = 0;
  }
  if (digitalRead(pin_minus) == LOW) {
    if (pressed_minus == 0) {
      pressed_minus = m;
      offset = -1;
    } else {
      if (m > pressed_minus+1000) {
        // long press
        unsigned int h = (m-pressed_minus)/1000;
        offset = -h*h;
      }
    }
  } else {
    pressed_minus = 0;
  }
  if (offset) {
    t += offset;
    Teensy3Clock.set(t);
  }

  char buff[17];
  Time2String(t,buff);
  
  lcd.setCursor(0, 0);
  lcd.print(buff);
  delay(20);
}
 
For T_4.x the Teensy Loader pushes 'pc' time to RTC on upload.

Perhaps set your PC to GST for uploads?

That time set code is not in the command line uploader yet, AFAIK. If an IDE Verify build was done and the HEX uploaded with the CMDLINE tool it might not change the clock.

TyCommander alternate uploader and SerMon tool had it added as well - in future is was going to have a way to add some control to pushing the PC time - but that isn't done yet AFAIK.
 
Thanks for the prompt reply!
My PC is a linux box and already runs on UTC. I would not mind the few seconds difference between GPST und UTC.
Only on Dos and Windows the hardware clock had been set to local time. And for this sin they payed a high price twice a year at the DST-changes.
So my box has UTC already. gettimeofday() returns the correct amount of seconds and microseconds since 1.1.1970GMT.
I really wonder how and why the current localized time is communicated to the teensy.

"the Teensy Loader pushes 'pc' time to RTC on upload"
So it is some software on the PC? Then it can be modified!
Which program would it be? I have just installed "teensyduino" as described on the website.
Is the source code available?

And I will try the "commandline uploader", thanks for the hint!

Yours,
Johannes
 
Do the Verify and CmdLine tool - it does have source on github.

TeensyLoader works to get DST corrected time - there was an issue with that after first change after release - Paul would know what is done to subvert your UTC setting - that is PJRC closed source - and if it has a way to disable or adjust not exposed yet.
 
Ok, compiled the teensy_loader_cli as described in https://www.pjrc.com/teensy/loader_cli.html
Now I want to compile my sketch into a .hex-file for loading.
I proceeded with https://www.pjrc.com/teensy/gcc.html and installed gcc-avr binutils-avr avr-libc.
Then downloaded the "blinky" Testapp from https://www.pjrc.com/teensy/blinky.zip as described, and with some fiddling ('const' missing) produced blinky.hex - for Teensy version 2.0.
The Makefile is somewhat out of date, the latest version is Teensy 2.0.

I found a promising Makefile at https://github.com/PaulStoffregen/cores/blob/master/teensy4/Makefile,
but this got me into dependency hell. First it did not specify include directories, and after fiddling around with -I/some/path/in/my/filesystem there are missing macro definitions:
blinky.c:43:26: error: 'CLKPR' undeclared
So I think I am making some fundamental mistake.

Is there an approved procedure or a tutorial or instructions how to compile for teensy 4.1 without arduino GUI?
Can you give me some hints?
Thanks in advance!
 
Why not just use the IDE to compile the sketch, then use the command line loader to load the hex file it creates?
 
Why not just use the IDE to compile the sketch, then use the command line loader to load the hex file it creates?

That would be the easy supported way to start.

The latest TeensyDuino 1.54 Beta 7 has, AFAIK, new udev_rules for recent linux changes and also to makefiles for T_4.x support in some fashion. Installing that will provide a usable tested toolchain as supported with Teensy. It should have a CMD_LINE exe in place as well perhaps.

Windows in use here ... and use cmdline to trigger IDE build, and recently someone noted they did that for linux as well. On Windows here, it uses same tool for same build process and resulting HEX - no makefile - but allows running it from chosen Sublime editor, dos box, or dblClick in File Explorer.
 
Run the TimeTeensy3 example from the IDE (File > Examples > Time > TimeTeensy3), then from your linux command line (bash) do
Code:
TZ_adjust=-4;  echo T$(($(date +%s)+60*60*$TZ_adjust)) > /dev/ttyACM0
that will set the RTC and teensy time from your linux box. use TZ_adjust=0; for UTC. If you don't have a battery for your T4 RTC, then you will have to reset the time after loss of power.

With a GPS attached to T4, you could get an accurate time from the GPS.
 
I have just used the teensy_loader_cli for uploading the hex file that I build before in using the arduino-gui. And I confirm: the RTC stays like it is and like it should be! So this is a first success, thanks for pointing out this possibility! But: after compiling the sketch a tiny window pops out - the teensy gui loader. This windows does not stay closed, it must be closed every time after compiling, otherwise it will interfere and change the time. The second downside is: the hex-File is hidden in the /tmp/ directory, in my case it was /tmp/arduino_build_744837/TeensyRawTime.ino.hex.
Can you tell me how to "use cmdline to trigger IDE build"? Then I could work without starting the arduino gui at all.
 
I have just used the teensy_loader_cli for uploading the hex file that I build before in using the arduino-gui. And I confirm: the RTC stays like it is and like it should be! So this is a first success, thanks for pointing out this possibility! But: after compiling the sketch a tiny window pops out - the teensy gui loader. This windows does not stay closed, it must be closed every time after compiling, otherwise it will interfere and change the time. The second downside is: the hex-File is hidden in the /tmp/ directory, in my case it was /tmp/arduino_build_744837/TeensyRawTime.ino.hex.
Can you tell me how to "use cmdline to trigger IDE build"? Then I could work without starting the arduino gui at all.

Code:
[B]In the IDE :: Ctrl + Alt + S :: menu: Sketch / Export compiled Binary[/B]

The Ctrl + K :: open the sketch folder and see the HEX files stored there.

Does a build into the sketch folder, not sure if it triggers opening TeensyLoader. IDE often opens it - and when in AUTO mode it will attempt to program any triggered Teensy. AUTO mode can be switched off and sometimes it sticks? Maybe with Ctrl+Alt+S? Or it can be closed, or get TyCommander and 'Integrate to Arduino' and TeensyLoader is bypassed and TyCommander only does upload when directed to allowing Teensy to sit in BootLoader mode.

If Windows was in use command line builds are well done with :: github.com/Defragster/Tset

As noted some weeks back another linux user noted a BASH script (?) used to build using IDE from command line - not recalling the thread - but forum search for BASH or TSET and it should show up.

To see what is needed do a verbose build in the IDE and capture the builder commands ( like in tset batch files ) and emulate them passing the 'fqbn' { fqbn=teensy:avr:%model%:usb=%usb%,speed=%speed%,opt=%opt%,keys=%keys% } params as passed during the build for Teensy.
 
I know the TimeTeensy3 example: from there I learned about Teensy3Clock.get()/set(). Changing the time back again every time after uploading a new sketch contradicts the purpose of the battery: I have attached a battery so that the RTC keeps the time - even if turned off - and I see no reason why I have to change the time back to what it actually was just before uploading a sketch. Still thanks for the commandline: I did not realize I can open /dev/ttyACM0 while the arduino gui has already opened the same device file.
And yes: with GPS I will be able to set the time automatically - when there is reception. But currently I am working/developing indoors without GPS reception and want to rely on the RTC and battery to keep the time. Which would actually work, if the arduino gui would stop ruining the RTC time every time I upload a new version. So I think teensy_loader_cli will be the way to go.
Just need to find out how to compile without starting the GUI.
 
Well, when I'm using Geany as my IDE (which is pretty much all of the time), when it comes time to compile something for a T4.x, my compile command looks like this:
Code:
board="teensy40";/usr/share/arduino/arduino --verify --board teensy:avr:$board:usb=serial,speed=600,opt=o1std,keys=en-us --port /dev/ttyACM0 --preserve-temp-files --pref build.path=/home/me/tmp %f

This is set up for:

  • Board: Teensy 4.0
  • CPU Speed: 600 MHz
  • USB Type: Serial
  • Optimize: Fast
  • Keyboard Layout: US English
  • Port: /dev/ttyACM0
 
Status
Not open for further replies.
Back
Top