Hi,
i want to add a regular ntp sync to my uno or nano.
I used a ens28j60 module from ebay and tried already with standard ethernet.h library.
now i switched to latest uipethernet.h and have the same problem.
The uno/nano received a ip adres from dhcp so that no problem.
i retrieved a function from internet to get epoch in seconds from ntp server.
The first sync is working perfectly.
But regardless how many time later of second sync, the epoch number is only added by +1 or +2 ......
So after a while the clock of course is going backwards.
I have not a black hole in the neighborhood.....
Also when i unplug the network-cable sync function still gives a TRUE for a couple of attemps .... weird.
In the past i used the function only in setup() once, so it was not a problem, but now i want to sync each hour ....
Can somebody see what i'm doing wrong?
#include <UIPEthernet.h>
byte mac[6] = {0x74,0x69,0x69,0x93,0x30,0x34};
unsigned int localPort = 8888; // local port to listen for UDP packets
//IPAddress timeServer(192, 43, 244, 18); // time.nist.gov NTP server
IPAddress timeServer(193,204,114,232);
//IPAddress timeServer(129,6,15,28);
//IPAddress timeServer{194,109,6,2}; //ntp.xs4all.nl
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
// A UDP instance to let us send and receive packets over UDP
EthernetUDP Udp;
uint16_t timeZone = 3600;
boolean lastsync = false;
void setup() {
// put your setup code here, to run once:
Serial.begin (9600);
delay(2000);
Serial.println();
Serial.println();
Serial.println("IP/NTP test.");
if(Ethernet.begin(mac)) {
Serial.print("DHCP ...");
Serial.print("localIP: ");
Serial.println(Ethernet.localIP());
Serial.print("subnetMask: ");
Serial.println(Ethernet.subnetMask());
Serial.print("gatewayIP: ");
Serial.println(Ethernet.gatewayIP());
Serial.print("dnsServerIP: ");
Serial.println(Ethernet.dnsServerIP());
} else {
Serial.println("DHCP Failed.");
}
Udp.begin(localPort);
Serial.println("Setup ready");
}
void loop() {
if (!lastsync) {
if (unsigned long t = ntpSync()){
if (adjustDstEurope(t)) {timeZone = 7200;} else {timeZone = 3600;}
if (t) {setTime(t+timeZone);}
Serial.println(F("Synced now."));
lastsync = true;
} else {
Serial.println(F("Synced failed."));
lastsync = false;
}
}
//Sync every minute (change to minute() to sync every hour.
if (second() == 0) {lastsync = false;}
Serial.println(hour());
Serial.println(minute());
Serial.println(second());
Serial.println();
// wait ten seconds before asking for the time again
delay(10000);
}
unsigned long ntpSync()
{
sendNTPpacket(timeServer); // send an NTP packet to a time server
// wait to see if a reply is available
delay(1000);
int cb = Udp.parsePacket();
if (cb) {
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, esxtract 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):
unsigned long secsSince1900 = highWord << 16 | lowWord;
//Serial.print("Seconds since Jan 1 1900 = " );
//Serial.println(secsSince1900);
// now convert NTP time into everyday time:
//Serial.print("Unix time = ");
// Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
const unsigned long seventyYears = 2208988800UL;
// subtract seventy years:
unsigned long epoch = secsSince1900 - seventyYears;
//print Unix time:
//Serial.println(epoch);
return epoch;
} else {
//Serial.println("no packet yet");
return false;
}
}
// 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
//Serial.print(".");
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(address, 123); //NTP requests are to port 123
Udp.write(packetBuffer,NTP_PACKET_SIZE);
Udp.endPacket();
}
boolean adjustDstEurope(long epoch2)
{
// last sunday of march
int beginDSTDate= (31 - (5* year(epoch2) /4 + 4) % 7);
int beginDSTMonth=3;
//last sunday of october
int endDSTDate= (31 - (5 * year(epoch2) /4 + 1) % 7);
int endDSTMonth=10;
// DST is valid as:
if (((month(epoch2) > beginDSTMonth) && (month(epoch2) < endDSTMonth))
|| ((month(epoch2) == beginDSTMonth) && (day(epoch2) >= beginDSTDate))
|| ((month(epoch2) == endDSTMonth) && (day(epoch2) < endDSTDate)))
return true; // DST europe = GMT +2
else return false; // nonDST europe = GMT +1
}
I think i have it solved, will test it for a night .....
instead of fixed ntp ip adress i resove dnd of time.nist.gov ......
It's looking promising now .......