I have working code that set DS3231 using GPS time with unixtime. Looking to use Timezone library and do not know how to go about accomplishing the task. Do I have to use Time.h and Timelib.h? Do I need to change RTClib.h (Adafruit) library Will I still be able to use unixtime?
These are the two functions that are the time keeping functions:
YEAR = now.year();
MONTH = now.month();
DATE = now.day();
DOW = now.dayOfTheWeek();
HOUR = now.hour();
MINUTE = now.minute();
SECOND = now.second();
By convention, all capital letter names are reserved for constants. Constants do NOT appear on the left of an equal sign after they are declared and initialized.
Looking to use Timezone library and do not know how to go about accomplishing the task.
What IS the task? You are getting date and time information from the GPS, in UTC time. You can use the timezone library to convert that date/time to local time, and use the local time to set the RTC.
You can get "unix time" from the Adafruit rtclib like this example. Of course, it makes some assumptions that the RTC has been properly set before hand.
DateTime now = rtc.now();
Serial.print( now.unixtime() ) ; // uint32_t
The time_t data type which you will see is a lot of is a uint32_t number representing unix time
Thank you 6v6gt appreciate your response and advise; yes that is the library.
What would the command be to set the DS3231 by passing parameter "unixtime." I was able to do this with the RTClib library. Is it possible to do this with "Time.h" or "Timelib.h" eliminating the RTClib?
If you have a physical DS3231 then you really need to use the matching RTC library. The alternative is to use the basic wire/I2C commands to poke/read the correct values into/from the RTC registers.
The time library (TimeLib.h) has setTime() and now() for handling unix time, that is a uint32_t representation of seconds since 1.1.1970.
void getDate_Time()
{
time_t utc = now();
time_t local = myTZ.toLocal(utc, &tcr);
time_t t = now(); // store the current time in time variable t
HOUR = hour(t); // returns the hour for the given time t
MINUTE = minute(t); // returns the minute for the given time t
SECOND = second(t); // returns the second for the given time t
DATE = day(t); // the day for the given time t
DOW = weekday(t); // day of the week for the given time t
MONTH = month(t); // the month for the given time t
YEAR = year(t); // the year for the given time t
printDateTime(local, tcr -> abbrev);
}
// format and print a time_t value, with a time zone appended.
void printDateTime(time_t t, const char *tz)
{
char buf[32];
char m[4]; // temporary storage for month string (DateStrings.cpp uses shared buffer)
strcpy(m, monthShortStr(month(t)));
sprintf(buf, "%.2d:%.2d:%.2d %s %.2d %s %d %s",
hour(t), minute(t), second(t), dayShortStr(weekday(t)), day(t), m, year(t), tz);
dtStamp = buf;
}
void RTC_UPDATE()
{
struct tm timeinfo;
unsigned long int unixtime;
if((!gps.date.isValid()) || (!gps.time.isValid()))
{
getDate_Time();
Serial.println(dtStamp);
return;
}
Serial.print(F("GPS: "));
if (gps.date.isValid())
{
timeinfo.tm_year = gps.date.year() - 1900;
timeinfo.tm_mon = gps.date.month() - 1;
timeinfo.tm_mday = gps.date.day();
}
else
{
Serial.print(F("Date INVALID"));
exit;
}
Serial.print(F(" "));
if (gps.time.isValid())
{
timeinfo.tm_hour = gps.time.hour();
timeinfo.tm_min = gps.time.minute();
timeinfo.tm_sec = gps.time.second();
unixtime = mktime(&timeinfo);
Serial.println("");
printf("unixtime = %u\n", unixtime);
setTime(unixtime); // the function to get the time from the RTC
if(timeStatus()!= timeSet)
Serial.println("Unable to sync with the RTC");
else
Serial.println("RTC has set the system time");;
Serial.println("RTC updated");
Serial.println("");
}
else
{
Serial.print(F(" Time INVALID"));
exit;
}
Serial.println();
Attached project Serial Monitor output; which shows two GPS time (unixtime) updates with interval set to 15 minutes. Interval is easily set; can be seconds, minutes, or hours.
Event that is coded to happen at 23:58:00 local time is being called at local time 20:58:00 EDT. Believe this is due to 20:00:00 EDT is 24:00:00 in UTC.
What is needed to get the fileStore event to occur at 23:58:00 EDT?
When I use print statement for HOUR is fine unit HOUR = 20; then it goes to HOUR = 0 and the 23:58:0 is called. I believe the DS3231 is using unixtime. I am using JChristensen's Timezone library with he DS3232 library. fileStore only appears in two places; once in loop and and once in void fileStore().
void loop()
{
...
if((HOUR == 23) && (MINUTE == 58) && (SECOND == 0)) //localOffset needed since RTC uses UTC Time.
{
fileStore();
Serial.println("fileStore called");
Serial.println(dtStamp);
}
...
}
/* Time keeping functions */
void getDate_Time()
{
time_t utc = now();
time_t local = myTZ.toLocal(utc, &tcr);
time_t t = now(); // store the current time in time variable t
HOUR = hour(t); // returns the hour for the given time t
MINUTE = minute(t); // returns the minute for the given time t
SECOND = second(t); // returns the second for the given time t
DATE = day(t); // the day for the given time t
DOW = weekday(t); // day of the week for the given time t
MONTH = month(t); // the month for the given time t
YEAR = year(t); // the year for the given time t
printDateTime(local, tcr -> abbrev);
}
// format and print a time_t value, with a time zone appended.
void printDateTime(time_t t, const char *tz)
{
char buf[32];
char m[4]; // temporary storage for month string (DateStrings.cpp uses shared buffer)
strcpy(m, monthShortStr(month(t)));
sprintf(buf, "%.2d:%.2d:%.2d %s %.2d %s %d %s",
hour(t), minute(t), second(t), dayShortStr(weekday(t)), day(t), m, year(t), tz);
dtStamp = buf;
}
void RTC_UPDATE()
{
struct tm timeinfo;
unsigned long int unixtime;
if((!gps.date.isValid()) || (!gps.time.isValid()))
{
getDate_Time();
Serial.println(dtStamp);
return;
}
Serial.print(F("GPS: "));
if (gps.date.isValid())
{
timeinfo.tm_year = gps.date.year() - 1900;
timeinfo.tm_mon = gps.date.month() - 1;
timeinfo.tm_mday = gps.date.day();
}
else
{
Serial.print(F("Date INVALID"));
exit;
}
Serial.print(F(" "));
if (gps.time.isValid())
{
timeinfo.tm_hour = gps.time.hour();
timeinfo.tm_min = gps.time.minute();
timeinfo.tm_sec = gps.time.second();
unixtime = mktime(&timeinfo);
Serial.println("");
printf("unixtime = %u\n", unixtime);
setTime(unixtime); // the function to get the time from the RTC
if(timeStatus()!= timeSet)
Serial.println("Unable to sync with the RTC");
else
Serial.println("RTC has set the system time");;
Serial.println("RTC updated");
Serial.println("");
}
else
{
Serial.print(F(" Time INVALID"));
exit;
}
Serial.println();
}
/* fileStore function */
void fileStore() //If 6th day of week, rename "log.txt" to ("log" + month + day + ".txt") and create new, empty "log.txt"
{
String logname;
logname = "/LOG";
logname += DATE; ////logname += Clock.getMonth(Century);
logname += MONTH; ///logname += Clock.getDate();
logname += YEAR;
logname += ".TXT";
// Open file for appended writing
File log = SPIFFS.open(logname.c_str(), "a");
if (!log)
{
Serial.println("file open failed");
}
}
Prefer to use DS3231 for the HOUR value; since there could be invalid GPS.time causing a logging failure.
Here you are hard coding times in your local timezone:
if((HOUR == 23) && (MINUTE == 58) && (SECOND == 0)) //localOffset needed since RTC uses UTC Time.
I'm not sure this is doing what you expect:
time_t utc = now();
time_t local = myTZ.toLocal(utc, &tcr);
time_t t = now(); // store the current time in time variable t
HOUR = hour(t); // returns the hour for the given time t
now() is the Arduino "System Time" and has to have been set previously with setTime( time_t myUnixTime )
if you want HOUR to be in local time, you have to say HOUR = hour( local )
You have to post your entire sketch if you need more help.
It is a big sketch, but I think I see what you are doing.
You appear to want to use GPS time to set the RTC periodically in unix time UTC. However, it is not clear to me if that is what you are actually doing.
This code from void RTC_UPDATE() has misleading comments in it and the indentation in the if/then/else statement does not match the block structure:
setTime(unixtime); // the function to get the time from the RTC
// setTime(unixtime) does not set the RTC, it sets the Arduino "System Time"
if(timeStatus()!= timeSet)
Serial.println("Unable to sync with the RTC");
else
Serial.println("RTC has set the system time");;
Serial.println("RTC updated");
Serial.println("");
You use the RTC to set Arduino "System Time" ) and that is also in unix time UTC. So, for example, now() returns UTC.
setSyncProvider(RTC.get);
Which, by default, runs every 5 minutes
So, it is as I said before. If you want this to work in local time, ie 23:58 EDT
if((HOUR == 23) && (MINUTE == 58) && (SECOND == 0)) //localOffset needed since RTC uses UTC Time.
you have to change this:
void getDate_Time()
{
time_t utc = now();
time_t local = myTZ.toLocal(utc, &tcr);
//Serial.println();
//printDateTime(utc, "UTC");
// time_t t = now(); // store the current time in time variable t - now() returns UTC in this case !!
HOUR = hour(local); // returns the hour for the given time
MINUTE = minute(local); // returns the minute for the given time
SECOND = second(local); // returns the second for the given time
DATE = day(local); // the day for the given time
DOW = weekday(local); // day of the week for the given time
MONTH = month(local); // the month for the given time
YEAR = year(local); // the year for the given time
printDateTime(local, tcr -> abbrev);
}
Incidentally, you could break your code down to into smaller .h and .cpp units (separate tabs in the Arduino IDE).
Thank you 6v6gt; you are excellent at presenting what needs to be done; much appreciated. I am still learning and developing style. Yes, I am familiar with"tabbed compiling;" I find in the initial stages of a project, it is easier for me to search the entire project. My editor of choice is "Notepad++;" I find this search tool is easier to use than the "Arduino IDE" search tool.
Once I have finished coding project I will use "ASytle" to present a well formatted source code. My apologies for the confusing comments. Thanks for your input.
I have no experience writing .cpp or .h library files; perhaps sometime in the future. This project had its beginnings in the Fall of 2012 when I was given an "Arduino Uno;" project has evolved to the present project code I am completely self-learned in "Arduino C++" programming and continue learning at 70 years old!