How to get current time using esp8266

Hi,

I just implemented a system, like it switched ON/OFF motor based on the time using arduino uno + ESP8266 with MQTT. I'm struggling to get current time using ESP8266. please anyone can help me. Please suggest some code regarding this issue.

I'm struggling to get current time using ESP8266

Get it from where?

Try this esp8266-Arduino/Time.ino at master · scanlime/esp8266-Arduino · GitHub

Sorry for bumping an old thread but it's applicable and I'm hoping it will deliver a solution for a project I'm working on. For that matter, there was no follow-up to Dave's suggestion so I'll be trying this out when I get back home.

I'm working on a solar garden light which measures soil moisture level and reports the measurement after being converted to a percentage to a small web interface. My initial testing went very well but I found that the ESP8266 draws quite a bit more power than I had anticipated and thus drained the batteries during the night to beyond the usable low limit and shut off. I need this to be able to operate around the clock as I'm going to be building 8 or 10 of these to be placed around a front and back yard to collect a good dataset. The plan is to collect enough data to determine water efficiency and best times / intervals to water. When you water during the day, you may get as little as 50% efficiency, but watering in the middle of the night, you can end up with fungus and moss accumulation and this is less than desirable weather you're watering your lawn / garden or some larger agricultural plot.

Anyway, as a counterpart to the web interface, the board will also be controlling an RGB spotlight both to illuminate it's subject at night, but also to indicate weather the soil is wet or dry by periodically blinking the spotlight in a specific color. This is not required when it's light out, so the board will need to know if it is light or dark out. The typical solution to this would be to use a sensor, measure the voltage at the PV or add a real time clock to the build. The issue is that these solutions require analog input and the ESP8266 boards I am using only have one analog input which is being used for the soil moisture sensor. Plus, the board will already have internet access so why not just get time from the internet. To that end, I'm looking for the simplest solution, getting the job done in as few lines of code as possible.

I'll be testing out the linked example when I get back home in the morning, and if successful will add it to my other code. I just need to be able to turn off the light during the day and possibly have the ESP8266 bump into a light sleep mode for about an hour at a time to give the batteries a rest. I'll make sure to link this thread to future me as a reminder to come report back with an update. I'll also share some more inclusive code in case anybody else is working on the same type of thing.

After I get this working, I want to add an RGB color picker to the web interface, just because.

You could maybe use a photodiode or phototransistor on a digital pin to determine day/night.

This shows how to get NTP time on ESP8266 and this shows how to get sunrise/sunset times for a given location.

Riva:
You could maybe use a photodiode or phototransistor on a digital pin to determine day/night.

This shows how to get NTP time on ESP8266 and this shows how to get sunrise/sunset times for a given location.

Now there’s an idea. Because I really only need to know if it’s light or dark, not specifically the intensity of light, though I wonder if the nearby street light at the corner of my yard would throw things off a bit. Perhaps if I had this pointing more to the south, similarly to the angle I like to set the PV at. This would have it pointing away from the light source.

I’m still working on this time situation though, and I’ve just about got it worked out. The code example that was linked by Dave seems to work, but I only had a few minutes after work this morning to combine it with my other code and upload it to the board to see what the output was. Well, it got the day of the week right, but also thought it was January first, 1970 and the hour was also off. Safe to say there’s a lot here that I haven’t fully come to understand yet, but I’ll keep working at it until I get the desired output. I’m also considering scrapping the ESP8266 micro-controller for an Arduino nano with an ESP01 attached. While this will probably dictate more code that has to be introduced, adding an additional layer of communication between the board and the wireless adapter, I’m wondering if it will operate more efficiently. My guess is probably not, but I will have more analog inputs at my disposal.

Back to the “Time.ino” sourced by Dave, I’ve found a recommendation on a change to the code that goes inside the main loop. I haven’t had a chance to test this yet but will when I’m back at home in the morning.

Void loop() from “Time.ino”:

}

void loop() {
  time_t now = time(nullptr);
  Serial.println(ctime(&now));
  delay(1000);
}

Void loop() from my un-creatively named “Time2.ino”

void loop() {
  time_t now;
  struct tm * timeinfo;
  time(&now);
  timeinfo = localtime(&now);
  Serial.println(timeinfo->tm_hour);
  delay(1000);
}

My assumption from the second example above is that localtime() is of course going to display my local time based on what number is put into the integer “int timezone” at the top of the code. I also found a list of timezone number designations at Unattended, A Windows deployment system: Index numbers for [GuiUnattended]/TimeZone so that might be helpful to others working on this sort of thing, under the assumption that we’re located all over the world. Or maybe you want to build a desk clock that will display local time for your friend in another country.

