Due compatible Time library?

Hi all,
any one know if there is a compatible Time library for Arduino Due?
What i use are:

setTime(hour,min,secs,day,mont,year)
hour()
minute()
second()

I am getting this kind of errors:

/home/deco/progetti/arduino/progetti/Arduino/libraries/Time/Time.h:15: error: conflicting declaration 'typedef long unsigned int time_t'
/home/deco/software/arduino2/arduino-1.5.1/hardware/tools/g++_arm_none_eabi/bin/../lib/gcc/arm-none-eabi/4.4.1/../../../../arm-none-eabi/include/sys/types.h:109: error: 'time_t' has a previous declaration as 'typedef long int time_t'

Code compiled correctly (and still compiles) on older arduino versions.
I think the error is quite easy to fix, but I dint manage to get it in about an hour.
Line numbers are not precise, I dont know why, I think some sort of preprocessor passes before gcc.

Thank you all :slight_smile:

Markus is/was writing one and has posted recently.

http://arduino.cc/forum/index.php/topic,136126.0.html


Rob

Graynomad:
Markus is/was writing one and has posted recently.

http://arduino.cc/forum/index.php/topic,136126.0.html


Rob

Yes I did, if you have any questions, suggestions or if you need an function let me know.

Thank you both (thank you twice Markus!).
I just downloaded the library and as soon as possible I'll compile it.
I'll keep you in touch :slight_smile:

Sorry for the delay, but yesterday I was busy with work till late.
Just compiled with your library, after translating function calls, and it seems to work correctly :smiley:
Thank you very much.
By the way, the interface to the rtc_clock is clean and simple, very nice work.
Even if at the moment I dont use it, also the interface for the alarm:
rtc_clock.set_alarmtime(10, 30, 0);
rtc_clock.attachalarm(announcement);
void announcement(){
...
}
is very clean and I love it.
Thank you again

deco:
Sorry for the delay, but yesterday I was busy with work till late.
Just compiled with your library, after translating function calls, and it seems to work correctly :smiley:
Thank you very much.
By the way, the interface to the rtc_clock is clean and simple, very nice work.
Even if at the moment I dont use it, also the interface for the alarm:
rtc_clock.set_alarmtime(10, 30, 0);
rtc_clock.attachalarm(announcement);
void announcement(){
...
}
is very clean and I love it.
Thank you again

Thanks for the response.

No hurry, lovely that you like it. btw you can set Hours, Minuets and Seconds seperate for the time too, and the function to call the Alarminterrupt takes me the most time.

I recently ported the Time library for Teensy 3.0. This doesn't directly support the Due RTC, but it's meant to work together with the library mentioned above.

Michael Margolis (author of this Time library) and I talked about the time_t compatibility issue. His preference was to rename it to atime_t. Probably "a" for Arduino?

Here's the modified code:

~~http://www.pjrc.com/teensy/beta/Time.zip~~ (edit: do not use this old beta copy)

This is the final, well tested Time library:
http://www.pjrc.com/teensy/td_libs_Time.html

I really should have followed up by updating the playground page.

Can anyone here please test this on Due and then update the playground page? The original code has a TimeAlarms library in the same file, which I haven't used (I did start on it... contact me for the code). It probably needs to be split into a separate download, ported and tested. The page also mentions "time_t", which needs to be edited to "atime_t". I simply ran out of time to update the page.

Yuck! That seems like a dreadful solution.
Please, please don't go down that route. That is such a Windows-fix-of-the-moment type of fix.
That really breaks compatibility especially for those writing code that will use the time type for
things like calculating time intervals.
Why not use the __time_t_defined define to determine whether or not the system has already typed time_t ?
The define could be tested to see if time_t needs to be typed in the library Time.h file.
This seems like a proper fix.

Add this to the Time library Time.h header file:

#ifndef __time_t_defined
typedef unsigned long time_t;
#endif

Then the STUPID IDE also has an issue that rears it ugly head again that breaks this.
The IDE inserts its prologue which includes

#include "Arduino.h"

in the middle of the sketch .cpp file so it ends up after the

#include <Time.h>

So the system version of time_t doesn't get typed before the library Time.h looks at the define.
You have to insert some dummy code to coerce the silly IDE to put the prologue at the top of the .cpp file
I added this to the example sketch:

int dummy = 0;

right at the top of the sketch.

