Tag Archives: arduino clock

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));

 

DS-1302 RTC Clock Module for Arduino

DS-1302 from Maxim (data sheet download) is a cheap RTC chip. Below are some of the salient features.

  1. Real-Time Clock Counts Seconds,Minutes, Hours, Date of the Month, Month, Day of the Week, and Year with Leap-Year Compensation Valid Up to 2100
  2. Simple 3-Wire Interface
  3. 2.0V to 5.5V Full Operation
  4. TTL-Compatible (VCC = 5V)
  5. 31 x 8 Battery-Backed General-Purpose RAM
There are breakout boards available on ebay, which will be handy to build RTC based projects with Arduino. Look for China based sellers for a cheap price.
DS-1302 RTC 2 DS-1302 RTC 1DS-1302 RTC 3DS-1302 RTC 4
Though there are various modules available but the above two types I found to be working properly.
The below board didn't work at all. Notice the PCB trace which indicates the poor quality.Unfortunately there was no way to know this before delivery.

DS-1302 RTC - Bad  DS-1302 RTC - Bad 2
For those modules which has two power pins (VCC1 and VCC2), power to be connected to VCC2, VCC1 is connected to battery
The below code can be used to used to write and read time from the chip. Credit for the DS1302 library used here goes to Matt Sparks.  The library can be downloaded from Github and also from here (in case it goes off from Github).
Below is a code snippet (based on Matt Spark’s work) for setting time and reading it back easily. Please note for writing to the chip VCC2 needs to be given power (I used 5v).
    //http://datasheets.maximintegrated.com/en/ds/DS1302.pdf

    #include <DS1302.h>
    //#include <SoftwareSerial.h>

    //SoftwareSerial mySerial(2, 3); // RX, TX

    namespace {

      // Set the appropriate digital I/O pin connections.
      
      const int kCePin   = 8;  // Chip Enable (Some calls it Reset)
      const int kIoPin   = 7;  // Input/Output
      const int kSclkPin = 6;  // Serial Clock
      
      // Create a DS1302 object.
      DS1302 rtc(kCePin, kIoPin, kSclkPin);
      
      String dayAsString(const Time::Day day) {
        switch (day) {
          case Time::kSunday: return "Sunday";
          case Time::kMonday: return "Monday";
          case Time::kTuesday: return "Tuesday";
          case Time::kWednesday: return "Wednesday";
          case Time::kThursday: return "Thursday";
          case Time::kFriday: return "Friday";
          case Time::kSaturday: return "Saturday";
        }
        return "(unknown day)";
      }
      
      void printTime() {
        // Get the current time and date from the chip.
        Time t = rtc.time();
      
        // Name the day of the week.
        const String day = dayAsString(t.day);
      
        // Format the time and date and insert into the temporary buffer.
        char buf[50];
        snprintf(buf, sizeof(buf), "%s %04d-%02d-%02d %02d:%02d:%02d",
                 day.c_str(),
                 t.yr, t.mon, t.date,
                 t.hr, t.min, t.sec);
      
        // Print the formatted string to serial so we can see the time.
        Serial.println(buf);
        //mySerial.println(buf);
      }

    }  // end of namespace

    void setup() {
      Serial.begin(9600);
      //mySerial.begin(38400);
      // Initialize a new chip by turning off write protection and clearing the clock halt flag.
      rtc.writeProtect(false); //should be set to true after writing to prevent accidental writes
      rtc.halt(false);

      // Year month day hour min sec. DOW
      Time t(2016, 2, 28, 19, 9, 30, Time::kSunday);

      // Set the time and date on the chip.
      rtc.time(t);  //after writing once, comment/remove this code to prevent unnecessary/wrong re-writing of the time
    }

    // Loop and print the time every 5 seconds.
    void loop() {
      printTime(); //prints the date and time
      
      delay(5000);
    }