Arduino: configTime() not working

Created on 20 May 2018  路  6Comments  路  Source: esp8266/Arduino

Hi,

I have some weird issues with configTime. I have two different sketches, both using the same function to initialise the network and do a sync with NTP. Only on one sketch it works fine, time is updated, other sketch the time defaults to 01-01-1970 09:00:00.
Even a recurrent configTime() (every few minutes) doesn't update.
Network connectivity is normal, i can access the ESP, no issues there.

Is there anyway to debug the configTime function?

  • Hardware: [WeMos D1R2]
  • Core Version: [2.4.1]

Here's the abbreviated code parts;

define NTP_SERVERS "0.nl.pool.ntp.org", "1.nl.pool.ntp.org", "2.nl.pool.ntp.org"

define UTC_OFFSET +1

struct dstRule StartRule = {"CEST", Last, Sun, Mar, 2, 3600}; // Central European Summer Time = UTC/GMT +2 hours
struct dstRule EndRule = {"CET", Last, Sun, Oct, 2, 0}; // Central European Time = UTC/GMT +1 hour
simpleDSTadjust dstAdjusted(StartRule, EndRule);

if (WiFi.status() == WL_CONNECTED) {
digitalWrite(LED_BUILTIN, HIGH);
DEBUG_PRINTLN(F(""));
DEBUG_PRINTLN(F("Connected successfully"));
DEBUG_PRINTLN(F(""));
DEBUG_PRINTLN(F("WiFi connected."));
if (!MDNS.begin(V_UNIT_NAME)) {
DEBUG_PRINTLN(F("Error setting up MDNS responder!"));
} else {
DEBUG_PRINT(F("MDNS Service started for http://"));
DEBUG_PRINT(V_UNIT_NAME);
DEBUG_PRINTLN(F(".local"));
}
SetupWebserver();
WebServer.begin();
DEBUG_PRINT(F("IP address: "));
DEBUG_PRINTLN(WiFi.localIP());
DEBUG_PRINT(F("Gateway: "));
DEBUG_PRINTLN(WiFi.gatewayIP());
DEBUG_PRINT(F("Server started on port:"));
DEBUG_PRINTLN(WEB_SERVER_PORT);
configTime(UTC_OFFSET * 3600, 0, NTP_SERVERS);
delay(500);
}

Most helpful comment

I've experienced such "01-01-1970 09:00:00" situations before as well. The workaround was to query time a couple of times

  Serial.println("Syncing time...");
  configTime(0, 0, "pool.ntp.org");  
  setenv("TZ", "CET-1CEST,M3.5.0,M10.5.0/3", 0);
  while(time(nullptr) <= 100000) {
    Serial.print(".");
    delay(100);
  }

All 6 comments

I have two different sketches, both using the same function to initialise the network and do a sync with NTP. Only on one sketch it works fine,

So what makes you think this is a ESP8266/Arduino problem? (a problem with this repository) Nothing you have posted here indicates anything other than that you have a problem.

Here's the abbreviated code parts;

And how is someone supposed to do anything with that? If you are going to post your code then provide a complete simplified sketch. But keep in mind that this is not an I need help forum. See #3 in https://github.com/esp8266/Arduino/blob/master/POLICY.md And that seems to be what your issue is.

The following is a minimal example of a working sketch using configTime()

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <time.h>

const char* ssid = "xxxxx";
const char* password = "";

void setup(void) {
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  Serial.println("");

  configTime(0, 0, "pool.ntp.org");  
  setenv("TZ", "CET-1CEST,M3.5.0,M10.5.0/3", 0);  

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
  Serial.println("Setup done");
}

void loop(void) {
  time_t tnow = time(nullptr);
  Serial.print(String(ctime(&tnow)));
  delay(1000);
}

And its output

....
Connected to mySSID
IP address: 192.168.100.107
Setup done
Mon May 21 18:52:35 2018
Mon May 21 18:52:36 2018
Mon May 21 18:52:37 2018
Mon May 21 18:52:38 2018
Mon May 21 18:52:39 2018
Mon May 21 18:52:40 2018

Most of the time it is a DNS problem. Try directly with the IP of your DNS server. And as RudyFiero says ... it's not a problem with this repository.

Youre absolutely right guys. My (newbie) mistake. Issue closed.

I've experienced such "01-01-1970 09:00:00" situations before as well. The workaround was to query time a couple of times

  Serial.println("Syncing time...");
  configTime(0, 0, "pool.ntp.org");  
  setenv("TZ", "CET-1CEST,M3.5.0,M10.5.0/3", 0);
  while(time(nullptr) <= 100000) {
    Serial.print(".");
    delay(100);
  }