Down to the serial print statement, the argument is (timeinfo->tm_hour). My assumption there is that this will display only the hour, not the day, date year, minute etc. Which, for my use is perfectly acceptable since I planned to only have the time function turn the light on or off depending on weather it’s day or night. I also don’t want the light to run all night long but rather only for a few hours starting just after sunset. Maybe from 2200 to about 0300. It’s summertime and I’m east of the Cascades in Eastern washington, so it’s decidedly dark around 10pm and starts getting light again around 4:30 - 5am.

Does anybody else wish we could still poll data from Weather Underground? I know I do.

Hi all,

It seems there have been some issues getting into the forum during the early hours (Local to west coast United States). I’m not sure if anybody else has run into this but I did contact support to bring it up in case they were unaware, albeit pretty unlikely. Anyway, I was going to update this thread and couldn’t so I’ll do that now.

Circling back to the original ask, how to get current time using ESP8266. This comes from the examples your get when you install support for these boards. I’ve simply begun stripping the code down as much as I could to make it simpler to understand for myself and thought it may be useful to others. The only items you have to configure to get your local time are TZ (Timezone ‘GMT’ plus or minus for your local time) and DST_MN (Used for daylight savings time if applicable, otherwise set to zero). Given my location, I set TZ to -8 for pacific standard time, and because it’s summer time, DST gets 60 minutes put in. You can add extra code to re-calculate DST at the appropriate times of the year if you want. I haven’t gone that far yet. Please see below code example which is just the “NTP-TZ-DST” code example with all of the extra prints cut out.

#include <ESP8266WiFi.h>
#include <time.h>                       // time() ctime()
#include <sys/time.h>                   // struct timeval
#include <coredecls.h>                  // settimeofday_cb()

////////////////////////////////////////////////////////

#define SSID            "YourSSID"
#define SSIDPWD         "YourPassword"
#define TZ              -8       // (utc+) TZ in hours
#define DST_MN          60      // use 60mn for summer time in some countries

////////////////////////////////////////////////////////

#define TZ_MN           ((TZ)*60)
#define TZ_SEC          ((TZ)*3600)
#define DST_SEC         ((DST_MN)*60)

timeval cbtime;			// time set in callback
bool cbtime_set = false;

void time_is_set (void)
{
  gettimeofday(&cbtime, NULL);
  cbtime_set = true;
}

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


  configTime(TZ_SEC, DST_SEC, "pool.ntp.org");
  WiFi.begin(SSID, SSIDPWD);
}

// for testing purpose:
extern "C" int clock_gettime(clockid_t unused, struct timespec *tp);

#define PTM(w) \
//  Serial.print(":" #w "="); \                             //Some extra prints I've cut out..
//  Serial.print(tm->tm_##w);

void printTm (const char* what, const tm* tm) {
//  Serial.print(what);
  PTM(isdst); PTM(yday); PTM(wday);
  PTM(year);  PTM(mon);  PTM(mday);
  PTM(hour);  PTM(min);  PTM(sec);
}

timeval tv;
timespec tp;
time_t now;
uint32_t now_ms, now_us;

void loop() {

  gettimeofday(&tv, nullptr);
  clock_gettime(0, &tp);
  now = time(nullptr);
  now_ms = millis();
  now_us = micros();

  // localtime / gmtime every second change
  static time_t lastv = 0;
  if (lastv != tv.tv_sec) {
    lastv = tv.tv_sec;
    printTm("localtime", localtime(&now));
    printTm("gmtime   ", gmtime(&now));
  }

  Serial.println(ctime(&now)); //This is where we actually print the time string.

  // simple drifting loop
  delay(1000);
}

The issue I’m having now is that when I start adding my wifi-server code in with this code, time stops working. I’m pretty sure at this point that I know why that is happening, but it’s still early, and my only day off this weekend, so I haven’t gotten around to giving it another try yet.

How about this code. Does it stop when you add the rest of your server code? It’s basically a striped down and converted from ESP32 code I use in a Lora gateway.

#include "time.h"
#include <ESP8266WiFi.h>
//#include <WiFi.h>

const char* ssid     = "**************";                    // your network SSID (name)
const char* password = "**************";                    // your network password


const char* ntpServer = "pool.ntp.org";
const long  gmtOffset_sec = 0;
const int   daylightOffset_sec = 3600;

/*
  %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 literals (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) 
*/
char buffer[80];

void printLocalTime()
{
  time_t rawtime;
  struct tm * timeinfo;

  time (&rawtime);
  timeinfo = localtime (&rawtime);

  strftime (buffer,80," %d %B %Y %H:%M:%S ",timeinfo);
  //struct tm timeinfo;
  //time_t now = time(nullptr);
  Serial.println(buffer);
  //Serial.print(ctime(&now));
  //Serial.print(&timeinfo, " %d %B %Y %H:%M:%S ");
}

