---
title: "Arduino W5500 NTP Client — Get Accurate Time via UDP"
url: "https://maker.wiznet.io/junlee0615/projects/arduino-w5500-ntp-client--get-accurate-time-via-udp/"
markdown_url: "https://maker.wiznet.io/junlee0615/projects/arduino-w5500-ntp-client--get-accurate-time-via-udp/md"
type: "UCC: User Created Content"
author: "Arduino"
author_url: "https://docs.arduino.cc/tutorials/ethernet-shield-rev2/udp-ntp-client/"
editor: "WIZnet"
editor_url: "https://maker.wiznet.io/"
original_author: "Arduino"
original_url: "https://docs.arduino.cc/tutorials/ethernet-shield-rev2/udp-ntp-client/"
published: "2025-09-25"
language: "en"
tags: ["Arduino", "W5500", "UDP", "NTP", "Arduino Ethernet Shield 2"]
hardware: ["Arduino Ethernet Shield 2", "Arduino Mega 2560", "Monoprice RJ45 Ethernet Cable"]
likes: 0
views: 1723
comments: 0
source: "WIZnet Makers (https://maker.wiznet.io/)"
---

# 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.

Original author: Arduino (source: https://docs.arduino.cc/tutorials/ethernet-shield-rev2/udp-ntp-client/)

## Components

- **Arduino Ethernet Shield 2** x 1 ([docs](https://docs.arduino.cc/hardware/ethernet-shield-rev2))
- **Arduino Mega 2560** x 1 ([docs](https://www.farnell.com/datasheets/1674878.pdf?_ga=2.12759806.871556650.1519619484-654667508.1508905608&_gac=1.209399078.1518779130.EAIaIQobChMI97my66Sq2QIV77ftCh01kgA_EAMYASAAEgKPyvD_BwE))
- **Monoprice RJ45 Ethernet Cable** x 1
- Software: **Arduino IDE** ([docs](https://www.arduino.cc/en/software))

## Article

## 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 &lt;Ethernet.h>

#include &lt;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 &lt;&lt; 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.

---

Source: https://maker.wiznet.io/junlee0615/projects/arduino-w5500-ntp-client--get-accurate-time-via-udp/
