My latest ESP32/Nextion touch screen Weather/bus/train times project required a realtime clock.... however it has taken me quite a few weeks to find a good solid solution.
Firstly :-
....if you want to stay sane then avoid epoch time (best thing that happened in 1970's was "punk Rock" not unix count my seconds since birth)....rant over.
If your web enabled mcu project requires a neat way to sync things to a clock then here is the easiest way I have found .
Many if not all API web calls have a handshake header message before the real data is exchanged.
I am extracting weather data from the openweathermap.com project.
Its relatively easy to get the weather_data however it a bit more tricky to obtain some coherent date and time from it.
Code below is for an ESP32 :- |
#include <WiFi.h>
#include <HTTPClient.h>
const char* ssid = "Gareth"; //Router name
const char* password = "Slatybartfast"; //Router Password
const String PollTimeAPI = "http://api.openweathermap.org/data/2.5/weather?lat=-77.66&lon=168.22&units=metric&APPID="; // simple web call to extract weatherdata , however can double up to extract header data as well
const char * headerKeys[] = {"date"};//The data key you require from the HTTP Header
const size_t numberOfHeaders = 1; //The number of keys in your array above
int pollApiTime;
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) { delay(200); Serial.print(">"); }
Serial.print("Connected to "); Serial.println(ssid);
}
void loop() {
if (millis()-pollApiTime >=10000) {PrintDateTime(); pollApiTime=millis(); }
}
void PrintDateTime()
{
if ((WiFi.status() == WL_CONNECTED)) { //Check the current connection status
HTTPClient http;
http.begin(PollTimeAPI); //Specify the URL
http.collectHeaders(headerKeys, numberOfHeaders); // here is how to access certain data fields in the HTTP responce header
int httpCode = http.GET(); //Make the request
if (httpCode > 0) { //Check for the returning status code :-)
String headerDate = http.header("date"); //extract the date and time field
Serial.println(headerDate);
http.end(); } //free up the request
}
}
|
I am polling the data every 10 seconds here for demo, though in reality I would only need to sync the time maybe once/day.
As far as I can gather the HTTP specifications for the Date & GMT (yes GMT or nothing) Time layout is quite strict, which makes it easy to split the data up.
Ow .. I started reading on
Ow .. I started reading on unix time - epoch time - leap seconds ... and now have a headache ..
Cool project Gareth ! Now you can get to the bus on time (or maybe 25 seconds late ;)
real time
I can see the advantages of epoch time... however came to the conclusion it needed just the same amount of decoding to present it in a user readable format as a simple http heading read and decode.
The sync time polling will update a local clock with the esp32 timers ,so will at least nullify and timer slippage.
Your getting critical (should
Your getting critical (should I wear a coat info) from the openweather api ...
but I believe almost all http servers will return gmt time in the header response.
And this one doesn't require a key, it also comes with your public gateway address...
Great... looks like same format too
I had a funny feeling in my bones that that would be the case... great that you can confirm.
It is also gratifying to see that the date complies also to the specifications for HTTP headers.
Would be interesting to ping>>> a cross section of sites to see what gems are stored in the header response.