upgrad 1.0.3 to 1.0.5 resulted in issues with atime_t

Status
Not open for further replies.

gbathree

Active member
I recently setup the Arduino IDE v 1.0.5 along with the newest version of Teensyduino downloaded from PJRC in Ubuntu 12.04. My program (in fact, many versions of the program) which had compiled just fine (also in Ubuntu 12.04) before now gives me the following error:

Code:
Combined:78: error: 'atime_t' does not name a type
Combined.ino: In function 'void setup()':
Combined:177: error: invalid conversion from 'long unsigned int (*)()' to 'getExternalTime {aka long int (*)()}' [-fpermissive]
In file included from Combined.ino:47:0:
/home/photosynq/Desktop/arduino-1.0.5/libraries/Time/Time.h:134:9: error:   initializing argument 1 of 'void setSyncProvider(getExternalTime)' [-fpermissive]
Combined:195: error: 'atime_t' was not declared in this scope
Combined:195: error: expected ';' before 't'
Combined:197: error: 't' was not declared in this scope
Combined.ino: At global scope:
Combined:1486: error: 'atime_t' does not name a type

I'm using the following libraries.

#include <SdFat.h>
#include <SdFatUtil.h> // use functions to print strings from flash memory
#include <Time.h> // enable real time clock library
#include <Wire.h>
#include <DS1307RTC.h> // a basic DS1307 library that returns time as a atime_t
#include <PITimer.h>

