Difference between revisions of "Arduino: Ethernet NTP Client"

From OnnoWiki
Jump to navigation Jump to search
Line 13: Line 13:
  
 
==Code Versi Sederhana==
 
==Code Versi Sederhana==
 +
 +
  
 
  /*
 
  /*
 
   
 
   
   Udp NTP Client
+
   Udp NTP Client  
 
   
 
   
 
   Get the time from a Network Time Protocol (NTP) time server
 
   Get the time from a Network Time Protocol (NTP) time server
Line 28: Line 30:
 
   by Tom Igoe
 
   by Tom Igoe
 
   modified 02 Sept 2015
 
   modified 02 Sept 2015
   by Arturo Guadalupi
+
   by Arturo Guadalupi  
 
   
 
   
   This code is in the public domain.  
+
   This code is in the public domain.
 
   
 
   
  */
+
*/
 
   
 
   
 
  #include <SPI.h>
 
  #include <SPI.h>
Line 38: Line 40:
 
  #include <EthernetUdp.h>
 
  #include <EthernetUdp.h>
 
   
 
   
 +
// Enter a MAC address for your controller below.
 +
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
 
  byte mac[] = {
 
  byte mac[] = {
 
   0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
 
   0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
 
  };
 
  };
 +
unsigned int localPort = 8888;      // local port to listen for UDP packets 
 
   
 
   
unsigned int localPort = 8888;      // local port to listen for UDP packets
+
  char timeServer[] = "time.nist.gov"; // id.pool.ntp.org NTP server
  char timeServer[] = "time.nist.gov"; // time.nist.gov NTP server
+
IPAddress remoteIP(132,163,97,1);
 
  const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message
 
  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
 
  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;
 
  EthernetUDP Udp;
 +
 +
// Initialize the Ethernet client library
 +
// with the IP address and port of the server
 +
// that you want to connect to (port 80 is default for HTTP):
 +
EthernetClient client;
 
   
 
   
 
  void setup() {
 
  void setup() {
 
   // Open serial communications and wait for port to open:
 
   // Open serial communications and wait for port to open:
 
   Serial.begin(9600);
 
   Serial.begin(9600);
 +
  // this check is only needed on the Leonardo:
 
   while (!Serial) {
 
   while (!Serial) {
     ; // wait for serial port to connect. Needed for native USB port only
+
     ; // wait for serial port to connect. Needed for native USB port only
   }
+
   }  
 
 
 
   
 
   
   // start Ethernet and UDP
+
   // start the Ethernet connection:
 
   if (Ethernet.begin(mac) == 0) {
 
   if (Ethernet.begin(mac) == 0) {
 
     Serial.println("Failed to configure Ethernet using DHCP");
 
     Serial.println("Failed to configure Ethernet using DHCP");
Line 62: Line 74:
 
     for (;;)
 
     for (;;)
 
       ;
 
       ;
   }
+
    }
 +
   // print your local IP address:
 
   Udp.begin(localPort);
 
   Udp.begin(localPort);
 
  }
 
  }
