root / arduino-1.0 / libraries / Ethernet / examples / UdpNtpClient / UdpNtpClient.ino @ 58d82c77
History | View | Annotate | Download (4.17 KB)
1 |
/* |
---|---|
2 |
|
3 |
Udp NTP Client |
4 |
|
5 |
Get the time from a Network Time Protocol (NTP) time server |
6 |
Demonstrates use of UDP sendPacket and ReceivePacket |
7 |
For more on NTP time servers and the messages needed to communicate with them, |
8 |
see http://en.wikipedia.org/wiki/Network_Time_Protocol |
9 |
|
10 |
created 4 Sep 2010 |
11 |
by Michael Margolis |
12 |
modified 17 Sep 2010 |
13 |
by Tom Igoe |
14 |
|
15 |
This code is in the public domain. |
16 |
|
17 |
*/ |
18 |
|
19 |
#include <SPI.h> |
20 |
#include <Ethernet.h> |
21 |
#include <EthernetUdp.h> |
22 |
|
23 |
// Enter a MAC address for your controller below. |
24 |
// Newer Ethernet shields have a MAC address printed on a sticker on the shield |
25 |
byte mac[] = { |
26 |
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; |
27 |
|
28 |
unsigned int localPort = 8888; // local port to listen for UDP packets |
29 |
|
30 |
IPAddress timeServer(192, 43, 244, 18); // time.nist.gov NTP server |
31 |
|
32 |
const int NTP_PACKET_SIZE= 48; // NTP time stamp is in the first 48 bytes of the message |
33 |
|
34 |
byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets |
35 |
|
36 |
// A UDP instance to let us send and receive packets over UDP |
37 |
EthernetUDP Udp; |
38 |
|
39 |
void setup() |
40 |
{ |
41 |
Serial.begin(9600); |
42 |
|
43 |
// start Ethernet and UDP |
44 |
if (Ethernet.begin(mac) == 0) { |
45 |
Serial.println("Failed to configure Ethernet using DHCP"); |
46 |
// no point in carrying on, so do nothing forevermore: |
47 |
for(;;) |
48 |
; |
49 |
} |
50 |
Udp.begin(localPort); |
51 |
} |
52 |
|
53 |
void loop() |
54 |
{ |
55 |
sendNTPpacket(timeServer); // send an NTP packet to a time server |
56 |
|
57 |
// wait to see if a reply is available |
58 |
delay(1000); |
59 |
if ( Udp.parsePacket() ) { |
60 |
// We've received a packet, read the data from it |
61 |
Udp.read(packetBuffer,NTP_PACKET_SIZE); // read the packet into the buffer |
62 |
|
63 |
//the timestamp starts at byte 40 of the received packet and is four bytes, |
64 |
// or two words, long. First, esxtract the two words: |
65 |
|
66 |
unsigned long highWord = word(packetBuffer[40], packetBuffer[41]); |
67 |
unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]); |
68 |
// combine the four bytes (two words) into a long integer |
69 |
// this is NTP time (seconds since Jan 1 1900): |
70 |
unsigned long secsSince1900 = highWord << 16 | lowWord; |
71 |
Serial.print("Seconds since Jan 1 1900 = " ); |
72 |
Serial.println(secsSince1900); |
73 |
|
74 |
// now convert NTP time into everyday time: |
75 |
Serial.print("Unix time = "); |
76 |
// Unix time starts on Jan 1 1970. In seconds, that's 2208988800: |
77 |
const unsigned long seventyYears = 2208988800UL; |
78 |
// subtract seventy years: |
79 |
unsigned long epoch = secsSince1900 - seventyYears; |
80 |
// print Unix time: |
81 |
Serial.println(epoch); |
82 |
|
83 |
|
84 |
// print the hour, minute and second: |
85 |
Serial.print("The UTC time is "); // UTC is the time at Greenwich Meridian (GMT) |
86 |
Serial.print((epoch % 86400L) / 3600); // print the hour (86400 equals secs per day) |
87 |
Serial.print(':'); |
88 |
if ( ((epoch % 3600) / 60) < 10 ) { |
89 |
// In the first 10 minutes of each hour, we'll want a leading '0' |
90 |
Serial.print('0'); |
91 |
} |
92 |
Serial.print((epoch % 3600) / 60); // print the minute (3600 equals secs per minute) |
93 |
Serial.print(':'); |
94 |
if ( (epoch % 60) < 10 ) { |
95 |
// In the first 10 seconds of each minute, we'll want a leading '0' |
96 |
Serial.print('0'); |
97 |
} |
98 |
Serial.println(epoch %60); // print the second |
99 |
} |
100 |
// wait ten seconds before asking for the time again |
101 |
delay(10000); |
102 |
} |
103 |
|
104 |
// send an NTP request to the time server at the given address |
105 |
unsigned long sendNTPpacket(IPAddress& address) |
106 |
{ |
107 |
// set all bytes in the buffer to 0 |
108 |
memset(packetBuffer, 0, NTP_PACKET_SIZE); |
109 |
// Initialize values needed to form NTP request |
110 |
// (see URL above for details on the packets) |
111 |
packetBuffer[0] = 0b11100011; // LI, Version, Mode |
112 |
packetBuffer[1] = 0; // Stratum, or type of clock |
113 |
packetBuffer[2] = 6; // Polling Interval |
114 |
packetBuffer[3] = 0xEC; // Peer Clock Precision |
115 |
// 8 bytes of zero for Root Delay & Root Dispersion |
116 |
packetBuffer[12] = 49; |
117 |
packetBuffer[13] = 0x4E; |
118 |
packetBuffer[14] = 49; |
119 |
packetBuffer[15] = 52; |
120 |
|
121 |
// all NTP fields have been given values, now |
122 |
// you can send a packet requesting a timestamp: |
123 |
Udp.beginPacket(address, 123); //NTP requests are to port 123 |
124 |
Udp.write(packetBuffer,NTP_PACKET_SIZE); |
125 |
Udp.endPacket(); |
126 |
} |
127 |
|
128 |
|
129 |
|
130 |
|
131 |
|
132 |
|
133 |
|
134 |
|
135 |
|
136 |
|