Delayed ntp time and unix time calculation

  1. I am having trouble getting a fast ntp time after compiling my code below.
    It takes way too long to get valid ntp time from internet. I only get 1970-01-01 08:0:0 after first compiling and it last too long to get valid time from ntp. If I hit reset button again it will get valid ntp time faster.
    Is that considered normal? Once I get valid ntp time it is 3-4 seconds behind the time shown on my computer.
    2.Also I have to calculate the unix time by using a function I found from internet. Is there any method built in from time.cpp or timeLib.cpp like now.getunix() to get unix time?
  2. How do I know from code loop() that I have a valid ntp time ready to use other than 1970-1-1 8:0:0 from the begining? Thank you very much guys.
#include <ESP8266WiFi.h>// 2019-01-25
#include <time.h>
#include <TimeLib.h> //needed for convert any given time to unix format

 

const char* ssid = "" ;
const char* password = " ";


uint8_t ledPin = D6;// set up as active low, for verify wifi con

int timezone = -6 * 3600;// -7 is mountain time zone
int dst = 0;
String NTP_Date_Lcd;//for printing it to lcd ie 2019-01-31
String NTP_Time_Lcd;//for printing it to lcd ie 20:30u

unsigned long unix_NTP;
unsigned long unix_RTC;

uint32_t currentMillis = 0;
uint32_t previousMillis = 0;



#include <LiquidCrystal_I2C.h>
#include <Wire.h>
LiquidCrystal_I2C lcd(0x3F, 20, 4);


// Date and time functions using a DS3231 RTC connected via I2C and Wire lib
#include <Wire.h>
#include "RTClib.h"

RTC_DS3231 rtc;

char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};



// DHT Temperature & Humidity Sensor
// Unified Sensor Library Example
// Written by Tony DiCola for Adafruit Industries
// Released under an MIT license.

// REQUIRES the following Arduino libraries:
// - DHT Sensor Library: https://github.com/adafruit/DHT-sensor-library
// - Adafruit Unified Sensor Library: https://github.com/adafruit/Adafruit_Sensor

#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <DHT_U.h>

#define DHTPIN     D7         // Pin connected to the DHT sensor.


// Uncomment the type of sensor in use:
//#define DHTTYPE    DHT11     // DHT 11
#define DHTTYPE    DHT22     // DHT 22 (AM2302)
//#define DHTTYPE    DHT21     // DHT 21 (AM2301)

// See guide for details on sensor wiring and usage:
//   https://learn.adafruit.com/dht/overview

DHT_Unified dht(DHTPIN, DHTTYPE);

uint32_t delayMS;
float t, h; //used in loop for temperature and humidity



void setup() {
  Serial.begin(9600);
  pinMode(D6, OUTPUT);
  pinMode(D5, OUTPUT);
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, HIGH); // this pin is connected to 3V and D6 which will be turned on when D6 is LOW.



  Wire.begin(D2, D1);   //Use predefined PINS consts SCL SDA pins
  lcd.begin(20, 4);     // The begin call takes the width and height. This
  // Should match the number provided to the constructor.

  lcd.backlight();      // Turn on the backlight.
  lcd.clear();
  // lcd.home();



  Serial.begin(9600);
  Serial.print("Wifi connecting to");
  printLcd(1, 1, ssid);
  Serial.println( ssid );
  WiFi.begin(ssid, password);


  Serial.print("Connecting");

  while ( WiFi.status() != WL_CONNECTED ) {
    currentMillis = millis();
    if (currentMillis - previousMillis > 8000) {
      printLcd(2, 1, " WIFI timeout");
      delay(2000);
    }
    delay(500);
    Serial.print(".");
  }
  //reset millis counter
  currentMillis = 0;
  previousMillis = 0;


  printLcd(2, 1, "Wifi Connected!     ");
  printLcd(3, 1, ssid);


  //Serial.print("IP: ");
  printLcd(4, 1, WiFi.localIP().toString() );
  Serial.println(WiFi.localIP() );
  digitalWrite( ledPin, LOW);
  delay(2000);


  configTime(timezone, dst, "pool.ntp.org", "time.nist.gov");
  Serial.println("\nWaiting for Internet time");

  while (!time(nullptr)) {
    Serial.print("**********");
    delay(2000);
  }

  Serial.println("\nTime response....OK");

 
#ifndef ESP8266
  while (!Serial); // for Leonardo/Micro/Zero
#endif


  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }

  if (rtc.lostPower()) {
    Serial.println("RTC lost power, lets set the time!");
    // following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    //rtc.adjust(DateTime(2019, 1, 31, 23, 41, 30));
  }


  // Initialize device.
  dht.begin();
  Serial.println(F("DHTxx Unified Sensor Example"));
  // Print temperature sensor details.
  sensor_t sensor;
  dht.temperature().getSensor(&sensor);
  Serial.println(F("------------------------------------"));
  
 }

  
