WiFi UDP NTP Client
#include <>
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();
}