-->
Page 1 of 4

My 4 digit clock with a NTP time client

PostPosted: Mon May 25, 2015 8:10 am
by nigelbe
I have this working on a raspberry pi but I wanted to use and ESP so...

Code: Select all
/*
* espNTPdigitalClock.ino
*
* Created: 5/6/2015 2:17:03 PM
* Author: Nigel with help from lots of others.
*/

#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <Time.h>
#include <Wire.h>
#include <Adafruit_LEDBackpack.h>
#include <Adafruit_GFX.h>
#include <Ticker.h>
extern "C" {
   #include "user_interface.h"
}

char ssid[] = "*********";         //  your network SSID (name)
char pass[] = "?????????";             // your network password

#define localTimeOffset 0UL      // your localtime offset from UCT

#define UPDATESECS 1800UL      // update every 30 minutes
time_t update;
bool flag = true;
bool colon = false;

// A UDP instance to let us send and receive packets over UDP
WiFiUDP            udp;
Adafruit_7segment   disp = Adafruit_7segment();
Ticker            showTime;

unsigned int localPort = 2390;               // local port to listen for UDP packets

const char* timeServer = "sue.wine";         //  my own local time server
const char* timeServer2 = "uk.pool.ntp.org";   // fall back to regional time server

const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message

byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets

void setup()
{
   Serial.begin(115200);
   Wire.begin(4,5);   // sda,sdl
   delay(10);
   disp.begin(0x70);   // default display for the LED backpack
   notime();         // set the display to 8888 with no colon
   
   Serial.println();
   Serial.println();

   // We start by connecting to a WiFi network
   Serial.print("Connecting to ");
   Serial.println(ssid);
   WiFi.begin(ssid, pass);
   WiFi.mode(WIFI_STA);
   while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print(".");
   }
   Serial.println("");
   Serial.println("WiFi connected");
   Serial.println("IP address: ");
   Serial.println(WiFi.localIP());
   WiFi.disconnect();
   showTime.attach(0.333,doDisplay);
   setNTPtime();
}

void loop()
{
   if(now() > update) setNTPtime();
   if(flag && (now() % 10UL == 0UL)) printTime("Now ",now());
   else flag = true;
   delay(900);
}

void doDisplay()
{
   if (year() > 2014){
      disp.print(hourFormat12() * 100 + minute()); // I like to see it as a 12 hour clock
      disp.drawColon(colon);
      disp.writeDisplay();
   }
}

void setNTPtime()
{
   WiFi.begin(ssid, pass);
   WiFi.mode(WIFI_STA);
   colon = false;
   while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print(".");
   }
   Serial.println();
   time_t epoch = 0UL;
   if((epoch =  getFromNTP(timeServer)) != 0 || (epoch =  getFromNTP(timeServer2)) != 0){ // get from time server
      epoch -= 2208988800UL + localTimeOffset;
      setTime(epoch += dst(epoch));
      update = now() +  UPDATESECS; // set next update time if successful
      colon = true;
   }
   else{
      colon = false;
      update = now() + 30; // or try again in 30 seconds
   }
   WiFi.disconnect();
}

unsigned long getFromNTP(const char* server)
{
   udp.begin(localPort);
   sendNTPpacket(server);   // send an NTP packet to a time server
   delay(1000);         // wait to see if a reply is available
   int cb = udp.parsePacket();
   if (!cb) {
      Serial.println("no packet yet");
      return 0UL;
   }
   Serial.print("packet received, length=");
   Serial.println(cb);
   // We've received a packet, read the data from it
   udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer

   //the timestamp starts at byte 40 of the received packet and is four bytes,
   // or two words, long. First, extract the two words:

   unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
   unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
   // combine the four bytes (two words) into a long integer
   // this is NTP time (seconds since Jan 1 1900):
   udp.stop();
   return (unsigned long) highWord << 16 | lowWord;
}

// send an NTP request to the time server at the given address
unsigned long sendNTPpacket(const char* server)
{
   Serial.print("sending NTP packet to ");
   Serial.println(server);
   // set all bytes in the buffer to 0
   memset(packetBuffer, 0, NTP_PACKET_SIZE);
   // Initialize values needed to form NTP request
   // (see URL above for details on the packets)
   packetBuffer[0] = 0b11100011;   // LI, Version, Mode
   packetBuffer[1] = 0;     // Stratum, or type of clock
   packetBuffer[2] = 6;     // Polling Interval
   packetBuffer[3] = 0xEC;  // Peer Clock Precision
   // 8 bytes of zero for Root Delay & Root Dispersion
   packetBuffer[12]  = 49;
   packetBuffer[13]  = 0x4E;
   packetBuffer[14]  = 49;
   packetBuffer[15]  = 52;

   // all NTP fields have been given values, now
   // you can send a packet requesting a timestamp:
   udp.beginPacket(server, 123); //NTP requests are to port 123
   udp.write(packetBuffer, NTP_PACKET_SIZE);
   udp.endPacket();
}

int dst (time_t t) // calculate if summertime in Europe
{
   tmElements_t te;
   te.Year = year(t)-1970;
   te.Month =3;
   te.Day =1;
   te.Hour = 0;
   te.Minute = 0;
   te.Second = 0;
   time_t dstStart,dstEnd, current;
   dstStart = makeTime(te);
   dstStart = lastSunday(dstStart);
   dstStart += 2*SECS_PER_HOUR;  //2AM
   te.Month=10;
   dstEnd = makeTime(te);
   dstEnd = lastSunday(dstEnd);
   dstEnd += SECS_PER_HOUR;  //1AM
   if (t>=dstStart && t<dstEnd) return (3600);  //Add back in one hours worth of seconds - DST in effect
   else return (0);  //NonDST
}

time_t lastSunday(time_t t)
{
   t = nextSunday(t);  //Once, first Sunday
   if(day(t) < 4) return t += 4 * SECS_PER_WEEK;
   else return t += 3 * SECS_PER_WEEK;
}

void printTime(const char s[],time_t t)
{
   flag =false;
   Serial.print(s);
   printLeading0(hour(t));
   Serial.print(":");
   printLeading0(minute(t));
   Serial.print(":");
   printLeading0(second(t));
   Serial.print(" ");
   Serial.print(dayStr(weekday(t)));
   Serial.print(" ");
   Serial.print(day(t));
   Serial.print(" ");
   Serial.print(monthStr(month(t)));
   Serial.print(" ");
   Serial.println(year(t));
}

void printLeading0(int n)
{
   if(n < 10) Serial.print("0");
   Serial.print(n);
}

void notime(void)
{
   disp.drawColon(false);
   disp.print(8888);
   disp.writeDisplay();
}



I hope this helps someone.

Nigel.

Re: My 4 digit clock with a NTP time client

PostPosted: Wed Dec 16, 2015 8:57 pm
by Leandro Rodrigues
Hi, Mr! Sorry some my bab Englsh!
I'like undertand this "'tmElements_t' was not declared in this scope", when I try compiling...
Thanks a lot and best regards!

Re: My 4 digit clock with a NTP time client

PostPosted: Thu Dec 17, 2015 1:11 pm
by nigelbe
Leandro Rodrigues wrote:Hi, Mr! Sorry some my bab Englsh!
I'like undertand this "'tmElements_t' was not declared in this scope", when I try compiling...
Thanks a lot and best regards!



I think it is from Time.h

Re: My 4 digit clock with a NTP time client

PostPosted: Thu Dec 17, 2015 1:15 pm
by martinayotte
Yes, it is from Time library.
Do you have it installed ?
You can find it here : https://github.com/PaulStoffregen/Time