It seems to be an issue with the Time.h and/or DS1307RTC library (which define atime_t), because I can run previous versions which used the SdFat and SdFatUtil without any problems. Time and DS1307 libraries come packaged with Teensy, and I've used those though I have also tried downloading new ones just in case. I've checked all the files in the Libraries folder and they look file, with the *.h file in the top of the directory (so it's definitely visible when Arduino searches for it).

Also, I know I need to switch from PITimer to IntervalTimer (it's on the list), but I don't think this error is due to that.

I ran TimeTeensy3 and TimeRTC examples and they worked fine, along with other standard examples (blink, etc.)

Here's the snippet of code (which I believe was originally from a time example I found somewhere):

Code:
/*  code to process time sync messages from the serial port   */
#define TIME_MSG_LEN  11   // time sync to PC is HEADER followed by unix atime_t as ten ascii digits
#define TIME_HEADER  'T'   // Header tag for serial time sync message

atime_t processSyncMessage() {
  // return the time if a valid sync message is received on the serial port.
  while(Serial.available() >=  TIME_MSG_LEN ){  // time message consists of a header and ten ascii digits
    char c = Serial.read() ; 
    Serial.print(c);  
    if(c == TIME_HEADER ) {       
      atime_t pctime = 0;
      for(int i=0; i < TIME_MSG_LEN -1; i++){   
        c = Serial.read();          
        if( c >= '0' && c <= '9'){   
          pctime = (10 * pctime) + (c - '0') ; // convert digits to a number    
        }
      }   
      return pctime;
     Serial.println("this is pc time");
     Serial.println(pctime);
    }  
  }
  return 0;
  i=0; // reset i
}

Any ideas or similar problems?

Thanks,

Greg
 
TL;DR: You need to change every "atime_t" to "time_t". Or you can use "unsigned long" or "uint32_t" and cast to time_t where necessary.

I'm really sorry about this incompatible change. I really don't like it when code breaks, and in this case things weren't handled very gracefully.

Here's a little history. Shortly after Teensy3 shipped, several people wanted to use the RTC. I had the raw code, but it needed to integrate with the Arduino Time library. Unfortunately, the Time library definition of time_t conflicted with the newlib C library. It would probably conflict with nearly any POSIX-like C library. The AVR libc isn't even close to POSIX or other standards. It doesn't define time_t at all, so the Time library never had this issue with normal AVR-based Arduino or Teensy boards.

I contacted Michael Margolis, the author of the Time library (and the Arduino Cookbook and several other books). After a few messages back and forth about different ways to address the issue, Michael decided he wanted to keep all the code the same, but change the name in the library. Using "atime_t" was supposed to mean "Arduino Time" or something? I quickly hacked up a copy of the library with time_t changes to atime_t and published it with a version of Teensyduino supporting the RTC.

Months later, I revisited the Time library. Arduino Due suffered the same trouble as Teensy3 using the 32 bit newlib C library (except nobody was actually working on supporting Due). Other people joined the conversation on the Arduino Forums. One thing became clear very quickly. Everybody hated the "atime_t" idea. Honestly, I never liked it either. Someone made a great suggestion regarding a preprocessor macro, which I did not know about previously.

I started working on the Time library again. It turned out much of the code (especially example stuff) was very old and did not work anymore. When began as a "quick" solution to just get Time working on Teensy3 turned into a week-long project to greatly updated the Time library. Most of the examples were rewritten. Michael and I exchanged many messages and he rewrote the Processing example and some of the other Serial interface example code. Finally, a really good updated to the Time library was ready. Michael was happy to call it a release, and other people who had objected strongly seemed happy.

So the bad news is for about 4 months Teensyduino shipped a modified copy of Time with "atime_t", which has now changed back to "time_t". I'm not so happy about incompatible changes, but then again "atime_t" was incompatible with other code also. I really wanted to work together with Michael and not fork the code or make API changes.

So as a result of all this, you'll need to change "atime_t" to "time_t". I'm sorry we went down this path and then ultimately changed course back to "time_t". In the long run (or at least until 2038 or 2106), I believe cooperating with Michael Margolis and others in the Arduino community is the best way, even though it sometimes leads to changing course, especially when I push things out earlier than is done for other 32 bit Arduino compatible boards.
 
Thanks for the explanation - it actually really helps to understand the history!

It's ok - fix wasn't too bad. I switched all atime_t to time_t, but I also had to do change

setSyncProvider(Teensy3Clock.get);

to

setSyncProvider((getExternalTime) Teensy3Clock.get);

(see code at bottom for example in context). I think it's because Teensy3Clock.get was pulling the wrong variable type, so it needed to be specified. That seemed to fix it!

Also, just a quick note (probably worth a different thread, but I'll throw it in here) - I switched my code over from PITimer to IntervalTimer. I didn't realize that IntervalTimer was now integrated in the Teensy core library, so when I added the library to the "libraries" folder, it threw errors because it was finding 2 versions of everything. So I got rid of IntervalTimer in the "libraries" folder completely and things seem to compile ok now. But why did he get rid of functions like .zero and .counter? It seems odd that he'd remove those functions in upgrading from PITimer to IntervalTimer.

Thanks again for the help!

Code:
  // SET SYSTEM TIME IN ASCII "T" PLUS 10 DIGITS
  setSyncProvider((getExternalTime) Teensy3Clock.get);
  //  while (!Serial);  // Wait for Arduino Serial Monitor to open
  if(timeStatus()!= timeSet) 
    Serial.println("Unable to sync with the RTC");
  else
    Serial.println("RTC has set the system time"); // NOTE! Chris enter experiment start time stamp here

  //  for (i=0;i<15;i++) { 
  Serial.println("Please type in T followed by 10 digit ASCII time (eg 'T1231231231')");
  Serial.println("(if you make a mistake, restart teensy and reenter)");
  //  Serial.println(Serial.available());
  while (Serial.available()<11) {
    // c = Serial.read();
    //  Serial.print(Serial.available());
    //  Serial.print(",");
    //  Serial.println(Serial.peek());
    //  delay(500);
  }
  time_t t = processSyncMessage();
  Serial.print("'T' plus ASCII 10 digit time: ");
  Serial.println(t);
  Serial.print("Serial buffer size: ");
  Serial.println(Serial.available());
  setTime(t);          
  Serial.print("UTC time: ");
  SerialPrintClock();  
  //  delay(3000);
  //  digitalClockDisplay();
  //  }
  Serial.println("");
 
Status
Not open for further replies.
Back
Top