Wiznet makers

gavinchang

Published January 02, 2024 ©

53 UCC

25 WCC

60 VAR

0 Contests

3 Followers

0 Following

Original Link

Wiring the WIZNET W5100/W5500 as Network Time Protocol Client with Microcontroller

Wiring the WIZNET W5100/W5500 as Network Time Protocol Client with Microcontroller

COMPONENTS Hardware components

WIZnet - W5500

x 1


PROJECT DESCRIPTION

NTP (Network Time Protocol) is a networking protocol for clock synchronization between computer over packet switches, variable-latency data networks. NTP is one of the oldest IP in current used, this technology was designed by David Mills at the University of Delaware. NTP is intended to synchronize all participating computers within milliseconds of coordinated UTC (Universal Time Coordinated) it uses the intersection algorithm to select accurate time servers mitigated the effect of variable network latency. For more reading please refer to this link.

On this illustration guide we will going to wire the WIZNET W5100 module to run as NTP server client and act as your local area network time server provider sync from pool.ntp.org. you can also use the WIZNET W5500 & W5300 for this project. However some projects are more sophisticated because does not required an internet connection to get a time service from NTP provider, there are GPS that support as a time provider and this GPS are connected via satellite like the GTPA013 / FGPMMOPA6H. The GTPA013 can log GPS data ( UTC, Latitude , longitude, Valid ,Checksum ) suitable for building a NTP (stratum-1) server as standalone and can easily hookup to your ESP, SBC, Embedded Systems or any devices that supports serial communication / data networks / internetwork protocol & sync into the servers and routers if you want to know more about GTPA013 click here & for further readings about WIZNET W5XXX refer to this link.

Required Components

  • Arduino IDE | Atmel Studio | Energia | Processing
  • Arduino PRO, FIO, NANO, UNO, MINI, MEGA, PRO MINI, LEO, BT, DUE, ETHERNET,LILYPAD, NodeMCU, Teensy Board, TeensyDuino, ESP8266 12, 12E, ESP32, LinkItOne, ESP8266 NodeMCU, ESPDuino, ATMEGA328 16/12, ATMEGA32u4 16/8/ MHz, ESP8266, MSP430 ,ATMEGA250 16 MHz, ATSAM3x8E,  Note: The Diagram below is using NANO. (please refer to each MCU’s respective pin-outs & bus configurations)
  • Wiznet W5100 / W5500 Module
  • Jumper Wire / DuPont Wire
  • Breadboard

Wiring Guide

Source Code

#include <SPI.h>
#include <Ethernet.h>
#include <Dns.h>
#include <TimeLib.h>  

//#define MODULE  "ENC28J60" //Uncomment if your using ENC28J60
#define MODULE "W5100"

byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; //You can customize your burn-in-address here
unsigned int localPort = 8888;      // local port to listen for UDP packets
IPAddress timeServer;
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 


EthernetUDP Udp; // Set UDP instance to let us send and receive packets over UDP

// dow_char() Return day of week [Sun,Mon,Tue,]
char * dow_char_EN(byte days) {
  char *you[] = {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
  return you[days];
}

// dow_char() Return day letters
char * dow_char_JP(byte days) {
  char *you[] = {"Sunday","Monday","Tuesday","Wenesday","Thursday","Friday","Saturday"};
  return you[days];
}

// dow() Indicating the day of the week [0-Sunday, 1-Monday etc.]
uint8_t dow(unsigned long t) {
    return ((t / 86400) + 4) % 7;
}

void showTime(char * title, time_t timet, char * dow) {
   Serial.print(title);
   Serial.print(year(timet));
   Serial.print("/");
   Serial.print(month(timet));
   Serial.print("/");
   Serial.print(day(timet));
   Serial.print(" ");
   Serial.print(hour(timet));
   Serial.print(":");
   Serial.print(minute(timet));
   Serial.print(":");
   Serial.print(second(timet));
   Serial.print(" [");
   Serial.print(dow);
   Serial.println("]");
}
void setup() 
{
  delay(1000);
  Serial.begin(9600);
  if (!Ethernet.begin(mac) ) {
    Serial.println("Failed to configure Ethernet using DHCP");
    for(;;)
      ;
  }

  DNSClient dns;
  dns.begin(Ethernet.dnsServerIP());
//  if(dns.getHostByName("africa.pool.ntp.org",timeServer) == 1) {

    /*
    LIST OF SNTP Server
    time.google.com
    africa.pool.ntp.org
	antarctica.pool.ntp.org
	asia.pool.ntp.org
	europe.pool.ntp.org
    north-america.pool.ntp.org
    oceania.pool.ntp.org
    south-america.pool.ntp.org
    */

  if(dns.getHostByName("0.pool.ntp.org",timeServer) == 1) { 
    Serial.print(F("NTP = "));
    Serial.println(timeServer);
  } else {
    Serial.print(F("DNS lookup failed"));
    while(1) { }
  }
    
  Udp.begin(localPort);
}

void loop()
{
  sendNTPpacket(timeServer); // send an NTP packet to a time server
  if ( Udp.parsePacket() ) {  
    Serial.print("\n[NTP Client :");
    Serial.print(MODULE);
    Serial.println("]");
    Udp.read(packetBuffer,NTP_PACKET_SIZE);  // read the packet into the buffer
    unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
    unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);  
    unsigned long secsSince1900 = highWord << 16 | lowWord;  
    Serial.print("Seconds since Jan 1 1900 = " );
    Serial.println(secsSince1900);               
    // now convert NTP time into everyday 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.print("Unix time = ");
    Serial.println(epoch);                               

#if 0
    // print the hour, minute and second:
    Serial.print("The UTC time is ");       // UTC is the time at Greenwich Meridian (GMT)
    Serial.print((epoch  % 86400L) / 3600); // print the hour (86400 equals secs per day)
    Serial.print(':');  
    if ( ((epoch % 3600) / 60) < 10 ) {
      // In the first 10 minutes of each hour, we'll want a leading '0'
      Serial.print('0');
    }
    Serial.print((epoch  % 3600) / 60); // print the minute (3600 equals secs per minute)
    Serial.print(':'); 
    if ( (epoch % 60) < 10 ) {
      // In the first 10 seconds of each minute, we'll want a leading '0'
      Serial.print('0');
    }
    Serial.println(epoch %60); // print the second
#endif
    uint8_t DayOfWeek = dow(epoch); 
    showTime("The UTC time: ", epoch, dow_char_EN(DayOfWeek));
    DayOfWeek = dow(epoch + (9 * 60 * 60));
    showTime("The JST time: ", epoch + (9 * 60 * 60), dow_char_JP(DayOfWeek));
    
  } else {
    Serial.println("Waiting packets...");
  }
  delay(10000); 
}
unsigned long sendNTPpacket(IPAddress& address) //Sending RQ to NTP time server 
{
  memset(packetBuffer, 0, NTP_PACKET_SIZE);    // Set all buffer turn 0
  packetBuffer[0] = 0b11100011;   //Set LI, Version, Mode
  packetBuffer[1] = 0;     //Set Stratum, or type of clock
  packetBuffer[2] = 6;     //Set Polling Interval
  packetBuffer[3] = 0xEC;  //Set Peer Clock Precision
  
  //Set to 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 running at port 123
  Udp.write(packetBuffer,NTP_PACKET_SIZE);
  Udp.endPacket(); 
}


Downloads

Documents
Comments Write