ESP32 NTP Stratum 1 Time Server for your home network
This project was born with a simple goal: create a low-budget, Stratum 1 NTP time server solution with no need for periodic Linux OS updates. Rather just set it up and let it do its job.
It uses a GNSS North America & Europe) receiver as its time source, making it a true Stratum 1 server — meaning it gets its time directly from satellites rather than from another NTP server. Every device on your home network can then synchronize to it for highly accurate local time.
A full write-up of the original (version 1) project is available on Hackaday.io.
Version 2 is a significant upgrade over Version 1:
- New microcontroller board — now built around the WaveShare ESP32-P4-ETH instead of the Olimex ESP32-PoE-ISO. The ESP32-P4 is more modern and faster than the ESP32-WROOM-32/32E used in v1.
- More accurate NTP responses — PPS (Pulse Per Second) pin support is now fully exploited to discipline the time reference, delivering sub-millisecond accuracy when using a PPS-capable GPS module.
- Over-the-Ethernet OTA updates — firmware can now be updated over the Ethernet connection directly from VS Code, with on-screen progress shown on the LCD.
- LCD is now optional — in v1 an LCD 2004 screen was required; in v2 it is entirely optional.
- Optional up time / reset button — carry-over from v1, still supported.
- Updated 3D printed case — the enclosure files have been updated for the new WaveShare ESP32-P4-ETH board.
- Built with ESP-IDF — rewritten from the ground up in C++ on ESP-IDF v5.5.3 using FreeRTOS tasks.
- NVS-backed GPS state — the GPS module identity and baud rate are persisted across reboots so following the initial setup startup speed is quick.
- Broader GNSS module support — still works great with the SparkFun MAX-M10S (recommended), but now also supports lower-cost, generic GNSS modules, even those (although not recommended) that do not expose a PPS pin.
- Ability to set a custom MAC Address — (version 2.2) allows the use of the default ESP32-P4's MAC address or for a custom MAC address to be set.
The source code for Version 1 (Arduino / PlatformIO) remains available at: https://github.com/roblatour/ESP32TimeServer/releases/tag/v1.0.0.0
| Qty | Item |
|---|---|
| 1 | WaveShare ESP32-P4-ETH development board (with or without optional PoE Hat) 1 |
| 1 | GPS/GNSS module Recommeded: SparkFun GNSS Receiver Breakout - MAX-M10S (Qwiic) 1. Note: while some lower-cost generic modules (AliExpress - NEO8M) are also supported, those including a PPS pin are strongly preferred |
| 1 | GPS/GNSS antenna with SMA connector (SparkFun GPS/GNSS Magnetic Mount Antenna - 3m (SMA)) 1 |
| 1 | (Optional) 4×20 I²C LCD display with HD44780 controller with PCF8574 I²C backpack (AliExpress) 1 |
| 1 | (Optional) Momentary push button for displaying up time and triggering a reset (AliExpress) 1 |
| 1 | (Optional) USB C extension cable (with right angle end) (AliExpress) 1 + two M3*8 |
| — | Miscellaneous: Ethernet cable, female dupont connection wires, small 4" .1" zip ties, solder 2 |
| — | A PoE-capable switch, PoE injector, or USB-C power supply and USB-C cable |
⚠️ WARNING — Do NOT power the ESP32-P4-ETH via both its USB-C connector and a PoE powered Ethernet cable at the same time. Powering from both simultaneously may damage the ESP32-P4-ETH board, POE switch, or device providing USB power. Either power source alone is sufficient to power the board, GPS module, and LCD screen.
1 (Optional) 3D Printable Case designed with these specific components in mind (for more information see below)
2 (Optional) To cut down on wiring a PCB can be used. One designed to work within this project's 3D printed enclosure is available in the PCB folder. If your interested, please review the Readme.md file in that folder for more information.
GPS module → ESP32-P4-ETH (mandatory)
| GPS pin | ESP32-P4-ETH pin |
|---|---|
| GND | GND |
| VCC | 3V3 |
| TXD | GPIO 17 (RX) |
| RXD | GPIO 16 (TX) |
| PPS | GPIO 18 |
LCD 2004 (HD44780 + PCF8574 I²C backpack) → ESP32-P4-ETH (optional)
| LCD pin | ESP32-P4-ETH pin |
|---|---|
| GND | GND |
| VCC | 3V3 |
| SDA | GPIO 8 |
| SLC/SCL | GPIO 7 |
Up time / Reset button → ESP32-P4-ETH (optional)
| Button | ESP32-P4-ETH pin |
|---|---|
| One terminal | GND |
| The other terminal | GPIO 3 |
Refer to the pin definitions in main/ESP32TimeServerSettings.h.
An downloadable 3D printable enclosure designed for use the WaveShare ESP32-P4-ETH (with or without the POE hat) + Sparkfun GPS boards is included in the 3D printable case/ folder. Both .stl (print-ready) and .f3z (Fusion 360 editable source) files are provided so you can tweak the design to suit your needs.
Note: the 3D printable enclosure files also include the needed models for version one of this project which used the Olimex ESP32-PoE-ISO Rev. B.
This release is built using:
- Visual Studio Code
- Espressif ESP-IDF Extension for VS Code
- ESP-IDF v5.5.3
Dependencies are managed automatically via the ESP-IDF Component Manager:
SparkFun u-blox GNSS Arduino Library v3— GPS communicationesp-idf-lib/hd44780— LCD driveresp-idf-lib/pcf8574— I²C LCD backpack driverespressif/arduino-esp32— Arduino compatibility layer (used for OTA and serial)
All user-configurable settings — GPIO pins, GPS options, LCD options, button support, time zone, and safeguard threshold — are centralised in:
main/ESP32TimeServerSettings.h
Edit this file before building to match your hardware setup.
Load the ESP-IDF environment, then build and flash:
call C:\esp\v5.5.3\esp-idf\export.bat
idf.py build
idf.py -p COMx flash monitor(Replace COMx with your actual serial port.)
A VS Code task "ESP-IDF: OTA Upload over Ethernet" is included in .vscode/tasks.json. It builds the firmware and deploys it to the device over Ethernet using espota.py — no USB cable needed after the first flash. Alternatively, there is a terminal command that can be used, it is found in the misc folder, in the file Useful Power Shell Commands.txt.
Once running, and with your Network and System changes setup, you can validate accuracy at https://time.is.
Please see Setup.md
This project is released under the MIT License — see the LICENSE file for details.
To help support this project, or to just say thanks, you're welcome to 'buy me a coffee'
Copyright © 2026 Rob Latour

