Every once in a while you’ll come across an idea where keeping time a prime concern. For example, imagine a relay that has to be activated at a certain time or a data logger that has to store values at precise intervals.

The first thing that comes in your mind is to use an RTC (Real Time Clock) chip. But these chips are not perfectly accurate so, you need to do manual adjustments over and over again to keep them synchronized.

The solution here is to use Network Time Protocol (NTP). If your ESP8266 project has access to the Internet, you can get date and time (with a precision within a few milliseconds of UTC) for FREE. You don’t need any additional hardware.

What is an NTP?

An NTP stands for Network Time Protocol. It’s a standard Internet Protocol (IP) for synchronizing the computer clocks to some reference over a network.

The protocol can be used to synchronize all networked devices to Coordinated Universal Time (UTC) within a few milliseconds ( 50 milliseconds over the public Internet and under 5 milliseconds in a LAN environment).

Coordinated Universal Time (UTC) is a world-wide time standard, closely related to GMT (Greenwich Mean Time). UTC does not vary, it is the same world wide.

NTP sets the clocks of computers to UTC, any local time zone offset or day light saving time offset is applied by the client. In this manner clients can synchronize to servers regardless of location and time zone differences.

NTP Architecture

NTP uses a hierarchical architecture. Each level in the hierarchy is known as a stratum.

At the very top are high-precision timekeeping devices, such as atomic clocks, GPS or radio clocks, known as stratum 0 hardware clocks.

Stratum 1 servers have a direct connection to a stratum 0 hardware clock and therefore have the most accurate time.

NTP Hierarchical Architecture With Stratums

Each stratum in the hierarchy synchronizes to the stratum above and act as servers for lower stratum computers.

How NTP Works?

NTP can operate in a number of ways. The most common configuration is to operate in client-server mode. The basic working principle is as follows:

  1. The client device such as ESP8266 connects to the server using the User Datagram Protocol (UDP) on port 123.
  2. A client then transmits a request packet to a NTP server.
  3. In response to this request the NTP server sends a time stamp packet.
  4. A time stamp packet contains multiple information like UNIX timestamp, accuracy, delay or timezone.
  5. A client can then parse out current date & time values.

NTP Server Working - Request And Timestamp Packet Transfer

Preparing the Arduino IDE

Enough of the theory, Let’s Go Practical!

But before venturing further into this tutorial, you should have the ESP8266 add-on installed in your Arduino IDE. Follow below tutorial to prepare your Arduino IDE to work with the ESP8266, if you haven’t already.

Tutorial of Programming ESP32 in Arduino IDE

Insight Into ESP8266 NodeMCU Features & Using It With Arduino IDE

The Internet of Things (IoT) has been a trending field in the world of technology. It has changed the way we work. Physical objects...

Installing NTP Client Library

The easiest way to get date and time from an NTP server is using an NTP Client from arduino libraries. Follow the next steps to install this library in your Arduino IDE.

Navigate to the Sketch > Include Library > Manage Libraries…Wait for Library Manager to download libraries index and update list of installed libraries.

Filter your search by typing ‘ntpclient’. There should be a couple entries. Look for NTPClient by Fabrice Weinberg. Click on that entry, and then select Install.

Installing NTP Client Library In Arduino IDE

Getting Current Day and Time from NTP Server

The following sketch will give you complete understanding on how to get current day and time from the NTP Server.

Before you head for uploading the sketch, you need to make some changes to make it work for you.

  • You need to modify the following two variables with your network credentials, so that ESP8266 can establish a connection with existing network.
    const char* ssid       = "YOUR_SSID";
    const char* password   = "YOUR_PASS";
  • You need to adjust the UTC offset for your timezone in milliseconds. Refer the list of UTC time offsets.  Here are some examples for different timezones:
    • For UTC -5.00 : -5 * 60 * 60 : -18000
    • For UTC +1.00 : 1 * 60 * 60 : 3600
    • For UTC +0.00 : 0 * 60 * 60 : 0
    const long utcOffsetInSeconds = 3600;

Once you are done, go ahead and try the sketch out.

#include <NTPClient.h>
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>

const char *ssid     = "YOUR_SSID";
const char *password = "YOUR_PASS";

const long utcOffsetInSeconds = 3600;

char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

// Define NTP Client to get time
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", utcOffsetInSeconds);

void setup(){
  Serial.begin(115200);

  WiFi.begin(ssid, password);

  while ( WiFi.status() != WL_CONNECTED ) {
    delay ( 500 );
    Serial.print ( "." );
  }

  timeClient.begin();
}

void loop() {
  timeClient.update();

  Serial.print(daysOfTheWeek[timeClient.getDay()]);
  Serial.print(", ");
  Serial.print(timeClient.getHours());
  Serial.print(":");
  Serial.print(timeClient.getMinutes());
  Serial.print(":");
  Serial.println(timeClient.getSeconds());
  //Serial.println(timeClient.getFormattedTime());

  delay(1000);
}

After uploading the sketch, press the RST button on your NodeMCU, and you should get the current day and time every second as shown below.

ESP32 Reads Date & Time From NTP Server Output On Serial monitor

Code Explanation

Let’s take a quick look at the code to see how it works. First, we include the libraries needed for this project.

  • NTPClient.h is time library which does graceful NTP server synchronization.
  • ESP8266WiFi.h library provides ESP8266 specific WiFi methods we are calling to connect to network.
  • WiFiUdp.h library handles UDP protocol like opening a UDP port, sending and receiving UDP packets etc.
#include <NTPClient.h>
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>

Next, we set up a few constants like SSID, WiFi password & UTC Offset that you are already aware of. We also define daysOfTheWeek 2D array.

Now, before initializing NTP Client object, we need to specify the address of the NTP Server we wish to use. pool.ntp.org is an open NTP project great for things like this.

WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", utcOffsetInSeconds);

The pool.ntp.org automatically picks time servers which are geographically close for you. But if you want to choose explicitly, use one of the sub-zones of pool.ntp.org.

Sub-zones of pool.ntp.org
Area HostName
Worldwide pool.ntp.org
Asia asia.pool.ntp.org
Europe europe.pool.ntp.org
North America north-america.pool.ntp.org
Oceania oceania.pool.ntp.org
South America south-america.pool.ntp.org

In setup section, we first initialize serial communication with PC and join the WiFi network using WiFi.begin() function.

Serial.begin(115200);

WiFi.begin(ssid, password);

while ( WiFi.status() != WL_CONNECTED ) {
  delay ( 500 );
  Serial.print ( "." );
}

Once ESP8266 is connected to the network, we initialize the NTP client using begin() function.

timeClient.begin();

Now we can simply call the update() function whenever we want current day & time. This function transmits a request packet to a NTP server using UDP protocol and parse the received time stamp packet into to a readable format.

timeClient.update();

You can access the day & time information by accessing the NTP Client library functions.

Serial.print(daysOfTheWeek[timeClient.getDay()]);
Serial.print(", ");
Serial.print(timeClient.getHours());
Serial.print(":");
Serial.print(timeClient.getMinutes());
Serial.print(":");
Serial.println(timeClient.getSeconds());