root / arduino-1.0 / libraries / Ethernet / examples / UdpNtpClient / UdpNtpClient.ino @ 58d82c77
History | View | Annotate | Download (4.17 KB)
1 | 58d82c77 | Tom Mullins | /* |
---|---|---|---|
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 |