Set LocalTime from GPS

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();
  }

Possibly of interest: the Arduino Time library includes GPS as a source for setting the time.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.