void loop() {


  digitalWrite(D5, LOW);


  time_t currentTime = time(nullptr); // needed for NTP section
  struct tm* p_tm = localtime(&currentTime);// needed for NTP section



  // convert to unix time
  Serial.println( "
  time_t unix_NTP = tmConvert_t(p_tm->tm_year + 1900, p_tm->tm_mon + 1, p_tm->tm_mday, p_tm->tm_hour, p_tm->tm_min, p_tm->tm_sec);
  Serial.print("UNIX TIME FROM NTP: ");
  Serial.println(unix_NTP);



  String NTP_Date_Lcd = String(p_tm->tm_year + 1900) + "-" + addZero(p_tm->tm_mon + 1) + "-" + addZero(p_tm->tm_mday);
   String NTP_Time_Lcd = addZero(p_tm->tm_hour) + ":" + addZero(p_tm->tm_min) + ":" + addZero(p_tm->tm_sec);
  Serial.print(NTP_Time_Lcd );
  DateTime now = rtc.now();

  char realTime_YMD[10];
  sprintf ( realTime_YMD, "%02d-%02d-%02d", now.year(), now.month(), now.day());
  char realTime_HMS[10];
  sprintf ( realTime_HMS, "%02d:%02d:%02d", now.hour(), now.minute(), now.second());

  //String realTime_YMD = String(now.year()) + "-" + addZero(now.month()) + "-" + addZero(now.day());

  //String realTime_HMS = addZero(now.hour()) + ":" + addZero(now.minute()) + ":" + addZero(now.second());

  
  Serial.println(unix_NTP);
  Serial.print("UNIX TIME FROM RTC: ");
  Serial.println(now.unixtime());
  Serial.print("differences between two unix time(s): ");
  Serial.println(abs(now.unixtime() - unix_NTP));



  if ( WiFi.status() == WL_CONNECTED && ( p_tm->tm_year + 1900) > 1988 && abs(now.unixtime() -  unix_NTP) >= 2 && time(nullptr))
  {
    Serial.println("adjust rtc needed");
    rtc.adjust(DateTime(p_tm->tm_year + 1900, p_tm->tm_mon + 1, p_tm->tm_mday, p_tm->tm_hour, p_tm->tm_min, p_tm->tm_sec));
  }

 
  sensors_event_t event;
  dht.temperature().getEvent(&event);
  if (isnan(event.temperature)) {
    Serial.println(F("Error reading temperature!"));
  }
  else {
    Serial.print(F("Temperature: "));
    Serial.print(event.temperature);
    t = event.temperature;
    Serial.println(F("°C"));
  }
  // Get humidity event and print its value.
  dht.humidity().getEvent(&event);
  if (isnan(event.relative_humidity)) {
    Serial.println(F("Error reading humidity!"));
  }
  else {
    Serial.print(F("Humidity: "));
    Serial.print(event.relative_humidity);
    h = event.relative_humidity;
    Serial.println(F("%"));
  }

 
  if (now.unixtime() % 1 == 0) {
    printLcd(2, 1, realTime_YMD);//rtc date
    printLcd(2, 11, (NTP_Date_Lcd) ); //ntp date
    printLcd(3, 1, realTime_HMS);// rtc time
    printLcd(3, 12, (NTP_Time_Lcd) ); //ntp time
    //sprintf (timeStr, "%02d:%02d:%02d", hour (moment), minute (moment), second (moment));

    // sprintf(display_string,"%2d %2d %2d %2d",v1,v2,v3,v4);
    printLcd(4, 1, "T:" + String(t, 1) + " C");
    printLcd(4, 11, "H:" + String(h, 1)   + " %");

    Serial.println("----------------------------------------------------------------------------------------------------------------------------------------");
  }

}

//lcd.setCursor(0,1);
// sprintf(display_string,"%2d %2d %2d %2d",v1,v2,v3,v4);
// lcd.print( display_string );


void printLcd(uint8_t row, uint8_t column, String data)
// as tradiditional row first staring from 1, colunmn starting from 1
{
  lcd.setCursor(column - 1, row - 1);
  lcd.print(data);
}


time_t tmConvert_t(int YYYY, byte MM, byte DD, byte hh, byte mm, byte ss)
//onverts any given date and time to epoch/timestamp using an ESP8266 or NODEMCU board
//TimeLib.h needed in the sketch
{
  tmElements_t tmSet;
  tmSet.Year = YYYY - 1970;
  tmSet.Month = MM;
  tmSet.Day = DD;
  tmSet.Hour = hh;
  tmSet.Minute = mm;
  tmSet.Second = ss;
  return makeTime(tmSet);
}

String addZero( int data) {
  if (data < 10 && data > 0) {
    return "0" + String(data);
  }
  else {
    return String(data);
  }
}
  Serial.println("\nWaiting for Internet time");

  while (!time(nullptr)) {
    Serial.print("**********");
    delay(2000);
  }

Why do you care how many times the while loop iterates? Deliberately delaying for 2 seconds before trying to get the time again, and complaining that it takes too long to get the time are not things that belong in the same post.

Get rid of one of them.

Thank you for point out the defects I corrected it and became faster getting valid ntp time.

and now how to calculate unix time using method if that is available in the code I am using other than function.
thanks a lot.

Why does it matter if you use a function you found on the internet vs. using a method in a class you found on the internet? As long as the function returns the correct value, nothing else matters.

  1. How do I know from code loop() that I have a valid ntp time ready to use other than 1970-1-1 8:0:0 from the begining? Thank you very much guys.

Declared a boolean variable, gotNTPTime, initialized to false. Set it to true when you get the NTP time. Test that variable before using the internet time.

how to calculate unix time using method if that is available in the code I am using other than function.
thanks a lot.

The way you have the network time with

configTime(timezone, dst, "pool.ntp.org", "time.nist.gov");

You should have the local "unix" time in the currentTime variable, and no need for any conversion.

time_t currentTime = time(nullptr); // needed for NTP section
  struct tm* p_tm = localtime(&currentTime);// needed for NTP section
  // convert to unix time
  Serial.println( "
  time_t unix_NTP = tmConvert_t(p_tm->tm_year + 1900, p_tm->tm_mon + 1, p_tm->tm_mday, p_tm->tm_hour, p_tm->tm_min, p_tm->tm_sec);
  Serial.print("UNIX TIME FROM NTP: ");
  Serial.println(unix_NTP);