void setup() 
{
  Serial.begin(115200);
  delay(10);
  
  // We start by connecting to a WiFi network
  Serial.print("\n\nConnecting to ");
  Serial.println(ssid);
  
  /* Explicitly set the ESP8266 to be a WiFi-client, otherwise, it by default,
    would try to act as both a client and an access-point and could cause
  network-issues with your other WiFi-devices on your WiFi-network. */
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  
  while (WiFi.status() != WL_CONNECTED) 
  {
    delay(500);
    Serial.print(".");
  }
  
  Serial.println();
  Serial.println("WiFi connected");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
  
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
  
  Serial.println("\nWaiting for time");
  unsigned timeout = 5000;
  unsigned start = millis();
  while (!time(nullptr)) 
  {
    Serial.print(".");
    delay(1000);
  }
  delay(1000);
  
  Serial.println("Time...");
}

void loop() 
{
  //time_t now = time(nullptr);
  //Serial.print(ctime(&now));
  printLocalTime();
  delay(1000);
}

Riva:
How about this code. Does it stop when you add the rest of your server code? It's basically a striped down and converted from ESP32 code I use in a Lora gateway.

Code section removed for shorter reply.

Hello Riva,

This does look similar to a sketch I had tried previously and I did find that after adding back the rest of my code, it too stopped polling time properly from NTP. As it turns out, this was caused by a connection issue to my router. The original code that I started from as my starting point declares a static IP on the local network and for some reason, when combined with the rest of the code it is not able to connect with the NTP pool.

I picked up that original piece of code from the following link:ESP8266 SOIL MOISTURE SENSOR WITH ARDUINO IDE

This was actually a really great place to start since it also covered some of the other things I would have to do in order to be able to program my new boards using the Arduino IDE. Unfortunately, because I ordered from Amazon and they really suck at making sure products are legit, I ended up with some counterfeit devices and I'm not able to program them through the "USB" port on the boards. Instead I have to manually put them into program mode, and transmit the code directly through the serial pins.

Anyway, back to the code. I was able to still get proper NTP time after allowing the board to just get an IP from the DHCP pool of my router. It then relays that IP over serial. I can also access my router and get the IP from the DHCP table.

I'm still not sure why specifying a static IP causes the device not to be able to communicate with the NTP pool, but I am content leaving that alone for now. Once I start building a lot of these, I'll have to set a unique hostname for each one or something along those lines. I don't know if I mentioned it before or not, but this whole project was inspired by a friend asking how it would be possible / practical to take soil readings throughout their front and back yard, which will likely mean I need to build 8 - 10 of these devices and will need them all to report data back to some central device that can organize that sensor data in a way that it can be graphed. The idea is to come up with a watering schedule that will yield the best efficiency. Watering in the middle of the day here can result in up to 50% being lost to evaporation and also water on the ground can also end up burning the grass. However, watering at midnight can result in accumulation of fungus and moss in the grass which would also rather be avoided.

The main purpose of the device knowing what time it is, as I mentioned previously, is to determine when to shut the lights off, specifically between dusk and dawn. So the next bit of code I'm planning to add will hopefully allow the end user to schedule when to turn the lights on and off, as well as being able to specify unique RGB light colors for each node, or all the same, since these are decorative solar garden lights, might as well get as much practical use of them as possible. To that end, this project to make watering the lawn more efficient must also be energy efficient. The light has a pair of 850mAh cells connected in parallel, which doesn't allow for the light to be on for 8 hours and also power the ESP8266 device and it's connected sensor. I'm hoping that limiting the on-time of the lights to 4-6 hours will do the trick.

Lastly, I am considering programming each module to sleep about 45 minutes out of every hour to conserve power but this may only be practical during daylight hours as we want the lights to be working when it is dark but only really need 1 or 2 data points each hour from each device.

Another fantastic resource for this board, in closing is the following link, which I have already learned many tricks from.

A beginner's guide to the ESP8266

Things I didn't realize these boards were capable of demonstrated and explained very well. Check that document out if you have not already.

Another update on my project in case anybody is following this thread at all.

Now that I've got NTP time synchronization working I've started focusing on other things. I've added a DHT22 temperature and humidity sensor into the circuit and that data is now posted to the web interface along with the soil moisture, local time and another part I'm still working on a bit that determines weather it's morning, afternoon or evening, through a series of "Ifs". I'm also recording time and all of the sensor data periodically to a CSV file which is being stored in the SPIFFS. I'm planning to have the board email that file to me and delete/recreate a blank local copy of the file. This way, SPIFFS won't fill up (hopefully) and I have an easy way to access the data and turn it into a graph so I can analyze the results on my computer.

