Tag Archives: iot NTP

ESP-8266 and NTP = onboard timekeeping

We can sync the time of a ESP-8266 with a NTP server and then keep time count on the device. It will not need any other additional devices like a DS1307 clock. And once synced with the NTP server it can keep the time even if there is no internet  – very handy.

The time formatting and display functions are standard C++ functions.

#include <ESP8266WiFi.h>

#include "TinyDHT.h"

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


#define DHTPIN11 14          // What digital pin we're connected to
#define DHTTYPE11 DHT11     // DHT 11

DHT dht11(DHTPIN11, DHTTYPE11);

struct tm* tm;

float temperature, relHumidity;
String currentTime;

#define countof(a) (sizeof(a) / sizeof(a[0]))

#define LED 13

void setup() {

  time_t now = 0;

  // Initialize serial and wait for port to open:
  Serial.begin(9600);
  // This delay gives the chance to wait for a Serial Monitor without blocking if none is found
  delay(1500); 

  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");

  Serial.println("WiFi connected");
  
//sync time with the NTP server. First param 19800 seconds = +5:30 for IST, Second Param 0 = DST 
 configTime(19800, 0, "pool.ntp.org");

//waiting for time to get synced before proceeding. This is not strictly required. Please see after code 
  do
  {
    now = time(nullptr);
    delay(500);
    Serial.print("*");
  }while(now < time(nullptr));
  
  pinMode(LED, OUTPUT);
  
  pinMode(DHTPIN11, INPUT);
  dht11.begin();

  onLedIndicatorChange();
}


void loop() {
  // Your code here 
  time_t now = time(nullptr);
  
  char datestring[30];
  
  strftime(datestring, 
            countof(datestring),
            "%d/%m/%Y %I:%M:%S %p",
            localtime(&now)
            );
   
  currentTime = datestring; 
  Serial.println(currentTime);
  temperature = dht11.readTemperature();
  delay(200);
  relHumidity = dht11.readHumidity();
  delay(200);

}

void onLedIndicatorChange() {
  // Do something
  int ledIndicator = 1; 
  digitalWrite(LED, ledIndicator);
}

configtime listens for connection in the back and will sync as soon as a connection is available. So if a time is not critical for the successive codes or functions then the loop that waits for the sync can be skipped.

configTime(19800, 0, "pool.ntp.org");
do //loop and wait for a sync
{
  now = time(nullptr);
  delay(500);
  Serial.print("*");
}while(now < time(nullptr));

 

Sync Ds1302 with NTP

This code first syncs the DS1302 chip with a NTP server and then reads time from the DS1302 chip. Every time the system is booted the clock is synced with a NTP server.

#include <ESP8266WiFi.h>

#include "TinyDHT.h" // Adafruit library https://github.com/adafruit/TinyDHT

#include <ThreeWire.h> // needed by rtc
#include <RtcDS1302.h> // Makuna library https://github.com/Makuna/Rtc

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


#define DHTPIN11 14          // Pin to which DHT11 connected to
#define DHTTYPE11 DHT11     // DHT 11

DHT dht11(DHTPIN11, DHTTYPE11);

ThreeWire myWire(5,16,4); // IO, SCLK, CE/Reset
RtcDS1302<ThreeWire> Rtc(myWire);
RtcDateTime currentTimeEpoch;

#define countof(a) (sizeof(a) / sizeof(a[0]))

float temperature, relHumidity;
String currentTime;

void initialiseRTC()
{
    //now = time(nullptr);
    //Serial.print(now);
    
    /*if (!Rtc.IsDateTimeValid()) 
    {
        // Common Causes:
        //    1) first time you ran and the device wasn't running yet
        //    2) the battery on the device is low or even missing

        Serial.println("RTC lost confidence in the DateTime!");
        //by default the RTC library assumes time from year 2000, but EPOCH starts from 1970. Severs returns EPOCH and that is the standard. So below converting the EPOCH to equivalent RTC date.   
        currentTimeEpoch.InitWithEpoch32Time(time(nullptr));
        Rtc.SetDateTime(currentTimeEpoch);
    }*/

    if (!Rtc.GetIsRunning())
    {
        Serial.println("RTC was not actively running, starting now");
        Rtc.SetIsRunning(true);
    }

    if (Rtc.GetIsWriteProtected())
    {
        Serial.println("RTC was write protected, enabling writing");
        Rtc.SetIsWriteProtected(false);
    }

    //here we are always syncing the clock when the device is booted. 
    currentTimeEpoch.InitWithEpoch32Time(time(nullptr));
    Rtc.SetDateTime(currentTimeEpoch);
    
    if (!Rtc.GetIsWriteProtected())
    {
        Serial.println("RTC was not write protected, disabling writing");
        Rtc.SetIsWriteProtected(true);
    }

}

#define LED 13

void setup() {
  time_t now = 0;
  // Initialize serial and wait for port to open:
  Serial.begin(9600);
  // This delay gives the chance to wait for a Serial Monitor without blocking if none is found
  delay(1500); 

  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");

  Serial.println("WiFi connected");
  
// here we are setting up the NTP call. Consequently we can just call time() to get the time. 
//the first parameter is Timezone in seconds, second parameter is DST in seconds and third parameter is the NTP server. 
  configTime(19800, 0, "pool.ntp.org"); 

//wait till the clock is synced, else wrong time will get set in the DS1302 chip 
  do   
  {
    // time(nullptr) - returns the time that was received from NTP server
    now = time(nullptr);
    delay(500);
    Serial.print("*");
  }while(now < time(nullptr));

  Rtc.Begin(); //initialise the RTC library
  initialiseRTC(); // this will set the NTP time in DS1302 clock chip,
  
  pinMode(LED, OUTPUT);
  
  pinMode(DHTPIN11, INPUT);
  dht11.begin();

  onLedIndicatorChange();
}

void loop() {
  // Your code here 
  RtcDateTime now = Rtc.GetDateTime(); // reading the time from DS1302 clock module
  char datestring[20];
  
  snprintf_P(datestring, 
            countof(datestring),
            PSTR("%02u/%02u/%04u %02u:%02u:%02u"),
            now.Month(),
            now.Day(),
            now.Year(),
            now.Hour(),
            now.Minute(),
            now.Second() );
   
  currentTime = datestring; 
  Serial.println(currentTime);
  temperature = dht11.readTemperature();
  delay(200);
  relHumidity = dht11.readHumidity();
  delay(200);

}

void onLedIndicatorChange() {
  // Do something
  int ledIndicator = 1; 
  digitalWrite(LED, ledIndicator);
}