Difference between revisions of "Arduino: Ethernet NTP dapatkan waktu"

From OnnoWiki
Jump to navigation Jump to search
 
Line 3: Line 3:
 
==Code==
 
==Code==
  
 +
// NTP time issue
 +
// IDE 1.0.3
 +
// DHCP Server required
 +
// Arduino Mega2560 + Ethernetshield for Mega with SD-slot
 +
 +
#include <MsTimer2.h>
 
  #include <Time.h>
 
  #include <Time.h>
 
  #include <SPI.h>
 
  #include <SPI.h>
 
  #include <Ethernet.h>
 
  #include <Ethernet.h>
  #include <Udp.h>
+
  #include <EthernetUdp.h>
 
   
 
   
  byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
+
  #define SD_CS 4
byte ip[] = {  192, 168, 1, 44 }; // set the IP address to an unused address on your network
 
 
   
 
   
  unsigned int localPort = 8888; // local port to listen for UDP packets
+
  // Ethernet library configuration
 +
byte mac[] = { 0x24, 0x7B, 0xA2, 0x4A, 0x52, 0x10 };
 +
IPAddress timeServer(203, 89, 25, 6) ;
 
   
 
   
  byte timeServer[]  = { 192, 43, 244, 18}; // time.nist.gov
+
/* ALTER THESE VARIABLES AT YOUR OWN RISK */
 +
// local port to listen for UDP packets
 +
unsigned int localPort = 8888;
 +
// NTP time stamp is in the first 48 bytes of the message
 +
const int NTP_PACKET_SIZE= 48;   
 +
// Buffer to hold incoming and outgoing packets
 +
  byte packetBuffer[NTP_PACKET_SIZE];
 +
  // A UDP instance to let us send and receive packets over UDP
 +
EthernetUDP Udp;                 
 
   
 
   
  const int NTP_PACKET_SIZE= 48; // NTP time stamp is in the first 48 bytes of the message
+
  boolean s_flag = false;
 
   
 
   
  byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets
+
  void setup() {             
 
   
 
   
time_t prevDisplay = 0; // when the digital clock was displayed
+
  // disable SD SPI Chip Select
 +
  pinMode(SD_CS,OUTPUT);
 
   
 
   
  void digitalClockDisplay();
+
  Serial.begin(9600);
void printDigits(int digits);
+
  Serial.println("Wait for DHCP Server");
 +
  if (Ethernet.begin(mac) == 0) { // start Ethernet by DHCP conf.
 +
    Serial.println("DHCP config failed! ");
 +
  }
 +
  Serial.print("NTP Server: ");
 +
  Serial.println(timeServer);
 
   
 
   
unsigned long getNtpTime();
+
  setSyncInterval(5); // Set seconds between re-sync (5s for test only)
unsigned long sendNTPpacket(byte *address);
 
 
void setup()
 
{
 
// start Ethernet and UDP
 
Ethernet.begin(mac,ip);
 
Udp.begin(localPort);
 
Serial.begin(9600);
 
Serial.println("waiting for sync");
 
 
   
 
   
setSyncInterval(15); // sync every 15 seconds
+
  Udp.begin(localPort);
setSyncProvider(getNtpTime);
+
  Serial.print("Time: ");
 +
  Serial.println(getNtpTime());
 +
  Serial.print("Time Status before setSyncProvider:");
 +
  Serial.println(timeStatus());
 +
  setSyncProvider(getNtpTime);
 +
  Serial.print("Time Status after setSyncProvider:");
 +
  Serial.println(timeStatus());  
 
   
 
   
while(timeStatus()== timeNotSet)
+
  while(timeStatus()== timeNotSet)
; // wait until the time is set by the sync provider
+
      ; // wait until the time is set by the sync provider
 
   
 
   
Serial.println("Sync successfully");
+
  MsTimer2::set(1000, update1s); // 1s period
 +
  MsTimer2::start();
 
  }
 
  }
 +
 
 +
void loop() {
 
   
 
   
void loop()
+
  if (s_flag){
{
+
    s_flag=false;  
+
    digitalClockDisplay();
if( now() != prevDisplay) //update the display only if the time has changed
+
  }
{
+
}
prevDisplay = now();
+
 
digitalClockDisplay();
+
 
}
+
void update1s(){
 +
// 1s is over flag
 +
  s_flag=true;
 
  }
 
  }
 +
 +
