Wiznet makers

junlee0615

Published September 25, 2025 ©

2 UCC

10 VAR

0 Contests

0 Followers

0 Following

Original Link

Arduino W5500 NTP Client — Get Accurate Time via UDP

Build an Arduino NTP client using the WIZnet W5500 Ethernet Shield to query pool.ntp.org over UDP and display network time.

COMPONENTS Hardware components

Arduino - Arduino Ethernet Shield 2

x 1


Arduino - Arduino Mega 2560

x 1


Monoprice - RJ45 Ethernet Cable

x 1

Software Apps and online services

Arduino - Arduino IDE

x 1


PROJECT DESCRIPTION

Introduction

This project implements a classic Network Time Protocol (NTP) client on Arduino using the WIZnet W5500 Ethernet Shield. By sending a 48‑byte UDP request to an NTP server (e.g., pool.ntp.org) and parsing the response, the sketch retrieves the current Unix time, converts it to human‑readable format, and prints it to the Serial Monitor (or an optional LCD).

WIZnet Product Integration

The W5500 offloads TCP/IP, providing a reliable wired connection with minimal MCU overhead. The shield interfaces via SPI (ICSP header) and exposes RJ45 with link/activity LEDs. Using EthernetUDP, the sketch opens a UDP socket on port 123, transmits a properly formatted NTP packet, and reads the response.

Technical Implementation

Network Setup

DHCP (recommended): Ethernet.begin(mac); then print Ethernet.localIP().

Static IP (optional): Ethernet.begin(mac, ip); (ensure subnet/gateway match your LAN).

For long‑running DHCP, call Ethernet.maintain() periodically.

NTP Basics

Server: pool.ntp.org (or regional pools).

Port: UDP 123.

Packet: 48 bytes; set LI, VN, Mode bits in the first byte; zero the buffer; send.

Response parsing: Extract the Transmit Timestamp (bytes 40–43) → Unix epoch.

Core Sketch Snippets

1) Init & UDP begin

 
#include <Ethernet.h>
#include <EthernetUdp.h>
 
byte mac[] = { 0xDE,0xAD,0xBE,0xEF,0xFE,0xED };
EthernetUDP Udp;
unsigned int localPort = 8888; // any free UDP port
 
void setup(){
Serial.begin(9600);
Ethernet.begin(mac); // or Ethernet.begin(mac, ip)
Udp.begin(localPort);
}

2) Build & send NTP packet

 
const char* ntpServer = "pool.ntp.org";
const int NTP_PACKET_SIZE = 48;
byte packetBuffer[NTP_PACKET_SIZE];
 
void sendNTPpacket(IPAddress& address){
memset(packetBuffer, 0, NTP_PACKET_SIZE);
packetBuffer[0] = 0b11100011; // LI, Version, Mode
// other fields can remain 0 for basic query
Udp.beginPacket(address, 123);
Udp.write(packetBuffer, NTP_PACKET_SIZE);
Udp.endPacket();
}

3) Receive & parse

 
IPAddress timeServerIP;
 
void loop(){
if (Ethernet.hostByName(ntpServer, timeServerIP)) {
sendNTPpacket(timeServerIP);
}
delay(1000);
 
int size = Udp.parsePacket();
if (size >= NTP_PACKET_SIZE) {
Udp.read(packetBuffer, NTP_PACKET_SIZE);
unsigned long high = word(packetBuffer[40], packetBuffer[41]);
unsigned long low = word(packetBuffer[42], packetBuffer[43]);
unsigned long secsSince1900 = (high << 16) | low;
const unsigned long seventyYears = 2208988800UL; // NTP to Unix
unsigned long epoch = secsSince1900 - seventyYears;
Serial.print("Unix time: "); Serial.println(epoch);
}
delay(10000); // poll interval
}

Core Features and Performance

Reliable wired time sync via NTP over UDP (port 123).

DHCP or static IP options for different network environments.

Simple, lightweight packet handling suitable for 8‑bit MCU.

Applications and Use Cases

Time‑stamping data logs (SD/EEPROM/serial).

Scheduling tasks (alarms, timed relays) without RTC hardware.

Classroom demos on UDP and internet time.

Troubleshooting

No response: try another pool region, check router firewall for UDP/123.

DHCP issues: test with static IP; ensure cable/switch link; consider Ethernet.maintain().

Multiple UDP tasks: use separate EthernetUDP instances or manage ports carefully.

Conclusion

With the WIZnet W5500 Ethernet Shield, Arduino can act as a compact, dependable NTP client. The UDP approach is lightweight and fast, making it ideal for wired IoT nodes that need accurate time without an external RTC.

Documents
Comments Write