Thanks for this valuable suggestion! Finally got this to working! Upon further observation it was seen that although the RTCLib example code does not explicitly indicate a leading zero in the date format, it does lead to arbitrary values when the date is set. So, I added a rudimentary way to add leading zeros. I'm sure it could be done more craftily, but this works too. To check if the RTC has lost time, the following code is already in the example sketch:
if (rtc.lostPower())
or the following if there's an RTC failure:
if (! rtc.begin())
Here's the working sketch:
#include <TimeLib.h>
#include <SoftwareSerial.h>
#include <Arduino.h>
#include <TinyGPS++.h>
#include "RTClib.h"
RTC_DS3231 rtc;
char daysOfTheWeek[7][12] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
bool syncOnce = true;
const char TIMESTRING;
SoftwareSerial SerialGPS = SoftwareSerial(4, 3);
TinyGPSPlus tinyGPS;
const int offset = 19800; // hours (in seconds)
time_t prevDisplay = 0;
void setup() {
Serial.begin(9600);
while (!Serial)
;
SerialGPS.begin(9600);
rtc.begin();
}
void loop() {
while (SerialGPS.available())
tinyGPS.encode(SerialGPS.read()); // Send it to the encode function
// tinyGPS.encode(char) continues to "load" the tinGPS object with new
// data coming in from the GPS module. As full NMEA strings begin to come in
// the tinyGPS library will be able to start parsing them for pertinent info
int Year = tinyGPS.date.year();
int Month = tinyGPS.date.month();
int Day = tinyGPS.date.day();
int Hour = tinyGPS.time.hour();
int Minute = tinyGPS.time.minute();
int Second = tinyGPS.time.second();
setTime(Hour, Minute, Second, Day, Month, Year);
adjustTime(offset);
if (timeStatus() != timeNotSet) {
if (now() != prevDisplay) { //update the display only if the time has changed
prevDisplay = now();
//GPSprintformat();
if (tinyGPS.time.isValid()) {
sync();
}
rtcPrint();
}
}
}
void GPSprintformat() {
char buf[40];
sprintf(buf, "%4d,%2d,%2d %2d,%2d,%2d", year(), month(), day(), hour(), minute(), second());
Serial.println(buf);
}
void rtcPrint() {
DateTime now = rtc.now();
Serial.print(now.year(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.print(now.day(), DEC);
Serial.print(' ');
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
Serial.println();
}
void sync() {
if (syncOnce) {
String Months, Days, Hours, Minutes, Seconds;
if (month() < 10) {
Months = ("0" + String(month()));
} else Months = String(month());
if (day() < 10) {
Days = ("0" + String(day()));
} else Days = String(day());
if (hour() < 10) {
Hours = ("0" + String(hour()));
} else Hours = String(hour());
if (minute() < 10) {
Minutes = ("0" + String(minute()));
} else Minutes = String(minute());
if (second() < 10) {
Seconds = ("0" + String(second()));
} else Seconds = String(second());
String TIMES = String(year()) + "," + String(Months) + "," + String(Days) + "," + String(Hours) + "," + String(Minutes) + "," + String(Seconds);
const char *TIMESTRING = TIMES.c_str();
Serial.println(TIMESTRING);
rtc.adjust(DateTime(TIMESTRING));
syncOnce = false;
}
}
Edit:
As suggested by jRemington,
the sync process can be done with more arduino friendly sprintf function (again 0 padding is important at least for RTCLib.
char timeBuffer[40];
sprintf(timeBuffer, "%4d,%02d,%02d %02d,%02d,%02d", year(), month(), day(), hour(), minute(), second());
Serial.println(timeBuffer);
rtc.adjust(DateTime(timeBuffer));