void digitalClockDisplay(){
 +
  // digital clock display of the time
 +
  Serial.print(day());
 +
  Serial.print(".");
 +
  Serial.print(month());
 +
  Serial.print(".");
 +
  Serial.print(year());
 +
  Serial.print(" ");
 +
  Serial.print(hour());
 +
  printDigits(minute());
 +
  printDigits(second());
 +
  Serial.println(" ");
 
   
 
   
void digitalClockDisplay(){
+
  if (minute()>0&&minute()<15) Serial.print(" 15 menit");
// digital clock display of the time
+
  if (minute()>15&&minute()<30) Serial.print(" 30 menit");
Serial.print(hour());
+
  if (minute()>30&&minute()<45) Serial.print(" 45 menit");
printDigits(minute());
+
  if (minute()>45&&minute()<60) Serial.print(" 60 menit");
printDigits(second());
 
Serial.print(" ");
 
Serial.print(year());
 
Serial.print("-");
 
Serial.print(month());
 
Serial.print("-");
 
Serial.print(day());
 
Serial.println();
 
 
  }
 
  }
 
   
 
   
 
  void printDigits(int digits){
 
  void printDigits(int digits){
// utility function for digital clock display: prints preceding colon and leading 0
+
  // utility function for digital clock display: prints preceding
Serial.print(":");
+
  // colon and leading 0
if(digits < 10)
+
  Serial.print(":");
Serial.print('0');
+
  if(digits < 10)
Serial.print(digits);
+
    Serial.print('0');
 +
  Serial.print(digits);
 
  }
 
  }
 
   
 
   
  /*-------- NTP code ----------*/
