ESP32 NTP: How to Get Date and Time Using NTP [Arduino IDE]

The ESP32 is a powerful microcontroller with built-in Wi-Fi, making it ideal for IoT projects that require accurate timekeeping. Instead of relying on an external Real-Time Clock (RTC) module, the ESP32 can fetch the current date and time from an NTP (Network Time Protocol) server over the internet. This ensures accurate synchronization without requiring any additional hardware.

In this guide, you’ll learn how to use NTP with the ESP32 to get the current date & time and keep it updated automatically.

Table of Contents

    How NTP works

    NTP (Network Time Protocol) is used to synchronize clocks over a network. Your ESP32 will send a request to an NTP server, which responds with the current UTC time. Then, you can convert it into your local time in the code.

    These are the most popular NTP servers:

    • pool.ntp.org
    • time.nist.gov
    • time.google.com

    Setting Up NTP on ESP32

    Prerequisites

    Before we start implementing NTP on the ESP32, make sure you’ve got your ESP32 board, the Arduino IDE set up to work with it, and a Wi-Fi connection for the ESP32 to access NTP servers.

    Step 1: Include Libraries

    To begin with, we’ll use the WiFi.h library for Wi-Fi connectivity and time.h for handling the time.

    #include <WiFi.h>
    #include <time.h>

    Step 2: Define Wi-Fi and NTP values

    Next, we define all the needed values like the Wi-Fi credentials, the NTP server of our choice, etc.

    const char* ssid = "YOUR_SSID";
    const char* password = "YOUR_PASSWORD";
    const char* ntpServer = "pool.ntp.org";
    const long gmtOffset_sec = 3600; // adjust your timezone
    const int daylightOffset_sec = 3600; // adjust for daylight saving time

    The variables gmtOffset_sec and daylightOffset_sec are used to adjust the time retrieved from the NTP server to match your local timezone.

    The gmtOffset_sec is the offset in seconds from the Coordinated Universal Time (UTC) to your local time zone. For example, the offset to the Central European Time (CET) is one hour or 3600 seconds (UTC+1). In this case, your gmtOffset_sec value would be 3600.

    With the daylightOffset_sec variable, we adapt to the Daylight Saving Time (DST), which shifts the clock forward (typically by one hour) during certain months of the year. If your region is in DST, set daylightOffset_sec to 3600. Otherwise, set it to 0.

    If you need help setting the offsets for your time zone, use this time zone converter.

    Step 3: Connect to Wi-Fi

    Before we can proceed with fetching the time, we need to connect our ESP32 to a Wi-Fi network with internet access. We do that in the setup() function of the sketch.

    void setup() {
      Serial.begin(115200); // init serial output
      
      WiFi.begin(ssid, password);
      Serial.print("Connecting to WiFi...");
      while (WiFi.status() != WL_CONNECTED) { // indicate that the ESP32 is trying to connect
        delay(1000);
        Serial.print(".");
      }
      Serial.println("Connected!");

    Step 4: Initialize NTP and Get the Current Time

    Now, we will configure the time settings using the configTime() function and the variables we defined earlier. This ensures that we can get the time in our local timezone with all the correct offsets.

      configTime(gmtOffset_sec, daylightOffset_sec, ntpServer); // configure time settings
      printLocalDateTime();
    }

    configTime() will get the current time from the NTP server we specified and apply all the offsets. When printing the time later on, the ESP32 will keep track with its internal clock so that we don’t always have to request the time from the server again.

    That’s all we need to do in the setup() function. We will define the printLocalDateTime() function in the next step.

    Step 5: Print the current Date & Time

    We use the printLocalDateTime() function to format the date and time correctly and print it to the serial monitor.

    void printLocalDateTime() {
      struct tm timeInfo; // store the current time
      if (!getLocalTime(&timeInfo)) { // get the current time
        Serial.println("Failed to obtain time");
        return;
      }
      Serial.println(&timeInfo, "%A, %B %d %Y %H:%M:%S"); // format the date and time
    }

    Step 6: Upload the Sketch

    Last but not least, we need to run the code on the ESP32. Simply select the right board and COM port in the Arduino IDE and hit the upload button as usual.

    If your sketch fails to upload make sure to hold the boot button and use a USB cable that supports data transmission. For more troubleshooting tips, check out this guide.

    Full Code

    Here’s the complete sketch for you to copy:

    #include <WiFi.h>
    #include <time.h>
    
    const char* ssid = "YOUR_SSID";
    const char* password = "YOUR_PASSWORD";
    const char* ntpServer = "pool.ntp.org";
    const long gmtOffset_sec = 3600; // Central European Time (UTC+1)
    const int daylightOffset_sec = 3600; // DST offset
    
    void printLocalDateTime() {
      struct tm timeInfo; // store the current time
      if (!getLocalTime(&timeInfo)) { // get the current time
        Serial.println("Failed to obtain time");
        return;
      }
      Serial.println(&timeInfo, "%A, %B %d %Y %H:%M:%S"); // format the date and time
    }
    
    void setup() {
      Serial.begin(115200); // init serial output
      
      WiFi.begin(ssid, password);
      Serial.print("Connecting to WiFi...");
      while (WiFi.status() != WL_CONNECTED) { // indicate that the ESP32 is trying to connect
        delay(1000);
        Serial.print(".");
      }
      Serial.println("Connected!");
      
      configTime(gmtOffset_sec, daylightOffset_sec, ntpServer); // configure time settings
      printLocalDateTime();
    }
    
    void loop() {}

    When running the code and looking the serial monitor, you should see the following output:

    Handling Time Updates

    The ESP32 will keep the time synchronized even after losing internet access by using its internal clock. However, you can manually update the time periodically by calling configTime() again.

    To update the time every hour, use a simple timer:

    unsigned long previousMillis = 0;
    const long interval = 3600000; // 1 hour in milliseconds
    
    void loop() {
      unsigned long currentMillis = millis();
      if (currentMillis - previousMillis >= interval) {
        previousMillis = currentMillis;
        printLocalTime();
      }
    }

    Wrapping Up

    Using NTP with the ESP32 is a simple and efficient way to keep time synchronized in your projects. The only thing you need is an internet connection.

    This is useful for many IoT projects that need to have accurate timing. For example, you could water your plants or shut your roller blinds at a very specific time.

    Also, check out how to maintain the time even when the ESP32 is powered off or in deep sleep using an RTC (Real Time Clock) Module.


    Do you have a project that needs accurate timing? Let me know in the comments!

    Thanks for reading, happy coding!

    Links marked with an asterisk (*) are affiliate links which means we may receive a commission for purchases made through these links at no extra cost to you. Read more on our Affiliate Disclosure Page.

    Share this article

    Leave a Reply

    Your email address will not be published. Required fields are marked *