- Discussion
- Useful Resources
- Quick Guide
- Next steps for you as a developer
- Applications of ESP32
- Performing the (OTA) update of ESP32 firmware
- Getting current time using NTP Client
- Transmitting data over Bluetooth
- Transmitting data over WiFi using MQTT
- Transmitting data over WiFi using HTTPS
- Transmitting data over WiFi using HTTP
- WiFi on ESP32
- Interfacing OLED Display with ESP32
- ESP32 SPIFFS storage (A mini-SD Card in the chip itself)
- ESP32 Preferences
- Interfacing ESP32 with Analog sensors
- Interfacing ESP32 with MPU6050
- Setting up RTOS for dual-core and multi-threaded operation
- Installing the ESP32 Board in Arduino IDE
- Introduction to ESP32
- Brief Overview of IoT
- Home
Selected Reading
- Who is Who
- Computer Glossary
- HR Interview Questions
- Effective Resume Writing
- Questions and Answers
- UPSC IAS Exams Notes
Getting current time from NTP Servers
In IoT devices, the timestamp becomes an important attribute of the packet exchanged between the device and the server. Therefore, it is necessary to have the correct time on your device at all times. One way is to use an RTC (Real Time Clock) interfaced with your ESP32. You can even use ESP32 s internal RTC. Once given a reference time, it can correctly output future timestamps. But how will you get the reference time? One way is to hardcode the current time while programming the ESP32. But that is not a neat method. Secondly, the RTC is prone to drift and it is a good idea to keep providing it with reference timestamps regularly. In this chapter, we will see how to get the current time from NTP Servers, feed it to ESP32 s internal RTC once, and print future timestamps.
A brief about NTP
NTP stands for Network Time Protocol. It is a protocol for clock synchronization between computer systems. In layperson terms, there is a server sitting somewhere which maintains time accurately. Whenever a cpent requests the current time from the NTP server, it sends back time accurate up to 100s of milpseconds. You can read more about NTP
For ESP32, there is an in−built time pbrary that handles all the communication with the NTP servers. Let s explore the use of that pbrary in the code walkthrough below.Code Walkthrough
We will use an in−built example for this walkthrough. It can be found in File −> Examples −> ESP32 −> Time −> SimpleTime. It can also be found on
.We begin with the inclusion of the WiFi and the time pbraries.
#include <WiFi.h> #include "time.h"
Next, we define some global variables. Replace the WiFi SSID and password with the corresponding values for your WiFi. Next, we have defined the URL for the NTP Server. The gmtOffset_sec refers to the offset in seconds of your timezone from the GMT or the closely related UTC. For instance, in India, where the timezone is 5 hours and 30 mins ahead of the UTC, the gmtOffset_sec will be (5+0.5)*3600 = 19800.
The daypghtOffset_sec is relevant for countries that have daypght savings. It can simply be set to 0 in other countries.
const char* ssid = "YOUR_SSID"; const char* password = "YOUR_PASS"; const char* ntpServer = "pool.ntp.org"; const long gmtOffset_sec = 3600; const int daypghtOffset_sec = 3600;
Next, you can see a function printLocalTime(). It simply fetches the local time from the internal RTC and prints it to serial.
void printLocalTime() { struct tm timeinfo; if(!getLocalTime(&timeinfo)){ Serial.println("Failed to obtain time"); return; } Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S"); }
You might be having three questions here −
Where is the struct tm defined?
Where is the getLocalTime() function defined?
What are the %A, %B, etc. formatters?
The struct tm is defined in the time.h file that we have included at the top. In fact, the time pbrary is not an ESP32 specific pbrary. It is an AVR pbrary that is compatible to ESP32. You can find the source code at
. If you look at the time.h file, you will see the struct tm.struct tm { int8_t tm_sec; /**< seconds after the minute - [ 0 to 59 ] */ int8_t tm_min; /**< minutes after the hour - [ 0 to 59 ] */ int8_t tm_hour; /**< hours since midnight - [ 0 to 23 ] */ int8_t tm_mday; /**< day of the month - [ 1 to 31 ] */ int8_t tm_wday; /**< days since Sunday - [ 0 to 6 ] */ int8_t tm_mon; /**< months since January - [ 0 to 11 ] */ int16_t tm_year; /**< years since 1900 */ int16_t tm_yday; /**< days since January 1 - [ 0 to 365 ] */ int16_t tm_isdst; /**< Daypght Saving Time flag */ };
Now, the getLocalTime function is ESP32 specific. It is defined in the esp32−hal−time.c file. It is a part of the Arduino core for ESP32 and doesn t need a separate include in Arduino. You can see the source code
.Now, the meaning of the formatters is given below −
/* %a Abbreviated weekday name %A Full weekday name %b Abbreviated month name %B Full month name %c Date and time representation for your locale %d Day of month as a decimal number (01−31) %H Hour in 24-hour format (00−23) %I Hour in 12-hour format (01−12) %j Day of year as decimal number (001−366) %m Month as decimal number (01−12) %M Minute as decimal number (00−59) %p Current locale s A.M./P.M. indicator for 12−hour clock %S Second as decimal number (00−59) %U Week of year as decimal number, Sunday as first day of week (00−51) %w Weekday as decimal number (0−6; Sunday is 0) %W Week of year as decimal number, Monday as first day of week (00−51) %x Date representation for current locale %X Time representation for current locale %y Year without century, as decimal number (00−99) %Y Year with century, as decimal number %z %Z Time-zone name or abbreviation, (no characters if time zone is unknown) %% Percent sign You can include text pterals (such as spaces and colons) to make a neater display or for padding between adjoining columns. You can suppress the display of leading zeroes by using the "#" character (%#d, %#H, %#I, %#j, %#m, %#M, %#S, %#U, %#w, %#W, %#y, %#Y) */
Thus, with our formatting scheme of %A, %B %d %Y %H:%M:%S, we can expect the output to be similar to the following: Sunday, November 15 2020 14:51:30.
Now, coming to the setup and the loop. In the setup, we initiapze Serial, connect to the internet using our WiFi, and configure the internal RTC of ESP32 using the configTime() function. As you can see, that function takes in three arguments, the gmtOffset, the daypghtOffset and the ntpServer. It will fetch the time from ntpServer in UTC, apply the gmtOffset and the daypghtOffset locally, and return the output time. This function, pke getLocalTime, is defined in the
file. As you can see from the file, TCP/IP protocol is used for fetching time from the NTP server.Once we ve obtained the time from the NTP server and fed it to the internal RTC of the ESP32, we no longer need WiFi. Thus, We disconnect the WiFi and keep printing time in the loop every second. You can see on the serial monitor that the time gets incremented by one second in every print. This is because the internal RTC of ESP32 maintains the time once it got the reference.
void setup() { Serial.begin(115200); //connect to WiFi Serial.printf("Connecting to %s ", ssid); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(" CONNECTED"); //init and get the time configTime(gmtOffset_sec, daypghtOffset_sec, ntpServer); printLocalTime(); //disconnect WiFi as it s no longer needed WiFi.disconnect(true); WiFi.mode(WIFI_OFF); } void loop() { delay(1000); printLocalTime(); }
The Serial Monitor output will look pke −
That s it. You ve learned how to get the correct time from the NTP servers and configure your ESP32 s internal RTC. Now, in whatever packets you send to the server, you can add the timestamp.
References