+
  /*-------- NTP code ----------*/  
 
   
 
   
 
  unsigned long getNtpTime()
 
  unsigned long getNtpTime()
 
  {
 
  {
Serial.println("Sending time sync request to NTP server.");
+
  sendNTPpacket(timeServer); // send an NTP packet to a time server
sendNTPpacket(timeServer); // send an NTP packet to a time server
+
    delay(500);
 +
   
 +
    if ( Udp.parsePacket() ) {
 +
      Udp.read(packetBuffer,NTP_PACKET_SIZE);  // read packet into buffer
 
   
 
   
unsigned long startMillis = millis();
+
      //the timestamp starts at byte 40, convert four bytes into a long integer
int tryCounter = 1;
+
      unsigned long hi = word(packetBuffer[40], packetBuffer[41]);
while( millis() - startMillis < 1000)  // wait up to one second for the response
+
      unsigned long low = word(packetBuffer[42], packetBuffer[43]);
{  // wait to see if a reply is available
+
      // this is NTP time (seconds since Jan 1 1900
if ( Udp.available() )
+
      unsigned long secsSince1900 = hi << 16 | low;  
{
+
      // Unix time starts on Jan 1 1970
Udp.readPacket(packetBuffer,NTP_PACKET_SIZE);  // read the packet into the buffer
+
      const unsigned long seventyYears = 2208988800UL;    
+
      unsigned long epoch = secsSince1900 - seventyYears;  // subtract 70 years, add Daylight Saving and Timezone adjust
//the timestamp starts at byte 40 of the received packet and is four bytes,
+
      return epoch;
// or two words, long. First, esxtract the two words:
+
  }
unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
+
  return 0; // return 0 if unable to get the time
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;
 
// now convert NTP time into Arduino Time format:
 
// Time starts on Jan 1 1970. In seconds, that's 2208988800:
 
const unsigned long seventyYears = 2208988800UL;
 
// subtract seventy years:
 
unsigned long epoch = secsSince1900 - seventyYears;
 
 
Serial.println("Time sync successfully.");
 
   
 
return epoch;
 
}
 
 
Serial.print("No date data available. Try counter: .");
 
Serial.println(tryCounter++);
 
delay(100);
 
}
 
 
Serial.println("Time sync failed.");
 
 
return 0;   // return 0 if unable to get the time
 
  }  
 
 
   
 
   
 
  // send an NTP request to the time server at the given address
 
  // send an NTP request to the time server at the given address
  unsigned long sendNTPpacket(byte *address)
+
  unsigned long sendNTPpacket(IPAddress& address)
 +
//sendNTPpacket(IPAddress address)
 
  {
 
  {
// set all bytes in the buffer to 0
+
  memset(packetBuffer, 0, NTP_PACKET_SIZE); // 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
+
  // Initialize values needed to form NTP request
// you can send a packet requesting a timestamp:
+
  packetBuffer[0] = B11100011;  // LI, Version, Mode
Udp.sendPacket( packetBuffer,NTP_PACKET_SIZE,  address, 123); //NTP requests are to port 123
+
  packetBuffer[1] = 0;    // Stratum
  }
+
  packetBuffer[2] = 6;    // Max Interval between messages in seconds
 
+
  packetBuffer[3] = 0xEC;  // Clock Precision
 
+
  // bytes 4 - 11 are for Root Delay and Dispersion and were set to 0 by memset
 +
  packetBuffer[12]  = 49;  // four-byte reference ID identifying
 +
  packetBuffer[13]  = 0x4E;
 +
  packetBuffer[14]  = 49;
 +
  packetBuffer[15]  = 52;
 +
 +
  // send the packet requesting a timestamp:
 +
  Udp.beginPacket(address, 123); //NTP requests are to port 123
 +
  Udp.write(packetBuffer,NTP_PACKET_SIZE);
 +
  Udp.endPacket();
 +
  }
  
 
==Referensi==
 
==Referensi==
  
 
* http://forum.arduino.cc/index.php?topic=58915.0
 
* http://forum.arduino.cc/index.php?topic=58915.0

Latest revision as of 18:39, 28 May 2018

Sumber: http://forum.arduino.cc/index.php?topic=58915.0

Code

// NTP time issue
// IDE 1.0.3
// DHCP Server required
// Arduino Mega2560 + Ethernetshield for Mega with SD-slot

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

#define SD_CS 4

// Ethernet library configuration
byte mac[] = { 0x24, 0x7B, 0xA2, 0x4A, 0x52, 0x10 };
IPAddress timeServer(203, 89, 25, 6) ;

/* ALTER THESE VARIABLES AT YOUR OWN RISK */
// local port to listen for UDP packets
unsigned int localPort = 8888;
// NTP time stamp is in the first 48 bytes of the message
const int NTP_PACKET_SIZE= 48;     
// Buffer to hold incoming and outgoing packets
byte packetBuffer[NTP_PACKET_SIZE]; 
// A UDP instance to let us send and receive packets over UDP
EthernetUDP Udp;                   

boolean s_flag = false;

void setup() {               

  // disable SD SPI Chip Select
  pinMode(SD_CS,OUTPUT);

  Serial.begin(9600);
  Serial.println("Wait for DHCP Server");
  if (Ethernet.begin(mac) == 0) {  // start Ethernet by DHCP conf.
    Serial.println("DHCP config failed! ");
  }
  Serial.print("NTP Server: ");
  Serial.println(timeServer);

  setSyncInterval(5); // Set seconds between re-sync (5s for test only)

  Udp.begin(localPort);
  Serial.print("Time: ");
  Serial.println(getNtpTime());
  Serial.print("Time Status before setSyncProvider:");
  Serial.println(timeStatus());
  setSyncProvider(getNtpTime);
  Serial.print("Time Status after setSyncProvider:");
  Serial.println(timeStatus()); 

  while(timeStatus()== timeNotSet)
     ; // wait until the time is set by the sync provider

  MsTimer2::set(1000, update1s); // 1s period
  MsTimer2::start();
}
 
void loop() {

  if (s_flag){
    s_flag=false; 
    digitalClockDisplay();
  }
} 


void update1s(){
// 1s is over flag
  s_flag=true;
}
void digitalClockDisplay(){
  // digital clock display of the time
  Serial.print(day());
  Serial.print(".");
  Serial.print(month());
  Serial.print(".");
  Serial.print(year());
  Serial.print(" ");
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.println(" ");

  if (minute()>0&&minute()<15) Serial.print(" 15 menit");
  if (minute()>15&&minute()<30) Serial.print(" 30 menit");
  if (minute()>30&&minute()<45) Serial.print(" 45 menit");
  if (minute()>45&&minute()<60) Serial.print(" 60 menit");
}

void printDigits(int digits){
  // utility function for digital clock display: prints preceding
  // colon and leading 0
  Serial.print(":");
  if(digits < 10)
    Serial.print('0');
  Serial.print(digits);
}

/*-------- NTP code ----------*/ 

unsigned long getNtpTime()
{
  sendNTPpacket(timeServer); // send an NTP packet to a time server
    delay(500);
   
    if ( Udp.parsePacket() ) {
     Udp.read(packetBuffer,NTP_PACKET_SIZE);  // read packet into buffer 

     //the timestamp starts at byte 40, convert four bytes into a long integer
     unsigned long hi = word(packetBuffer[40], packetBuffer[41]);
     unsigned long low = word(packetBuffer[42], packetBuffer[43]);
     // this is NTP time (seconds since Jan 1 1900
     unsigned long secsSince1900 = hi << 16 | low; 
     // Unix time starts on Jan 1 1970
     const unsigned long seventyYears = 2208988800UL;     
     unsigned long epoch = secsSince1900 - seventyYears;  // subtract 70 years, add Daylight Saving and Timezone adjust
     return epoch;
  }
  return 0; // return 0 if unable to get the time
}

// send an NTP request to the time server at the given address
unsigned long sendNTPpacket(IPAddress& address)
//sendNTPpacket(IPAddress address)
{
  memset(packetBuffer, 0, NTP_PACKET_SIZE);  // set all bytes in the buffer to 0

  // Initialize values needed to form NTP request
  packetBuffer[0] = B11100011;   // LI, Version, Mode
  packetBuffer[1] = 0;     // Stratum
  packetBuffer[2] = 6;     // Max Interval between messages in seconds
  packetBuffer[3] = 0xEC;  // Clock Precision
  // bytes 4 - 11 are for Root Delay and Dispersion and were set to 0 by memset
  packetBuffer[12]  = 49;  // four-byte reference ID identifying
  packetBuffer[13]  = 0x4E;
  packetBuffer[14]  = 49;
  packetBuffer[15]  = 52;

  // send the packet requesting a timestamp:
  Udp.beginPacket(address, 123); //NTP requests are to port 123
  Udp.write(packetBuffer,NTP_PACKET_SIZE);
  Udp.endPacket();
}

Referensi