Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 5 of 5

Thread: ms timestamp since 2020.

  1. #1
    Member
    Join Date
    Jun 2018
    Location
    Northeast USA
    Posts
    62

    ms timestamp since 2020.

    Hello All,
    Been futzing with making a millisecond resolution timestamp for data logging. Thought a good approach would be a millisecond timer since Jan 1, 2020, a sort of 'covid epoch', but in milliseconds. This is running on a Teensy 4.0, but in the step where I multiply times 1000 (to make mS from seconds) it acts like the upper bits are wrapping around & I'm getting unexpected numbers in the bottom 3 decimal places (where I want to put the milliseconds).

    Thoughts? Better way to do it? I'd really like to end up with a single 32 bit number which is mS from Jan 2020.

    Thank You,
    John
    Code:
    /* This is supposed to generate a sort of 'timestamp since Covid in milli seconds',
     *  starting at Jan 1 2020, and getting rid of the bits you save by subtracting the 
     *  time from Jan 1970 to Jan 2020.  Then that number is supposed to be multiplied * 1000
     *  to become the time in mS, then add to that the number of milliseconds in the Teensy ms timer.
     */
     
    #include <TimeLib.h>
    void setup() {
      Serial.begin(115200);
      while (!Serial);                // Wait till user opens serial monitor
      Serial.println("setup done, good to print to user.");   
    }
    
    // Ref: the date Jan 1, 2020 0h:0m:0s is 1577836800 seconds from epoch Jan 1 1970.
    // So from the Jan 1970 epoch start, 50 years, or 1577836800 seconds have elapsed.
    
    void loop() {
      long epochTime = 0;
      time_t tt = Teensy3Clock.get();
      epochTime = tt;  
      Serial.print("epoch = ");                 Serial.print(epochTime); 
      Serial.print("     epoch - 50yrs = ");    Serial.print(epochTime - 1577836800 ); 
      Serial.print("     epoch-50yr*1000 = "); Serial.print((epochTime - 1577836800 ) * 1000); 
    
      int millis_now = millis() % 1000; // only care about the millis < 1000 
    
      Serial.print("      with mS added = ");   Serial.println(((epochTime - 1577836800 ) * 1000) + millis_now ); 
    
      delay(200);
    }

  2. #2
    Member
    Join Date
    Oct 2019
    Location
    Calgary
    Posts
    77
    I feel like I'm missing something obvious, but after a quick glance I got this:

    86400 seconds in a day.
    That's 86400000 mSecs in a day.
    unsigned long is 32 bits, with a maximum value of 4294967295.
    4294967295/86400000 ~= 49.7 days. That's the maximum length of time you can count mSecs in an unsigned long before the value wraps. A signed long would only last half as long.

    Wouldn't you have to do this with a 'unsigned long long' type and start with the full 64 bits from the RTC and divide that by 32.768 to get mSec?

  3. #3
    Member
    Join Date
    Jun 2018
    Location
    Northeast USA
    Posts
    62
    I also feel like I'm missing something obvious, and you may be on to it. The apparent wrap around issue. But even if that is the issue, I would think the 3 LSbits in the epochTime variable after the multiplication would be 000.

    Thank You, John

  4. #4
    Senior Member
    Join Date
    Jul 2020
    Posts
    174
    If you change that to an unsigned long long and run that program again, what is the output?

    If that doesn't fix it, try sprintf() instead of letting Serial.print() figure it out.

  5. #5
    Senior Member PaulS's Avatar
    Join Date
    Apr 2015
    Location
    Netherlands
    Posts
    298
    Pilot is right, Serial.print() does not always work well with big numbers.
    Here is a piece of code that shows you how to use sprintf():
    Code:
    // see https://arduinobasics.blogspot.com/2019/05/sprintf-function.html
    // see http://www.cplusplus.com/reference/cstdio/sprintf/
    
    void setup() {
      Serial.begin(115200);
      while (!Serial);
      Serial.println("Serial output started...");
    }
    
    void loop() {
      char buffer[30];
      unsigned long long number1 = 12345678901234;
      unsigned long long number2 = number1 * 1000;
      
      sprintf(buffer, "number2 = %llu", number2);
      Serial.println(buffer);
    
      delay(1000);
    }
    Paul

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •