Not another Time Lib for ESP !
Posted: Thu May 07, 2020 4:25 pm
This is NOT another WiFi Time library for the ESP world, adding confusion to the jungle of incompatible libraries!
I really got sick about the high amount of libraries apparently doing (more or less well) the same, jeopardizing each other, being only valid under special conditions and frequently limited to provide a single printed output.
I decided to reconsider the problem and provide only an extensive code example that can be used by everybody to build on their own code. The solution must be fully portable and run on Espressifs ESP32 and ESP8266 based boards without modification. The solution must:
-provide the Posix methods to deal with dates and strings and compute time differences
-provide examples for serial, but also examples for working with text buffers as being used for displays or communication protocols.
-provide the usual variables Second, Minute, Hour, Day, Month, Year as integers, DayName and MonthName as char arrays.
-be able to run a certain time off-line and periodically synchronize with NTP.
-provide the following subroutines:
void getWiFi()
void getNTP()
void getEpoch()
void getTimeData()
The code uses only one was established standard library in the Arduino IDE world: #include <NTPClient.h> // NTP Client by Fabrice Weinberg, Which is part of the library manager, and is extremely stable, running pretty much everywhere.
NTPClient.h provides a sleek WiFi and NTP connection. It provides also basic time resources and the Epoch timestamp, but deliberately did not want to include the overhead of date computations.
Usually, you are invited to use the Arduino TimeLib Library currently maintained by Paul Stoffregen... But as you are compiling for Espressif's systems you will get an unrequested overriding time library from there as well. Unfortunately a different one for ES8266 and ESP32!
So I used NTPClient.h to connect and provide the Epoch, then only use the common part of Espressif's library based on Posix functionality to get the different parts into the variables and the preconfigured strings.
Finally I decided to provide some printed outputs to demonstrate the usage of the different outputs and methods into this looped message using different methods to prepare that message:
Thanks God, it is: Thursday! Date is 07/05/2020 and Time is 23:07:25 Now is 23 Hour, 07 Minutes and 25 Seconds. The Epoch is: 1588892845 Date is Thursday, 07 May 2020 Americans say it is 11:07PM, but Europeans prefer using 23:07:25
Here is the code:
Enjoy!
I really got sick about the high amount of libraries apparently doing (more or less well) the same, jeopardizing each other, being only valid under special conditions and frequently limited to provide a single printed output.
I decided to reconsider the problem and provide only an extensive code example that can be used by everybody to build on their own code. The solution must be fully portable and run on Espressifs ESP32 and ESP8266 based boards without modification. The solution must:
-provide the Posix methods to deal with dates and strings and compute time differences
-provide examples for serial, but also examples for working with text buffers as being used for displays or communication protocols.
-provide the usual variables Second, Minute, Hour, Day, Month, Year as integers, DayName and MonthName as char arrays.
-be able to run a certain time off-line and periodically synchronize with NTP.
-provide the following subroutines:
void getWiFi()
void getNTP()
void getEpoch()
void getTimeData()
The code uses only one was established standard library in the Arduino IDE world: #include <NTPClient.h> // NTP Client by Fabrice Weinberg, Which is part of the library manager, and is extremely stable, running pretty much everywhere.
NTPClient.h provides a sleek WiFi and NTP connection. It provides also basic time resources and the Epoch timestamp, but deliberately did not want to include the overhead of date computations.
Usually, you are invited to use the Arduino TimeLib Library currently maintained by Paul Stoffregen... But as you are compiling for Espressif's systems you will get an unrequested overriding time library from there as well. Unfortunately a different one for ES8266 and ESP32!
So I used NTPClient.h to connect and provide the Epoch, then only use the common part of Espressif's library based on Posix functionality to get the different parts into the variables and the preconfigured strings.
Finally I decided to provide some printed outputs to demonstrate the usage of the different outputs and methods into this looped message using different methods to prepare that message:
Thanks God, it is: Thursday! Date is 07/05/2020 and Time is 23:07:25 Now is 23 Hour, 07 Minutes and 25 Seconds. The Epoch is: 1588892845 Date is Thursday, 07 May 2020 Americans say it is 11:07PM, but Europeans prefer using 23:07:25
Here is the code:
Code: Select all
//**Do not*** #include <TimeLib.h> by Paul Stoffregen, we will mimic it!
#include <NTPClient.h> // NTP Client by Fabrice Weinberg
#if defined(ESP8266)
#include <ESP8266WiFi.h> // default from Espressif
#include <WiFiUdp.h> // default from Espressif
#elif defined(ESP32)
#include <WiFi.h> // default from Espressif
#endif
#define WIFI_SSID "SSID"
#define WIFI_PASS "PASSWORD"
#define HOST_NAME "ESP-IoT"
#define TZ 2 // (utc+) TZ in hours
#define DST_MN 60 // use 60mn for summer time in some countries
#define GMT_OFFSET_SEC 3600 * TZ // Do not change here...
#define DAIYLIGHT_OFFSET_SEC 60 * DST_MN // Do not change here...
#define NTP_SERVER "de.pool.ntp.org"
// Variables for Time
static int lastSecond;
tm* timeinfo; //localtime returns a pointer to a tm structstatic int Second;
time_t Epoch;
static int Second;
static int Minute;
static int Hour;
static int Day;
static int Month;
static int Year;
static int Weekday;
char DayName[12];
char MonthName[12];
char Time[10];
char Date[12];
static IPAddress ip;
//*** Buffers ***
static char charbuff[80]; //Char buffer for many functions
//String text; //String buffer for many functions
// Constructors
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, NTP_SERVER, GMT_OFFSET_SEC);
void getWiFi()
{
WiFi.begin(WIFI_SSID, WIFI_PASS);
while ( WiFi.status() != WL_CONNECTED )
{
delay ( 500 );
Serial.print ( "." );
}
ip = WiFi.localIP();
sprintf(charbuff, "Connected to IP: %03d.%03d.%03d.%03d", ip[0], ip[1], ip[2], ip[3]);
Serial.println(charbuff);
}
void getNTP()
{
timeClient.begin();
timeClient.update();
Serial.print(timeClient.getFormattedTime());
}
void getEpoch()
{
Epoch = timeClient.getEpochTime();
}
void getTimeData()
{
timeinfo = localtime(&Epoch); // cf: https://www.cplusplus.com/reference/ctime/localtime/
Second = timeinfo->tm_sec;
Minute = timeinfo->tm_min;
Hour = timeinfo->tm_hour;
Weekday = timeinfo->tm_wday + 1 ;
Day = timeinfo->tm_mday;
Month = timeinfo->tm_mon + 1;
Year = timeinfo->tm_year + 1900; //returns years since 1900
strftime (DayName , 12, "%A", timeinfo); //cf: https://www.cplusplus.com/reference/ctime/strftime/
strftime (MonthName, 12, "%B", timeinfo);
strftime (Time,10, "%T", timeinfo);
strftime (Date,12, "%d/%m/%Y", timeinfo);
}
void setup()
{
Serial.begin(115200);
getWiFi();
getNTP();
}
void loop()
{
timeClient.update(); // should be called from time to time to refresh NTP when expired, does nothing most of the time.
getEpoch(); // writes the Epoch (Numbers of seconds till 1.1.1970...
getTimeData(); // breaks down the Epoch into discrete values.
// Examples with Strings
Serial.print(F("Thanks God, it is: ")); Serial.print( DayName );
Serial.print(F("! Date is ")); Serial.print( Date );
Serial.print(F(" and Time is ")); Serial.println( Time );
// Examples with a character buffer (can be used for displays as well)
sprintf(charbuff, "Now is %02d Hour, %02d Minutes and %02d Seconds. The Epoch is: %10lu" , Hour , Minute, Second, Epoch);
Serial.println(charbuff);
sprintf(charbuff, "Date is %s, %02d %s %04d ", DayName , Day , MonthName, Year);
Serial.print(charbuff);
Serial.println();
// Examples with Posix expressions
strftime (charbuff, 80, "Americans say it is %I:%M%p, but Europeans prefer using %T", timeinfo);
Serial.println(charbuff);
Serial.println();
Serial.println();
delay(1000);
}
Enjoy!