(Can't the IDE be fixed to avoid this silly wrong location prologue insertion????)

One thing that is concerning to me is that since Windows is doesn't handle mixed case
on its file names, #include <Time.h> might end up pulling in the system time.h since it is earlier on the include path
(I don't do Windows so I'm not sure about that).

--- bill

Hello Paul Stoffregen,

I have tested your version of Time and it's remotely to be ported for Due. Actually I already did the time_t variable name change, but that is not the only thing that need to be modified (I did it as bperrybap suggest thought).

#include <machine/types.h>

#ifndef __time_t_defined
//typedef unsigned long time_t;			// original library typedef.
typedef _TIME_T_ time_t;				
#define __time_t_defined
#endif

After that I have been through several compiling errors I would like to bring them here.
First with setTime function, it seems that overloading that function bothers the compiler
previous declaration 'void setTime(atime_t)' here

I decide to remove (comment out) the version with more arguments as you can use the makeTime to have time_t from individual values.
I also have to remove from Time Folder the file DateStrings.cpp.

After all that I make a simple test file like this

#include <Wire.h>  
#include <Time.h>  

void setup()  {
  Wire.begin();
  Serial.begin(9600);
  Serial.println("setup RTC test");

  tmElements_t t;
  t.Second = 0;
  t.Minute = 30;
  t.Hour = 19;
  t.Wday = 3;
  t.Day = 16;
  t.Month = 1;
  t.Year = y2kYearToTm(13);
  Serial.println("setup makeTime");
  makeTime(t);
//  setTime(makeTime(t));
  Serial.println("how come  ");

  
}
void loop()
{
   digitalClockDisplay();  
   delay(1000);
}



void digitalClockDisplay(){
  // digital clock display of the time
  time_t t = now();
  Serial.print(hour(t));
  printDigits(minute(t));
  printDigits(second(t));
  Serial.print(" ");
  Serial.print(day(t));
  Serial.print(" ");
  Serial.print(month(t));
  Serial.print(" ");
  Serial.print(year(t)); 
  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);
}

the good thing is that it compiles but the bad is that a warning appears

test_time.cpp.o: In function setup':* *C:\...\arduino-1.5.1r2/test_time.ino:24: warning: undefined reference to makeTime(tmElements_t&)'
Binary sketch size: 25,856 bytes (of a 524,288 byte maximum)

I recently discover that if you put the Time.h include at the beginning of the import section it produces the above error and the Due hangs before it can print "how come".

If you put any other import before Time.h it compiles cleanly and run without problems.

Maybe it have to do with

Then the STUPID IDE also has an issue that rears it ugly head again that breaks this.
The IDE inserts its prologue which includes
Code:
#include "Arduino.h"
in the middle of the sketch .cpp file so it ends up after the
Code:
#include <Time.h>
So the system version of time_t doesn't get typed before the library Time.h looks at the define.
You have to insert some dummy code to coerce the silly IDE to put the prologue at the top of the .cpp file
I added this to the example sketch:
Code:
int dummy = 0;
right at the top of the sketch.

I found another issue, in file Time.h the line

typedef time_t(*getExternalTime)();

should be

typedef time_t(*getExternalTime)(void);

Best,

Hello, I'm trying to compile this libs on Arduino due for use an external TinyRTC

#include <Wire.h>
#include <Time.h> // lib with updates from this post
#include <DS1307RTC.h> //lib from http://www.pjrc.com/teensy/td_libs_DS1307RTC.html

void setup() {
  // put your setup code here, to run once:
}
void loop() {
  // put your main code here, to run repeatedly:
}