+
 
 
  void loop() {
 
  void loop() {
   sendNTPpacket(timeServer); // send an NTP packet to a time server
+
   sendNTPpacket(timeServer); // send an NTP packet to a time server
 
   
 
   
 
   // wait to see if a reply is available
 
   // wait to see if a reply is available
Line 73: Line 86:
 
   if (Udp.parsePacket()) {
 
   if (Udp.parsePacket()) {
 
     // We've received a packet, read the data from it
 
     // We've received a packet, read the data from it
     Udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer
+
     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 highWord = word(packetBuffer[40], packetBuffer[41]);
 
     unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
 
     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;
 
     unsigned long secsSince1900 = highWord << 16 | lowWord;
 +
    Serial.print("Seconds since Jan 1 1900 = ");
 +
    Serial.println(secsSince1900);
 
   
 
   
 
     // now convert NTP time into everyday time:
 
     // now convert NTP time into everyday time:
 
     Serial.print("Unix time = ");
 
     Serial.print("Unix time = ");
 +
    // Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
 
     const unsigned long seventyYears = 2208988800UL;
 
     const unsigned long seventyYears = 2208988800UL;
 
     // subtract seventy years:
 
     // subtract seventy years:
 
     unsigned long epoch = secsSince1900 - seventyYears;
 
     unsigned long epoch = secsSince1900 - seventyYears;
 
     // print Unix time:
 
     // print Unix time:
     Serial.println(epoch);
+
     Serial.println(epoch); 
 +
 +
    // 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
 +
  }
 
   // wait ten seconds before asking for the time again
 
   // wait ten seconds before asking for the time again
 
   delay(10000);
 
   delay(10000);
Line 106: Line 143:
 
   packetBuffer[13]  = 0x4E;
 
   packetBuffer[13]  = 0x4E;
 
   packetBuffer[14]  = 49;
 
   packetBuffer[14]  = 49;
   packetBuffer[15]  = 52;
+
   packetBuffer[15]  = 52;
 
   
 
   
 
   // all NTP fields have been given values, now
 
   // all NTP fields have been given values, now
 
   // you can send a packet requesting a timestamp:
 
   // you can send a packet requesting a timestamp:
   Udp.beginPacket(address, 123); //NTP requests are to port 123
+
   Udp.beginPacket(remoteIP, 123); //NTP requests are to port 123
 
   Udp.write(packetBuffer, NTP_PACKET_SIZE);
 
   Udp.write(packetBuffer, NTP_PACKET_SIZE);
 
   Udp.endPacket();
 
   Udp.endPacket();

Revision as of 17:07, 25 May 2018

Sumber: https://www.arduino.cc/en/Tutorial/UdpNtpClient


Dalam contoh ini, kita akan menggunakan Ethernet Shield dan Arduino untuk query Network Time Protocol (NTP) server. Dengan cara ini, Arduiono akan dapat memperoleh waktu / time dari Internet.

Kebutuhan Hardware

  • Arduino atau Genuino Board
  • Arduino Ethernet Shield



Code Versi Sederhana

/*

 Udp NTP Client 

 Get the time from a Network Time Protocol (NTP) time server
 Demonstrates use of UDP sendPacket and ReceivePacket
 For more on NTP time servers and the messages needed to communicate with them,
 see http://en.wikipedia.org/wiki/Network_Time_Protocol

 created 4 Sep 2010
 by Michael Margolis
 modified 9 Apr 2012
 by Tom Igoe
 modified 02 Sept 2015
 by Arturo Guadalupi 

 This code is in the public domain.

*/

#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>

// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
unsigned int localPort = 8888;       // local port to listen for UDP packets  

char timeServer[] = "time.nist.gov"; // id.pool.ntp.org NTP server
IPAddress remoteIP(132,163,97,1);
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;

// Initialize the Ethernet client library
// with the IP address and port of the server
// that you want to connect to (port 80 is default for HTTP):
EthernetClient client; 

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  // this check is only needed on the Leonardo:
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port  only
  } 

  // start the Ethernet connection:
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    for (;;)
      ;
   }
  // print your local IP address:
  Udp.begin(localPort);
}
void loop() {
  sendNTPpacket(timeServer); // send an NTP packet to a time server  

  // wait to see if a reply is available
  delay(1000);
  if (Udp.parsePacket()) {
    // 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):
    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);  

    // 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
  }
  // wait ten seconds before asking for the time again
  delay(10000);
  Ethernet.maintain();
}

// send an NTP request to the time server at the given address
void sendNTPpacket(char* address) {
  // 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(remoteIP, 123); //NTP requests are to port 123
  Udp.write(packetBuffer, NTP_PACKET_SIZE);
  Udp.endPacket();
}

Code

/*

 Udp NTP Client

 Get the time from a Network Time Protocol (NTP) time server
 Demonstrates use of UDP sendPacket and ReceivePacket
 For more on NTP time servers and the messages needed to communicate with them,
 see http://en.wikipedia.org/wiki/Network_Time_Protocol

 created 4 Sep 2010
 by Michael Margolis
 modified 9 Apr 2012
 by Tom Igoe
 modified 02 Sept 2015
 by Arturo Guadalupi

 This code is in the public domain. 

 */

#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>

// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};

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

char timeServer[] = "time.nist.gov"; // time.nist.gov NTP 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

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

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
 

  // start Ethernet and UDP
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    for (;;)
      ;
  }
  Udp.begin(localPort);
}

void loop() {
  sendNTPpacket(timeServer); // send an NTP packet to a time server

  // wait to see if a reply is available
  delay(1000);
  if (Udp.parsePacket()) {
    // 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):
    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);
 

    // 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
  }
  // wait ten seconds before asking for the time again
  delay(10000);
  Ethernet.maintain();
}

// send an NTP request to the time server at the given address
void sendNTPpacket(char* address) {
  // 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(address, 123); //NTP requests are to port 123
  Udp.write(packetBuffer, NTP_PACKET_SIZE);
  Udp.endPacket();
}

Referensi