Arduino UNO R4 WiFi: Turn Two Official Examples into an NTP Clock on the LED Matrix
Combine two official examples from arduino/ArduinoCore-renesas (LED matrix text + WiFiS3 NTP) into a compiling UNO R4 WiFi shelf clock. Covers the ArduinoGraphics include-order error, 2.4 GHz-only Wi-Fi, bridge firmware checks and demo-only habits. Includes an affiliate-disclosed eBay board link.

Arduino UNO R4 WiFi: Turn Two Official Examples into an NTP Clock on the LED Matrix
The Arduino UNO R4 WiFi has two things an old UNO never had: a 12×8 LED matrix on the board and an ESP32-S3 handling Wi-Fi. The nicest first project uses both, and you don't need a third-party library zoo for it. Everything here comes from Arduino's own open-source core, which ships the examples I start from.
Sources used in this post:
- arduino/ArduinoCore-renesas, the official core for the UNO R4 boards (Boards Manager package
arduino:renesas_uno; I built against 1.6.0) - Its
Arduino_LED_Matrixexamples, especiallyTextWithArduinoGraphics - Its
WiFiS3examples, especiallyWiFiUdpNtpClient - ArduinoGraphics, the text/drawing library the matrix examples need (Library Manager installed 1.1.5 for me)
- The UNO R4 WiFi product docs for hardware facts
Disclosure: further down I link one eBay listing for the board. That link is an eBay affiliate link (customid=blog01); if you buy through it I may earn a commission at no extra cost to you. Check the listing yourself before you pay.
What is actually on the board
Per Arduino's docs, the main MCU is a Renesas RA4M1 (Arm Cortex-M4, 48 MHz, 256 kB flash, 32 kB SRAM) and its GPIOs run at 5 V, like a classic UNO. Wi-Fi and Bluetooth come from a separate ESP32-S3 module. Your sketch runs on the RA4M1 and talks to the ESP32-S3 through the WiFiS3 library. Two practical consequences:
- The ESP32-S3 radio is 2.4 GHz only, so a 5 GHz-only SSID will never connect.
- The ESP32-S3 runs its own bridge firmware.
WiFiS3definesWIFI_FIRMWARE_LATEST_VERSION("0.6.0"in core 1.6.0), and the official examples print "Please upgrade the firmware" when the board reports something older.
Gotcha 1: include order decides whether text works at all
The first line of the official TextWithArduinoGraphics example is a warning, and it is not decorative:
cpp
// To use ArduinoGraphics APIs, please include BEFORE Arduino_LED_Matrix
#include "ArduinoGraphics.h"
#include "Arduino_LED_Matrix.h"
I swapped the two lines and compiled with arduino-cli for arduino:renesas_uno:unor4wifi. The build fails with errors that don't mention include order:
text
error: 'class ArduinoLEDMatrix' has no member named 'beginDraw'; did you mean 'begin'?
error: 'class ArduinoLEDMatrix' has no member named 'textFont'
error: 'Font_5x7' was not declared in this scope
That's because Arduino_LED_Matrix.h only adds the drawing and text methods when it sees ArduinoGraphics already included. If you get no member named 'beginDraw', check the include order and confirm ArduinoGraphics is installed.
Gotcha 2: the NTP example is a demo, not a clock
WiFiUdpNtpClient is a good protocol walkthrough, but three things make it a poor base for something that sits on a shelf:
while (!Serial);waits for a serial monitor. It's fine at your desk, but it's the wrong default for a board running from a USB charger.- It asks the time server every 10 seconds and uses
delay()everywhere. - The time server is a hard-coded IP,
IPAddress timeServer(162, 159, 200, 123), even though the comment sayspool.ntp.org.WiFiUDP::beginPacket()inWiFiS3also accepts a hostname, so you can just pass"pool.ntp.org".
The combined sketch
This keeps the official examples' structure and fixes the points above. It syncs once at boot, re-syncs every 10 minutes, keeps time with millis() in between, and scrolls HH:MM across the matrix. It compiles cleanly against core 1.6.0 ("Sketch uses 70460 bytes (26%) of program storage space"). I haven't run it on hardware in this write-up, so treat runtime behaviour as untested.
R4MatrixClock.ino:
cpp
// UNO R4 WiFi: NTP time scrolled on the 12x8 LED matrix.
// Built from two official examples in arduino/ArduinoCore-renesas:
// libraries/WiFiS3/examples/WiFiUdpNtpClient
// libraries/Arduino_LED_Matrix/examples/TextWithArduinoGraphics
#include "ArduinoGraphics.h" // must come BEFORE Arduino_LED_Matrix.h
#include "Arduino_LED_Matrix.h"
#include <WiFiS3.h>
#include "arduino_secrets.h"
const long UTC_OFFSET_SEC = 8L * 3600; // change for your time zone
const unsigned long RESYNC_MS = 10UL * 60 * 1000;
ArduinoLEDMatrix matrix;
WiFiUDP Udp;
byte packetBuffer[48];
unsigned long epochAtSync = 0; // Unix seconds at last good sync
unsigned long millisAtSync = 0;
void scroll(const char *text) {
matrix.beginDraw();
matrix.stroke(0xFFFFFFFF);
matrix.textScrollSpeed(60);
matrix.textFont(Font_5x7);
matrix.beginText(0, 1, 0xFFFFFF);
matrix.println(text);
matrix.endText(SCROLL_LEFT);
matrix.endDraw();
}
bool syncNtp() {
memset(packetBuffer, 0, sizeof(packetBuffer));
packetBuffer[0] = 0b11100011; // LI, version, mode (client)
Udp.beginPacket("pool.ntp.org", 123);
Udp.write(packetBuffer, sizeof(packetBuffer));
Udp.endPacket();
unsigned long start = millis();
while (millis() - start < 2000) {
if (Udp.parsePacket() >= 48) {
Udp.read(packetBuffer, sizeof(packetBuffer));
unsigned long secs1900 = (unsigned long)word(packetBuffer[40], packetBuffer[41]) << 16
| word(packetBuffer[42], packetBuffer[43]);
epochAtSync = secs1900 - 2208988800UL;
millisAtSync = millis();
return true;
}
delay(10);
}
return false;
}
void setup() {
Serial.begin(115200);
unsigned long t0 = millis();
while (!Serial && millis() - t0 < 3000) {} // don't hang forever on a USB charger
matrix.begin();
if (WiFi.status() == WL_NO_MODULE) {
Serial.println("No WiFi module");
scroll(" NO WIFI ");
while (true) {}
}
if (String(WiFi.firmwareVersion()) < WIFI_FIRMWARE_LATEST_VERSION) {
Serial.println("Bridge firmware is older than this core expects; consider updating it");
}
while (WiFi.begin(SECRET_SSID, SECRET_PASS) != WL_CONNECTED) {
Serial.println("Retrying WiFi...");
scroll(" WIFI? ");
delay(5000);
}
Serial.print("IP: ");
Serial.println(WiFi.localIP());
Udp.begin(2390);
while (!syncNtp()) {
scroll(" NTP? ");
}
}
void loop() {
if (millis() - millisAtSync > RESYNC_MS) syncNtp();
unsigned long now = epochAtSync + (millis() - millisAtSync) / 1000 + UTC_OFFSET_SEC;
char buf[12];
snprintf(buf, sizeof(buf), " %02lu:%02lu ", (now % 86400UL) / 3600, (now % 3600UL) / 60);
scroll(buf);
}
arduino_secrets.h, in the same folder (keep it out of git):
cpp
#define SECRET_SSID "your-2.4GHz-network"
#define SECRET_PASS "your-password"
Set UTC_OFFSET_SEC for your zone (8L * 3600 is UTC+8). There's no daylight-saving logic. If you need it, the RA4M1's built-in RTC and the core's RTC library are the next step.
Build and upload
In the IDE, install Arduino UNO R4 Boards from Boards Manager and ArduinoGraphics from Library Manager. From the command line:
bash
arduino-cli core install arduino:renesas_uno
arduino-cli lib install ArduinoGraphics
arduino-cli compile --fqbn arduino:renesas_uno:unor4wifi R4MatrixClock
arduino-cli upload --fqbn arduino:renesas_uno:unor4wifi -p /dev/ttyACM0 R4MatrixClock
One box-specific note: on my Linux machine, the first core install failed with "checking local archive integrity" because the core archive downloaded as 0 bytes. Downloading the same ArduinoCore-renesas_uno-1.6.0.tar.bz2 into ~/.arduino15/staging/packages/ by hand (its SHA-256 matched the index) and re-running the install fixed it.
The board I'd point you to
If you still need a board, this is the listing I checked while writing: Arduino UNO R4 WiFi (ABX00087) on eBay (affiliate link).
When I opened it on Nov 3, 2026, it was listed as New, item specifics showed Brand: Arduino and Country of Origin: Italy, and the item was located in Dallas, Texas, United States. The seller had 99.4% positive feedback from about 4,000 ratings, returns were accepted for 30 days (buyer pays return shipping), and the page showed US $29.99 with free USPS First Class shipping to a US address. The part number ABX00087 appears in the title but isn't filled in the item specifics, so check the board and box markings when it arrives.
Whichever seller you choose, check that the board says UNO R4 WiFi (not "Minima", which has no Wi-Fi and no matrix) and that the listing is the genuine Arduino part, ABX00087, if that matters to you. Many "R4 WiFi compatible" boards exist; the official core may work on them, but that's not guaranteed.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
no member named 'beginDraw' |
Include order, or ArduinoGraphics missing | Include ArduinoGraphics.h first; install the library |
Matrix scrolls WIFI? forever |
5 GHz SSID, typo, or captive portal | Use a 2.4 GHz WPA2 network |
Scrolls NTP? |
UDP port 123 blocked | Try another network or NTP host |
| Nothing at all from a USB charger | Original while (!Serial); left in |
Use the timeout version above |
| Serial says to upgrade firmware | Old ESP32-S3 bridge firmware | Update it with Arduino's firmware updater |
Takeaway
The UNO R4 WiFi's best "hello world" is already in its open-source core: the matrix text example and the NTP example. Combine them, fix the include order and the demo-only habits, and you get a shelf clock in about 100 lines.
Affiliate disclosure: the eBay link above is an affiliate link (customid=blog01). Prices, stock and seller details change; I describe the listing as I saw it on Nov 3, 2026.