WiFi UDP NTP Client
#include <>
Hardware Required Circuit Schematic Code
Ethernet Shield Network Time Protocol (NTP) Client
Query a Network Time Protocol (NTP) server using UDP.
AUTHOR: Arduino

LAST REVISION: 10/05/2022, 08:00 AM

Tutorials > Examples > Ethernet > UdpNtpClient
In this example, you will use your Ethernet Shield and your Arduino to query a 
Network Time Protocol (NTP) server. This way, your Arduino can get the time from
the Internet.



Hardware Required
Arduino Board Arduino Ethernet Shield
Circuit
The Ethernet shield allows you to connect a WIZNet Ethernet controller to the Arduino boards via the SPI bus. It uses the ICSP header pins and pin 10 as chip select for the SPI connection to the Ethernet controller chip. Later models of the Ethernet shield also have an SD Card on board. Digital pin 4 is used to control the chip select pin on the SD card. The shield should be connected to a network with an Ethernet cable. You will need to change the network settings in the program to correspond to your network.
The circuit for this tutorial
The circuit for this tutorial. Image developed using Fritzing. For more circuit examples, see the Fritzing project page In the above image, the Arduino board would be stacked below the Ethernet shield.
Schematic
The schematic for this tutorial.
Code
/*H******************************************************* 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 #include #include //************************* DEFINES ************************************ //************************* PROTOTYPES ************************************ void sendNTPpacket( const char *address); //************************* VARIABLES ************************************ // ENTER A MAC ADDRESS FOR 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 const char timeServer[] = "time.nist.gov"; // time.nist.gov NTP SERVER const int NTP_PACKET_SIZE = 48; // NTP TIME STAMP IS IN MSG 1st 48 BYTES byte packetBuffer[NTP_PACKET_SIZE]; // INCOMING AND OUTGOING PACKET BUFFER // A UDP INSTANCE TO SEND AND RECEIVE PACKETS OVER UDP EthernetUDP Udp; /*F******************************************************************** * **********************************************************************/ void setup() { // USE Ethernet.init( pin ) TO CONFIGURE CS PIN //Ethernet.init(10); // MOST ARDUINO SHIELDS //Ethernet.init(5); // MKR ETH SHIELD //Ethernet.init(0); // Teensy 2.0 //Ethernet.init(20); // Teensy++ 2.0 //Ethernet.init(15); // ESP8266 WITH aDAFRUIT FEATHERWING ETHERNET //Ethernet.init(33); // ESP32 WITH Adafruit FEATHERWING ETHERNEt Serial.begin( BAUD ); // OPEN SERIAL COMM & WAIT FOR PORT TO OPEN 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" ); if( Ethernet.hardwareStatus() == EthernetNoHardware ) // CHECK HDW Serial.println( "Ethernet shield was not found."); else if( Ethernet.linkStatus() == LinkOFF ) Serial.println( "Ethernet cable is not connected." ); while( true ) delay( 1 ); // NO POINT IN CARRYING ON, SO DO NOTHING FOREVERMORE } Udp.begin( localPort ); } /*F******************************************************************** * **********************************************************************/ void loop() { sendNTPpacket( timeServer ); // SEND AN NTP PACKET TO A TIME SERVER delay( 1000 ); // WAIT FOR REPLY IS AVAILABLE if( Udp.parsePacket()) { // RECEIVED A PACKET, READ IT'S DATA Udp.read( packetBuffer, NTP_PACKET_SIZE); // READ PACKET INTO BUFFER // TIMESTAMP STARTS AT BYTE 40 OF THE RECEIVED PACKET AND IS FOUR BYTES, // OR TWO WORDS, LONG. fIRST, EXTRACT TWO WORDS unsigned long highWord = word( packetBuffer[40], packetBuffer[41]); unsigned long lowWord = word( packetBuffer[42], packetBuffer[43]); // COMBINE 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 ); // CONVERT NTP TIME INTO EVERYDAY TIME: Serial.print( "Unix time = " ); // UNIX TIME STARTS ON jAN 1 1970. SECONDS: 2208988800 const unsigned long seventyYears = 2208988800UL; unsigned long epoch = secsSince1900 - seventyYears; // SUBTRACT 70 YEARS // PRINT uNIX TIME Serial.println( epoch ); // PRINT HOUR, MINUTE AND SECOND Serial.print( "The UTC time is ");// UTC TIME GREENWICH MERIDIAN (GMT) Serial.print( (epoch % 86400L) / 3600); // PRINT HOUR (86400 EQUALS SECS PER DAY) Serial.print( ':' ); if( ((epoch % 3600) / 60) < 10) Serial.print( '0' ); // ADD LEADIG ZRO Serial.print( (epoch % 3600) / 60 ); // PRINT MINUTE (3600 EQUALS SECS PER MINUTE) Serial.print( ':' ); if( (epoch % 60) < 10 ) Serial.print( '0' ); // FIX LEADING ZRO Serial.println( epoch % 60 ); // PRINT SECOND } delay( 10000 ); // WAIT TEN SECONDS BEFORE ASKING FOR TIME AGAIN Ethernet.maintain(); } /*F******************************************************************** * SEND AN NTP REQUEST TO TIME SERVER AT GIVEN ADDRESS **********************************************************************/ void sendNTPpacket( const char *address) { memset( packetBuffer, 0, NTP_PACKET_SIZE ); // CLEAR RCV BUFF // INIT VALUES NEEDED TO FORM NTP REQUESt // (SEE URL ABOVE FOR DETAILS ON 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 packetBuffer[12] = 49; // 8 BYTES OF ZERO FOR ROOT DELAY & ROOT DISPERSION packetBuffer[13] = 0x4E; packetBuffer[14] = 49; packetBuffer[15] = 52; // ALL NTP FIELDS POPULATED 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(); }