What is the best way to get NPT data to Arduino using ESP8266

Hi, I’ve a long code for irrigation system working on Arduino uno. I’m using RTC DS1307 module, however it skips more than 1 minute every day so I purhased ESP8266 module to periodically update time.

As I’m using Time.h library together with TimeAlarms library, and I see that there is setSyncProvider(getTimeFunction) command to synchronize time periodically.

I’ve separately test ESP8266 and successfully get NPT data to ESP8266. But it works based on the delay inside the loop of ESP8266 code. So for now it gets NPT data every second. I can send this code via Serial port, listen it from Arduino periodically, update Arduino/RTC time when a data is received from Serial port.

However it does not make much sense, because I want to update time data once a day, so listening the same port all the time for a code that will be received only once a day feels like too much.

So I guess it would be better if Arduino request NPT time from ESP8266 and ESP turns back with the new value only when it is asked. How it would be possible? Any sample code for Arduino and ESP8266 I should use?

Below is the code I’ve tested with ESP8266 that gets NPT time every second.

#include <NTPClient.h>
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>

const char *ssid     = "Wifi Name";
const char *password = "Password";
const long utcOffsetInSeconds = 14400;  //Dubai time zone is GMT+4 = 4*60*60 = 14400seconds difference
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

String formattedDate;
String dayStamp;
String timeStamp;

// 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();
  
  formattedDate = timeClient.getFormattedDate();
  Serial.println(formattedDate);                      //Return will be like 2019-09-01T23:56:36Z
  delay(1000);
}

gunaygurer:
Hi, I've a long code for irrigation system working on Arduino uno. I'm using RTC DS1307 module, however it skips more than 1 minute every day....

If seen it noted on the forum that DS1307 is kind of crappy. There are better ones.

To do it this way, you need to set up a command / response protocol between the 2 processors. Take a look at @Robin2's Serial Tutorial for various techniques. I'd send the time as NTP or Unix Time (int32_t or unit32_t) rather than trying to format hhmmss / ddmmyy or some such. You could send the number as ASCII as that's simpler (though less efficient) than binary. The TimeLib library can take care of conversion for you once it's received in the Arduino.

Because of the variable response time over the internet for the NTP reply (and the inherently slow nature of Serial communications), you should implement a state machine so that you're code doesn't block while waiting for waiting for the reply. For the same reason, I'd probably not use the setSyncProvider() technique but rather set the new time directly when you get a fresh NTP reading.

Also consider the need to handle failure of the NTP request and a "stale" timestamp.

However it does not make much sense, because I want to update time data once a day, so listening the same port all the time for a code that will be received only once a day feels like too much.

So you might just listen once a day. You can use the RTC's change of day to do that. I don't suppose the plants will complain much if the water is a minute late but what you are getting is pretty typical with a DS1307 outdoors. The DS3231 is much more accurate and costs only a dollar or so more. Note that the module is a lot bigger than that typical for the DS1307. The battery holder can be a problem..

Thanks for the answers, I dont want to switch to another RTC module, as I already have esp8266 on hand. Additionally I'll use ESP for tracking the system from my phone so as long as I have a wifi, I prefer to use it.

I guess transferring the time in Unix Time format would be a good idea.

Now the question is I've get the esp work. It prints ntp data from serial port every second. As I've asked in my latest post I was thinking about how to get ntp data only once a day at a certain time, and print it only when there is a change.

I was also considering another way. Instead of ESP sending this NTP data every day at a certain time, I would program arduino to ask for time update by using an alarm(timeAlarms.h), esp to return with the right time. But I believe it would not be so good as if NTP time is a couple of seconds before Arduino time, then arduino would be triggered continuously as it would reach the same alarm time again.

Just keep a softRTC running on the ESP that keeps itself updated as often as it wants.

Then in the serial protocol used between the ESP and Arduino just add the current timestamp to the start of the packet. “[timeserial] - thedata\r”
Then the Arduino can just check that to see if it is still within time spec on each transaction.

Yes to your point about re-tripping alarms if the time is set back a little,
You just have to cater for that in your code,
perhaps disabling alarms until the right time has passed after updating.
But if you have the timestamp in every serial packet there is no need to request it via an alarm.!

You may also want to be sending stuff from the Arduino to the ESP for transmitting to cloud logging.
Same thing just include the Arduino timestamp in the serial packet that the Arduino send to the ESP.

Long term you may also want to enable HTTP firmware updates on both the ESP and the Arduino.
You can program the Arduino using the ESP, but you knew that already…

Remember not to directly connect any 5v Arduino data lines to the ESP.
The ESP is only tolerant to 3.3v.
Simple Level convertors should be used on any interconnections.

gunaygurer:
I would program arduino to ask for time update by using an alarm(timeAlarms.h), esp to return with the right time. But I believe it would not be so good as if NTP time is a couple of seconds before Arduino time, then arduino would be triggered continuously as it would reach the same alarm time again.

That ia probably what I was talking about, where the NPT is checked at midnight.

GetClock();
  if (today != day)
  {
   today = day;
   chkNPT(); 
  }

I take your point about taking another bite as long as RTC is fast, but I don't think you will notice the extra few rounds of resetting the clock. I think there might be only one extra anyway.

I think, if you use NTP, the DS1307 is redundant. Alll you need do is use NTP in set up to get the correct time irrespective of that time of day.