I had initially thought to have the ESP serve this file through the web interface for download, but haven't managed to get that working yet. There is also a data logger example included in the documentation I linked previously that shows how to take this data and display it as a graph in a web form, which is cool, but not really what I'm going for. Plus, the author is using some proprietary sensor that I don't have.

Once all of the above is accomplished, the final task will be (Hopefully) to add to my current web interface, the ability to customize the RGB color of the garden spotlight. After that, I'll clean up, organize and notate my code and share it here. Actually, I'll create my own thread and link that here.

Yo Steverobey--

Bump.

Thanks for your work here. I am interested in your final results as getting the time on my ESP8266 is something I will be needing shortly.

Cheers,

--Jeff

Here is another sketch - more complex but covers all timezones:

https://www.arduinoslovakia.eu/blog/2017/7/esp8266---ntp-klient-a-letny-cas?lang=en

Steverobey:
Now there's an idea. Because I really only need to know if it's light or dark, not specifically the intensity of light, though I wonder if the nearby street light at the corner of my yard would throw things off a bit.

I use a photoresistor to control a chicken coop door, and I have my triggering thresholds set based on what the readings are when it's night time and when it's daytime. Sure, with the street light it won't get as dark at night as it otherwise would, but you'd still see a difference in the readings, and just set your thresholds accordingly.

Hi all,
I am also trying the same code which was mentioned above. I am facing a problem while including ESP8266WiFi.h file as i am getting error:

Arduino: 1.8.10 (Windows 10), Board: “Arduino/Genuino Uno”

Multiple libraries were found for “ESP8266WiFi.h”
Used: C:\Program
In file included from C:\Program Files (x86)\Arduino\libraries\ESP8266WiFi\src/ESP8266WiFi.h:33:0,

from F:\esp8266_time\esp8266_time.ino:33:

C:\Program Files (x86)\Arduino\libraries\ESP8266WiFi\src/ESP8266WiFiType.h:26:10: fatal error: queue.h: No such file or directory

#include <queue.h>

^~~~~~~~~

compilation terminated.

I don’t understand how to rectify it. I am unable to solve this problem. Is there any other library which i can use instead of this?

Please Help!!

Arduino: 1.8.10 (Windows 10), Board: "Arduino/Genuino Uno"

Is this correct? The code is for the ESP8266 core

Kumkum23:
Hi all,
I am also trying the same code which was mentioned above. I am facing a problem while including ESP8266WiFi.h file as i am getting error:

Arduino: 1.8.10 (Windows 10), Board: “Arduino/Genuino Uno”

Multiple libraries were found for “ESP8266WiFi.h”
Used: C:\Program
In file included from C:\Program Files (x86)\Arduino\libraries\ESP8266WiFi\src/ESP8266WiFi.h:33:0,

from F:\esp8266_time\esp8266_time.ino:33:

C:\Program Files (x86)\Arduino\libraries\ESP8266WiFi\src/ESP8266WiFiType.h:26:10: fatal error: queue.h: No such file or directory

#include <queue.h>

^~~~~~~~~

compilation terminated.

I don’t understand how to rectify it. I am unable to solve this problem. Is there any other library which i can use instead of this?

Please Help!!

you need to install board for esp8266 … search this… esp8266 board manager

Kumkum23:
I am also trying the same code which was mentioned above.

What code? The ESP8266 example code I posted in #7 compiles fine for me using the v2.6.1 core.

Oh,
Then what should I do to get current date and time from esp8266-01 connected with arduino uno?

Hi Steverobey!

Hi all,

It seems there have been some issues getting into the forum during the early hours (Local to west coast United States). I'm not sure if anybody else has run into this but I did contact support to bring it up in case they were unaware, albeit pretty unlikely. Anyway, I was going to update this thread and couldn't so I'll do that now.

Circling back to the original ask, how to get current time using ESP8266. This comes from the examples your get when you install support for these boards. I've simply begun stripping the code down as much as I could to make it simpler to understand for myself and thought it may be useful to others. The only items you have to configure to get your local time are TZ (Timezone 'GMT' plus or minus for your local time) and DST_MN (Used for daylight savings time if applicable, otherwise set to zero). Given my location, I set TZ to -8 for pacific standard time, and because it's summer time, DST gets 60 minutes put in. You can add extra code to re-calculate DST at the appropriate times of the year if you want. I haven't gone that far yet. Please see below code example which is just the "NTP-TZ-DST" code example with all of the extra prints cut out.

I tried your code, and it's working fine, but I need help!
I would like to use the hours, minutes and seconds individually maybe in integer for a project, can you show me, how can I do this with this code?
Anyhow, great job!