I am trying to set my RTC from GPS if the network is not available. The GPS shows the right time, but the technique I try to use to set LocalTime is not working. Is there a procedure for setting localTime from GPS?
The code below is the relevant portion of a program that compiles to 997640 bytes on an ESP32 LilyGo T-Beam. I can send the whole thing if you ask.
I believe the failure comes at // it works up to this point //////////:
void initTime(String timezone) // stable
{
if (WiFi.status() == WL_CONNECTED)
{
Serial.println("initTime getting NTP time: ");
while (!getLocalTime(&timeinfo) && counter < 10)
{
configTime(0, 0, ntpServer); // connect to NTP server, with 0 TZ offset
counter++;
Serial.print("NTPv "); Serial.print(counter); Serial.print(F(" "));
}
Serial.println();
if (getLocalTime(&timeinfo))
{
setTimezone(timezone);
Serial.print("LocalTime: ");
printLocalTime();
}
}
else if (!getLocalTime(&timeinfo))
{
Serial.println("NTPv: readParseGPS"); Serial.println();
readParseGPS();
}
}
void readParseGPS()
{
if (GPSSerial.available())
{
while (GPSSerial.available() > 0)
gps.encode(GPSSerial.read());
}
if (gps.date.isUpdated())
{
Serial.print(F("GPS Year="));
Serial.print(gps.date.year()); Serial.print(F(" "));
Serial.print(F("GPS Month="));
Serial.print(gps.date.month()); Serial.print(F(" "));
Serial.print(F("GPS Day="));
Serial.println(gps.date.day());
}
if (gps.time.isUpdated())
{
Serial.print(F("Hour="));
Serial.print(gps.time.hour()); Serial.print(F(" "));
Serial.print(F("Minute="));
Serial.print(gps.time.minute()); Serial.print(F(" "));
Serial.print(F("Second="));
Serial.println(gps.time.second());
// it works up to this point //////////
timeinfo.tm_sec = gps.time.second();
timeinfo.tm_min = gps.time.minute();
timeinfo.tm_hour = gps.time.hour();
timeinfo.tm_mday = gps.date.day();
timeinfo.tm_mon = gps.date.month();
timeinfo.tm_year = gps.date.year();
// this works, but with bad info /////
setTimezone(timezone);
printLocalTime();
Serial.println("Set RTC to GPS");
setRTC();
}
void setTimezone(String timezone) // stable
{
Serial.printf("Setting Timezone to %s\n", timezone.c_str());
setenv("TZ", timezone.c_str(), 1); // adjust the TZ. Clock settings are adjusted to show the new local time
tzset();
return;
}
void setRTC()
{
Serial.print("setRTC(); ");
getLocalTime(&timeinfo);
rtc.adjust(DateTime(timeinfo.tm_year + 1900, timeinfo.tm_mon + 1, timeinfo.tm_mday,
timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec));
DateTime now = rtc.now();
Serial.print( "RTC set to: ");
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();
}
// RTC initialization
if (!rtc.begin())
{
Serial.println("RTCv");
Serial.println();
}
else if (rtc.begin())
{
Serial.println("rtc.begin");
rtc.disable32K(); // disable the 32K Pin
pinMode(RTC_INT_PIN, INPUT); // attach an interrupt to the alarm
attachInterrupt(digitalPinToInterrupt(RTC_INT_PIN), setRemotetime, FALLING);
rtc.clearAlarm(1); // reset alarm 1, 2 flag on reboot & recompile
rtc.clearAlarm(2);
rtc.disableAlarm(2); // turn off alarm 2 at reboot
rtc.writeSqwPinMode(DS3231_OFF); // stop signals at SQW Pin
rtc.setAlarm1(DateTime(0, 0, 0, 0, 1, 0), DS3231_A1_Hour);
Serial.println("Alarm(1) set to trigger at midnight");
Serial.println();
}