Every now and then, you’ll come across an idea where keeping time is a top priority. For example, consider a relay that must be activated at a specific time or a data logger that must store values at precise intervals.
The first thing that comes to mind is to use an RTC (Real Time Clock) chip. However, because these chips are not perfectly accurate, you must perform manual adjustments on a regular basis to keep them synchronized.
Instead, it is preferable to employ the Network Time Protocol (NTP). If your ESP8266 project has Internet access, you can obtain date and time (with a precision of a few milliseconds of UTC) for FREE. Also, you don’t need any additional hardware.
What is an NTP?
NTP is an abbreviation for Network Time Protocol. It is a standard Internet Protocol (IP) for synchronizing computer clocks over a network.
This protocol synchronizes 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 global time standard that is similar to GMT (Greenwich Mean Time). UTC does not change; it is the same all over the world.
The idea here is to use NTP to set the computer clocks to UTC and then apply any local time zone offset or daylight saving time offset. This allows us to synchronize our computer clocks regardless of location or time zone differences.
NTP Architecture
NTP employs 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 provide the most accurate time.
Each stratum in the hierarchy synchronizes with the stratum above and acts as a server for computers in lower stratums.
How NTP Works?
NTP can operate in a number of ways. The most common configuration is to operate in client-server mode.
The fundamental operating principle is as follows:
- The client device, such as the ESP8266, connects to the NTP server via the User Datagram Protocol (UDP) on port 123.
- The client then sends a request packet to the NTP server.
- In response to this request, the NTP server sends a time stamp packet. A time stamp packet contains a variety of data, such as a UNIX timestamp, accuracy, delay, or timezone.
- A client can then extract the current date and time from it.
Preparing the Arduino IDE
You should have the ESP8266 add-on installed in your Arduino IDE before proceeding with this tutorial. If you haven’t installed it yet, follow the tutorial below.
Installing the NTP Client Library
The NTP Client Library simplifies the process of retrieving time and date from an NTP server. Follow the steps below to install this library in your Arduino IDE.
Navigate to Sketch > Include Library > Manage Libraries… Wait for the Library Manager to download the libraries index and update the list of installed libraries.
Filter your search by entering ‘ntpclient’. Look for NTPClient by Fabrice Weinberg. Click on that entry and then choose Install.
Getting Date and Time from NTP Server
The sketch below will show you exactly how to get the date and time from the NTP Server.
#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);
}
Before you start uploading the sketch, you’ll need to make a few changes to make sure it’ll work for you.
- Modify the following two variables with your network credentials so that the ESP8266 can connect to an existing network.
const char* ssid = "YOUR_SSID"; const char* password = "YOUR_PASS";
- Adjust the UTC offset for your timezone (in seconds). Refer to the list of UTC time offsets. Here are some examples for various time zones:
- 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;
After uploading the sketch, press the RST button on your NodeMCU. The serial monitor should display the date and time every second.
Code Explanation
Let’s take a quick look at the code to see how it works. To begin, we include the libraries required for this project.
- NTPClient.h is a time library that handles NTP server synchronization gracefully.
- ESP8266WiFi.h is a library containing the ESP8266-specific WiFi methods we will use to connect to a network.
- WiFiUdp.h library handles UDP protocol tasks such as opening a UDP port, sending and receiving UDP packets, and so on.
#include <NTPClient.h>
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
A few constants are defined, such as the SSID, WiFi password, and UTC offset. daysOfTheWeek
2D array is also defined.
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"};
In addition, the address of the NTP Server is specified. pool.ntp.org is a great open NTP project for this kind of thing.
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", utcOffsetInSeconds);
pool.ntp.org automatically selects time servers that are physically close to you. However, if you want to select a specific server, use one of the pool.ntp.org sub-zones.
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 the setup section, we first establish serial communication with the PC and then connect to the WiFi network by calling the WiFi.begin()
function.
Serial.begin(115200);
WiFi.begin(ssid, password);
while ( WiFi.status() != WL_CONNECTED ) {
delay ( 500 );
Serial.print ( "." );
}
Once the ESP8266 is connected to the network, we use the begin()
function to initialize the NTP client.
timeClient.begin();
Now we simply call the update()
function to obtain the current date and time. This function sends a request packet to an NTP server and parses the received time stamp packet into a readable format.
timeClient.update();
You can retrieve the current date and time by calling the NTP Client object’s methods.
Serial.print(daysOfTheWeek[timeClient.getDay()]);
Serial.print(", ");
Serial.print(timeClient.getHours());
Serial.print(":");
Serial.print(timeClient.getMinutes());
Serial.print(":");
Serial.println(timeClient.getSeconds());