Time is coming from ntp servers some time after the request.
FYI when using lwip2, there is a callback set by settimeofday_cb() called when time is set by NTP.
You can see its use in the NTP-TZ-DST.ino example.

(this example needs rework though, cbtime is quite useless, and .println not wise in a callback)

In case someone else comes here looking for help on time, here's something I created based on a variety of tips and samples elsewhere.... (in this case, Pacific time) - that first checks if the time is already set, then tries to set network time, then resorts to a hard-coded epoch time (could possibly have a web service providing epoch time, too)

// *******************************************************************************************
void setupLocalTime()
// *******************************************************************************************
{
    // see https://github.com/esp8266/Arduino/issues/4637
    time_t now; 
    now = time(nullptr); // if there's no time, this will have a value of 28800; Thu Jan  1 08:00:00 1970 
    Serial.print("Initial time:"); Serial.println(now);
    Serial.println(ctime(&now));

    int myTimezone = -7;
    int dst = 0;
    int SecondsPerHour = 3600;
    int MAX_TIME_RETRY = 60;
    int i = 0;

    // it is unlikely that the time is already set since we have no battery; 
    // if no time is avalable, then try to set time from the network
    if (now <= 1500000000) {
        // try to set network time via ntp packets
        configTime(0, 0, "pool.ntp.org", "time.nist.gov"); // see https://github.com/esp8266/Arduino/issues/4749#issuecomment-390822737

                // Starting in 2007, most of the United States and Canada observe DST from
        // the second Sunday in March to the first Sunday in November.
        // example setting Pacific Time:
        setenv("TZ", "PST8PDT,M3.2.0/02:00:00,M11.1.0/02:00:00", 1); // see https://users.pja.edu.pl/~jms/qnx/help/watcom/clibref/global_data.html
        //                     | month 3, second sunday at 2:00AM
        //                                    | Month 11 - firsst Sunday, at 2:00am  
        // Mm.n.d
        //   The dth day(0 <= d <= 6) of week n of month m of the year(1 <= n <= 5, 1 <= m <= 12, where 
        //     week 5 means "the last d day in month m", which may occur in the fourth or fifth week).
        //     Week 1 is the first week in which the dth day occurs.Day zero is Sunday.

        tzset();
        Serial.print("Waiting for time(nullptr).");
        i = 0;
        while (!time(nullptr)) {
            Serial.print(".");
            delay(1000);
            i++;
            if (i > MAX_TIME_RETRY) {
                Serial.println("Gave up waiting for time(nullptr) to have a valid value.");
                break;
            }
        }
    }
    Serial.println("");

    // wait and determine if we have a valid time from the network. 
    now = time(nullptr);
    i = 0;
    Serial.print("Waiting for network time.");
    while (now <= 1500000000) {
        Serial.print(".");
        delay(1000); // allow a few seconds to connect to network time.
        i++;
        now = time(nullptr);
        if (i > MAX_TIME_RETRY) {
            Serial.println("Gave up waiting for network time(nullptr) to have a valid value.");
            break;
        }
    }
    Serial.println("");

    // get the time from the system
    char *tzvalue;
    tzvalue = getenv("TZ");
    Serial.print("Network time:");  Serial.println(now);
    Serial.println(ctime(&now));
    Serial.print("tzvalue for timezone = "); Serial.println(tzvalue);

    // TODO - implement a web service that returns current epoch time to use when NTP unavailable (insecure SSL due to cert date validation)

    // some networks may not allow ntp protocol (e.g. guest networks) so we may need to fudge the time
    if (now <= 1500000000) {
        Serial.println("Unable to get network time. Setting to fixed value. \n");
        // set to RTC text value
        // see https://www.systutorials.com/docs/linux/man/2-settimeofday/
        //
        //struct timeval {
        //  time_t      tv_sec;     /* seconds */
        //  suseconds_t tv_usec;    /* microseconds */
        //};
        timeval tv = { RTC_TEST, 0 };
        //
        //struct timezone {
        //  int tz_minuteswest;     /* minutes west of Greenwich */
        //  int tz_dsttime;         /* type of DST correction */
        //};
        timezone tz = { myTimezone * 60 , 0 };  

        // int settimeofday(const struct timeval *tv, const struct timezone *tz);
        settimeofday(&tv, &tz);
    }

    now = time(nullptr);
    Serial.println("Final time:");  Serial.println(now);
    Serial.println(ctime(&now));
}

Was this page helpful?
0 / 5 - 0 ratings