// libraries
#include <SPI.h>
#include <Ethernet.h>
#include <Wire.h>
#include "RTClib.h"
#include <EthernetUdp.h>
// Configuration des adresses Ethernet (MAC) et Internet (IP) du serveur TCP/IP de la carte Arduino.
byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0xB5, 0x42 };//Valeur en hexadécimale de l'adresse MAC de la carte Arduino. Valeur unique sur le réseau.
IPAddress ip(192,168,1,12);
// Configuration pour connection à un serveur NTP pour mise à jour de l'heure
unsigned int localPort = 8888; // local port to listen for UDP packets
IPAddress timeServer(95, 130, 9, 77); // http://Ntp.crashdump.fr se synchronise sur les serveur de strate 1
//IPAddress timeServer(193, 79, 237, 14);
//IPAddress timeServer(193, 52, 137, 193); //http://www.pool.ntp.org/fr/
byte pb[48]; // buffer to hold incoming and outgoing packets // NTP time stamp is in the first 48 bytes of the message
//Déclaration Internet
EthernetServer server(80);//déclaration du serveur internet de la carte Arduino.
// A UDP instance to let us send and receive packets over UDP
EthernetUDP Udp;
// for refresh time day
const unsigned long DISPLAY_INTERVAL_day = 86400000; // wait for 1 day
static unsigned long lastTime_day=0; // in ms
unsigned long time_day=0; // in ms
// DS 1307 Time declarations
typedef enum clock__members
{ clock__MemberDay,
clock__MemberMonth,
clock__MemberYear,
clock__MemberHour,
clock__MemberMinute,
clock__MemberSecond
} clock__member_t;
static void clock__printDatetime();
static RTC_DS1307 clock__rtc;
static DateTime clock__currentTime;
///// SETUP /////
void setup() {
Serial.begin(9600);
Ethernet.begin(mac, ip);
server.begin();
Wire.begin();
// Initialize RTC.
clock__rtc.begin();
delay(10);
// update RTC time with NTP protocol if connected to network
ntpUpdate();
}
///// MAIN PROG /////
void loop(){
clock__currentTime = clock__rtc.now();
clock__printDatetime();
// Update time every day by NTP
time_day=millis();
if (time_day-lastTime_day>DISPLAY_INTERVAL_day) // if at least DISPLAY_INTERVAL ms have passed
{
ntpUpdate(); // update RTC time with NTP protocol
lastTime_day=time_day; // reset timer
}
}
static void clock__printDatetime(){
// Build date string
char date[] = "XX/XX/XXXX";
snprintf
(
date,
strlen(date) + 1,
"%02d/%02d/%04d",
clock__currentTime.day(),
clock__currentTime.month(),
clock__currentTime.year()
);
// Build time string
char time[] = "00:00:00";
snprintf
(
time,strlen(time) + 1,
"%02d:%02d:%02d",
clock__currentTime.hour(),
clock__currentTime.minute(),
clock__currentTime.second()
);
// Print date
lcd.setCursor(3, 0);
lcd.print(date);
// Print time
lcd.setCursor(4, 1);
lcd.print(time);
}
// send an NTP request to the time server at the given address
unsigned long sendNTPpacket(IPAddress& address)
{
// set all bytes in the buffer to 0
memset(pb, 0, 48);
// Initialize values needed to form NTP request
// (see URL above for details on the packets)
pb[0] = 0b11100011; // LI, Version, Mode
pb[1] = 0; // Stratum, or type of clock
pb[2] = 6; // Polling Interval
pb[3] = 0xEC; // Peer Clock Precision
// 8 bytes of zero for Root Delay & Root Dispersion
pb[12] = 49;
pb[13] = 0x4E;
pb[14] = 49;
pb[15] = 52;
// all NTP fields have been given values, now
// you can send a packet requesting a timestamp:
// all NTP fields have been given values, now
// you can send a packet requesting a timestamp:
Udp.beginPacket(address, 123); //NTP requests are to port 123
Udp.write(pb,48);
Udp.endPacket();
}
void ntpUpdate(void)
{
lcd.setCursor(0,0);
lcd.print("NTP Time sync...");
Udp.begin(localPort);
delay(250);
// send an NTP packet to a time server
sendNTPpacket(timeServer);
// wait to see if a reply is available
delay(1000);
if ( Udp.parsePacket() ) {
// read the packet into the buffer
Udp.read(pb, 48);
// NTP contains four timestamps with an integer part and a fraction part
// we only use the integer part here
unsigned long t1, t2, t3, t4;
t1 = t2 = t3 = t4 = 0;
for (int i=0; i< 4; i++)
{
t1 = t1 << 8 | pb[16+i];
t2 = t2 << 8 | pb[24+i];
t3 = t3 << 8 | pb[32+i];
t4 = t4 << 8 | pb[40+i];
}
// part of the fractional part
// could be 4 bytes but this is more precise than the 1307 RTC
// which has a precision of ONE second
// in fact one byte is sufficient for 1307
float f1,f2,f3,f4;
f1 = ((long)pb[20] * 256 + pb[21]) / 65536.0;
f2 = ((long)pb[28] * 256 + pb[29]) / 65536.0;
f3 = ((long)pb[36] * 256 + pb[37]) / 65536.0;
f4 = ((long)pb[44] * 256 + pb[45]) / 65536.0;
//Serial.println(f1);
//Serial.println(f2);
//Serial.println(f3);
//Serial.println(f4);
const unsigned long seventyYears = 2208988800UL;
t1 -= seventyYears;
t2 -= seventyYears;
t3 -= seventyYears;
t4 -= seventyYears;
//Serial.println("T1 .. T4 && fractional parts");
//PrintDateTime(DateTime(t1)); Serial.println(f1,4);
//PrintDateTime(DateTime(t2)); Serial.println(f2,4);
//PrintDateTime(DateTime(t3)); Serial.println(f3,4);
//PrintDateTime(DateTime(t4)); Serial.println(f4,4);
//Serial.println();
// Adjust timezone and DST... in my case substract 4 hours for Chile Time
// or work in UTC?
t4 += adjustDstEurope(t4); // Adjustig Time with DST Europe/France: UTC+1h in winter, UTC+2h in summer
t4 += 1; // adjust the delay(1000) lost at begin of loop
if (f4 > 0.4) t4++; // adjust fractional part, see above
clock__rtc.adjust(DateTime(t4)); // update RTC DS 1307 Clock
lcd.setCursor(0,0);
lcd.print("NTP sync OK! ");
delay(2000);
lcd.clear();
}
else
{
lcd.setCursor(0,0);
lcd.print("NTP sync not OK!");
delay(2000);
lcd.clear();
}
}
int adjustDstEurope(DateTime t)
{
/*You can use the following equations to calculate when DST starts and ends.
The divisions are integer divisions, in which remainders are discarded.
"mod" means the remainder when doing integer division, e.g., 20 mod 7 = 6.
That is, 20 divided by 7 is 2 and 6/7th (where six is the remainder).
With: y = year.
For the United States:
Begin DST: Sunday April (2+6*y-y/4) mod 7+1
End DST: Sunday October (31-(y*5/4+1) mod 7)
Valid for years 1900 to 2006, though DST wasn't adopted until the 1950s-1960s. 2007 and after:
Begin DST: Sunday March 14 - (1 + y*5/4) mod 7
End DST: Sunday November 7 - (1 + y*5/4) mod 7;
European Economic Community:
Begin DST: Sunday March (31 - (5*y/4 + 4) mod 7) at 1h U.T.
End DST: Sunday October (31 - (5*y/4 + 1) mod 7) at 1h U.T.
Since 1996, valid through 2099
(Equations by Wei-Hwa Huang (US), and Robert H. van Gent (EC))
Adjustig Time with DST Europe/France/Paris: UTC+1h in winter, UTC+2h in summer
*/
// last sunday of march
int beginDSTDate= (31 - (5* t.year() /4 + 4) % 7);
//Serial.println(beginDSTDate);
int beginDSTMonth=3;
//last sunday of october
int endDSTDate= (31 - (5 * t.year() /4 + 1) % 7);
//Serial.println(endDSTDate);
int endDSTMonth=10;
// DST is valid as:
if (((t.month() > beginDSTMonth) && (t.month() < endDSTMonth))
|| ((t.month() == beginDSTMonth) && (t.day() >= beginDSTDate))
|| ((t.month() == endDSTMonth) && (t.day() <= endDSTDate)))
return 7200; // DST europe = utc +2 hour (summer time)
else return 3600; // nonDST europe = utc +1 hour (winter time)
}
Avec gestion heure d'été, heure d'hiver