and I have this errors =(:

In file included from sketch_apr09a.ino:6:
D:\\\Arduino\libraries\DS1307RTC/DS1307RTC.h:45: error: expected ')' before '*' token
D:\\\Arduino\libraries\DS1307RTC/DS1307RTC.h:45: error: expected ')' before '*' token

any idea :disappointed_relieved: I've run this code on Arduino MEGA and I have no error

Could you try using both Time and DS1307RTC from the PJRC site? Maybe you've got an older version?

If that doesn't work, could you also try those 2 with Arduino 1.5.2? Maybe something has changed since they were tested on 1.5.2?

Enrique_SL:
Hello, I'm trying to compile this libs on Arduino due for use an external TinyRTC

#include <Wire.h>

#include <Time.h> // lib with updates from this post
#include <DS1307RTC.h> //lib from DS1307RTC Library, For Accessing Real Time Clock (RTC) Chips

void setup() {
  // put your setup code here, to run once:
}
void loop() {
  // put your main code here, to run repeatedly:
}





and I have this errors =(:




In file included from sketch_apr09a.ino:6:
D:\\Arduino\libraries\DS1307RTC/DS1307RTC.h:45: error: expected ')' before '' token
D:\\Arduino\libraries\DS1307RTC/DS1307RTC.h:45: error: expected ')' before '
' token




any idea :disappointed_relieved: I've run this code on Arduino MEGA and I have no error
[/quote]

DS1307RTC.h


#ifndef DS1307RTC_h
#define DS1307RTC_h
#include <Time.h>
class DS1307RTC
{
public:
 
DS1307RTC();
static time_t get(void);    
static bool set(time_t t);    
static bool read(tmElements_t &tm);  
static bool write(tmElements_t &tm);  
static bool chipPresent(void) {return exists;}

private:

static bool exists;
static uint8_t dec2bcd(uint8_t num);  
static uint8_t bcd2dec(uint8_t num);
};
extern DS1307RTC RTC;
#endif




DS1307RTC.cpp



#include <Wire.h>
#include "DS1307RTC.h"

#define DS1307_CTRL_ID 0x68
DS1307RTC::DS1307RTC()
{
 Wire.begin();
}

// PUBLIC FUNCTIONS
time_t DS1307RTC::get()   // Aquire data from buffer and convert to time_t
{
 tmElements_t tm;
 if (read(tm) == false) return 0;
 return(makeTime(tm));
}
bool DS1307RTC::set(time_t t)
{
 tmElements_t tm;
 breakTime(t, tm);
 tm.Second |= 0x80;  // stop the clock
 write(tm);
 tm.Second &= 0x7f;  // start the clock
 write(tm);
}
// Aquire data from the RTC chip in BCD format
bool DS1307RTC::read(tmElements_t &tm)
{
 uint8_t sec;
 Wire.beginTransmission(DS1307_CTRL_ID);
#if ARDUINO >= 100  
 Wire.write((uint8_t)0x00);
#else
 Wire.send(0x00);
#endif  
 if (Wire.endTransmission() != 0) {
   exists = false;
   return false;
 }
 exists = true;
 // request the 7 data fields   (secs, min, hr, dow, date, mth, yr)
 Wire.requestFrom(DS1307_CTRL_ID, tmNbrFields);
 if (Wire.available() < tmNbrFields) return false;
#if ARDUINO >= 100
 sec = Wire.read();
 tm.Second = bcd2dec(sec & 0x7f);  
 tm.Minute = bcd2dec(Wire.read() );
 tm.Hour =   bcd2dec(Wire.read() & 0x3f);  // mask assumes 24hr clock
 tm.Wday = bcd2dec(Wire.read() );
 tm.Day = bcd2dec(Wire.read() );
 tm.Month = bcd2dec(Wire.read() );
 tm.Year = y2kYearToTm((bcd2dec(Wire.read())));
#else
 sec = Wire.receive();
 tm.Second = bcd2dec(sec & 0x7f);  
 tm.Minute = bcd2dec(Wire.receive() );
 tm.Hour =   bcd2dec(Wire.receive() & 0x3f);  // mask assumes 24hr clock
 tm.Wday = bcd2dec(Wire.receive() );
 tm.Day = bcd2dec(Wire.receive() );
 tm.Month = bcd2dec(Wire.receive() );
 tm.Year = y2kYearToTm((bcd2dec(Wire.receive())));
#endif
 if (sec & 0x80) return false; // clock is halted
 return true;
}
bool DS1307RTC::write(tmElements_t &tm)
{
 Wire.beginTransmission(DS1307_CTRL_ID);
#if ARDUINO >= 100  
 Wire.write((uint8_t)0x00); // reset register pointer  
 Wire.write(dec2bcd(tm.Second)) ;  
 Wire.write(dec2bcd(tm.Minute));
 Wire.write(dec2bcd(tm.Hour));      // sets 24 hour format
 Wire.write(dec2bcd(tm.Wday));  
 Wire.write(dec2bcd(tm.Day));
 Wire.write(dec2bcd(tm.Month));
 Wire.write(dec2bcd(tmYearToY2k(tm.Year)));
#else  
 Wire.send(0x00); // reset register pointer  
 Wire.send(dec2bcd(tm.Second)) ;  
 Wire.send(dec2bcd(tm.Minute));
 Wire.send(dec2bcd(tm.Hour));      // sets 24 hour format
 Wire.send(dec2bcd(tm.Wday));  
 Wire.send(dec2bcd(tm.Day));
 Wire.send(dec2bcd(tm.Month));
 Wire.send(dec2bcd(tmYearToY2k(tm.Year)));  
#endif
 if (Wire.endTransmission() != 0) {
   exists = false;
   return false;
 }
 exists = true;
 return true;
}
// PRIVATE FUNCTIONS
// Convert Decimal to Binary Coded Decimal (BCD)
uint8_t DS1307RTC::dec2bcd(uint8_t num)
{
 return ((num/10 * 16) + (num % 10));
}

// Convert Binary Coded Decimal (BCD) to Decimal
uint8_t DS1307RTC::bcd2dec(uint8_t num)
{
 return ((num/16 * 10) + (num % 16));
}
bool DS1307RTC::exists = false;
DS1307RTC RTC = DS1307RTC(); // create an instance for the user

Did you try either of my 2 suggestions?

II have the Arduino IDE 1.5.5 with support for Arduino Due, I just download the IDE 1.5.2 to try, later I'll post the results. thanks for your suggestions

Try the Time library from this page

http://www.pjrc.com/teensy/td_libs_Time.html

The beta copy from reply #6 is old. Do not use it. I have removed it from my server, so that link should no longer work.

:slight_smile: I've tried with your suggestions but I haven't any change with the errors :frowning:

Paul,
The problem is a name collision.
RTC is the DS1307RTC global object name used by the library but is also #define down in:
{IDEinstallDir}/hardware/arduino/sam/system/CMSIS/Device/ATMEL/sam3s/include/sam3s2a.h
And the define breaks everything.

Bummer....
lots of "ugly" global #define names in that header file.

Not sure how to fix this properly without renaming the DS1307RTC library object.
Although as a temporary kludge/fix you can edit DS1307RTC.h and insert this line:

#undef RTC

Just after

#define DS1307RTC_h

It should be noted that this kludge is not guaranteed to work.
For example, since Wire.h includes the header file above
if Wire.h is included after DS1307RTC.h then this kludge will not work
because sam3s2a.h will simply redefine it.
The examples in DS1307RTC library include <Wire.h> after DS1307RTC.h so
those examples will still break with this kludge inserted.
However, if you change the examples to include <Wire.h> before DS1307RTC.h
the examples will compile.

Like I said this is a temporary kludge and I'm not really sure how to fix
it properly without renaming the library's global RTC object.

--- bill

From the little I've seen of libraries and the core code they are full of non-unique defines like RTC, that's way too generic. What if I rant to use it for Rob's Timer Counter :slight_smile:

I think all libs should use a prefix to their definitions where the prefix is essentially the name of the lib or an appropriate abbreviation.


Rob

Hi, I've tried with bperrybap's solution and the error of D:\\Arduino\libraries\DS1307RTC/DS1307RTC.h:45: error: expected ')' before '*' token disappears.

So I've opened an example of DS130RTC lib.

#include <Time.h>
#include <DS1307RTC.h>
#include <Wire.h>

void setup() {
  Serial.begin(9600);
  while (!Serial) ; // wait for serial
  delay(200);
  Serial.println("DS1307RTC Read Test");
  Serial.println("-------------------");
}

void loop() {
  tmElements_t tm;

  if (RTC.read(tm)) {
    Serial.print("Ok, Time = ");
    print2digits(tm.Hour);
    Serial.write(':');
    print2digits(tm.Minute);
    Serial.write(':');
    print2digits(tm.Second);
    Serial.print(", Date (D/M/Y) = ");
    Serial.print(tm.Day);
    Serial.write('/');
    Serial.print(tm.Month);
    Serial.write('/');
    Serial.print(tmYearToCalendar(tm.Year));
    Serial.println();
  } else {
    if (RTC.chipPresent()) {
      Serial.println("The DS1307 is stopped.  Please run the SetTime");
      Serial.println("example to initialize the time and begin running.");
      Serial.println();
    } else {
      Serial.println("DS1307 read error!  Please check the circuitry.");
      Serial.println();
    }
    delay(9000);
  }
  delay(1000);
}

void print2digits(int number) {
  if (number >= 0 && number < 10) {
    Serial.write('0');
  }
  Serial.print(number);
}

and a new error appears

Arduino: 1.5.5-r2 (Windows 7), Placa:"Arduino Due (Programming Port)"

ReadTest.ino: In function 'void loop()':
ReadTest:18: error: request for member 'read' in '1074666080u', which is of non-class type 'Rtc*'
ReadTest:33: error: request for member 'chipPresent' in '1074666080u', which is of non-class type 'Rtc*'

Read the rest of my previous post.
--- bill