Digital Clock with MatriXDeck
Create a stylish digital clock with WiFi time synchronization, multiple display modes, and customizable colors.

Required Components:
Digital Clock with MatriXDeck
Introduction
Transform your MatriXDeck into a stylish, WiFi-connected digital clock that automatically keeps perfect time. This project demonstrates how to use the ESP32's WiFi capabilities to sync with NTP (Network Time Protocol) servers, allowing your clock to maintain accurate time even after power cycles.
You'll learn about:
- Connecting to WiFi networks
- Fetching time from NTP servers
- Designing custom fonts and animations
- Creating different display modes
Materials Needed
- MatriXDeck V1
- WiFi internet connection
- USB-C cable for power (or use the battery)
Project Overview
We'll create a digital clock with the following features:
- Automatic time synchronization via WiFi
- Multiple display modes (12/24 hour, date display)
- Customizable colors with different themes
- Smooth time transitions and animations
Step-by-Step Instructions
1. Setting Up WiFi and NTP
First, we need to connect to WiFi and set up the NTP client to fetch the current time:
#include <MatriXDeck.h>
#include <WiFi.h>
#include <time.h>
MatriXDeck matrix;
// WiFi credentials
const char* ssid = "YourWiFiName";
const char* password = "YourWiFiPassword";
// NTP Server settings
const char* ntpServer = "pool.ntp.org";
const long gmtOffset_sec = 3600; // Replace with your GMT offset (seconds)
const int daylightOffset_sec = 3600; // Replace with daylight savings offset
void setup() {
matrix.begin();
// Connect to WiFi
matrix.clear();
matrix.print("Connecting", 0, 0, GREEN);
matrix.print("to WiFi...", 0, 8, GREEN);
matrix.update();
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
}
// Display connected message
matrix.clear();
matrix.print("Connected!", 0, 4, GREEN);
matrix.update();
delay(2000);
// Init and get the time
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
// Disconnect WiFi to save power (optional)
// WiFi.disconnect(true);
// WiFi.mode(WIFI_OFF);
}
2. Creating the Clock Display
Now, let's add the main loop to display the time:
// Global variables for storing time
int prevMinute = -1;
int hours, minutes, seconds;
bool is24HourFormat = true;
int displayMode = 0; // 0 = time, 1 = date, 2 = seconds
void loop() {
updateTime();
// Only update display when needed
if (minutes != prevMinute || displayMode != 0) {
updateDisplay();
prevMinute = minutes;
}
// Check for button presses to change modes
checkButtons();
delay(100);
}
void updateTime() {
struct tm timeinfo;
if(!getLocalTime(&timeinfo)) {
matrix.clear();
matrix.print("Time Error", 0, 4, RED);
matrix.update();
delay(2000);
return;
}
hours = timeinfo.tm_hour;
minutes = timeinfo.tm_min;
seconds = timeinfo.tm_sec;
}
void updateDisplay() {
matrix.clear();
// Display time in HH:MM format
if (displayMode == 0) {
int displayHour = is24HourFormat ? hours : (hours % 12 == 0 ? 12 : hours % 12);
// Draw hours
drawNumber(displayHour / 10, 2, 4);
drawNumber(displayHour % 10, 9, 4);
// Blink the colon once per second
if (seconds % 2 == 0) {
matrix.setPixel(16, 5, GREEN);
matrix.setPixel(16, 10, GREEN);
}
// Draw minutes
drawNumber(minutes / 10, 19, 4);
drawNumber(minutes % 10, 26, 4);
// AM/PM indicator (if in 12-hour mode)
if (!is24HourFormat) {
if (hours >= 12) {
matrix.print("PM", 27, 0, RED);
} else {
matrix.print("AM", 27, 0, GREEN);
}
}
}
// Add code for other display modes here
matrix.update();
}
3. Adding Button Controls
Let's add button controls to switch between display modes:
void checkButtons() {
// Using MatriXDeck built-in buttons
if (matrix.isButtonPressed(BUTTON_A)) {
displayMode = (displayMode + 1) % 3;
delay(200); // Debounce
}
if (matrix.isButtonPressed(BUTTON_B)) {
is24HourFormat = !is24HourFormat;
delay(200); // Debounce
}
}
4. Creating Custom Number Font
For larger, more readable numbers, we'll create a custom number font:
// Custom 5x7 number font
const bool numberFont[10][5][7] = {
// 0
{
{1, 1, 1, 1, 1, 1, 0},
{1, 0, 0, 0, 0, 1, 0},
{1, 0, 0, 0, 0, 1, 0},
{1, 0, 0, 0, 0, 1, 0},
{1, 1, 1, 1, 1, 1, 0}
},
// 1
{
{0, 0, 0, 0, 0, 1, 0},
{0, 0, 0, 0, 0, 1, 0},
{0, 0, 0, 0, 0, 1, 0},
{0, 0, 0, 0, 0, 1, 0},
{0, 0, 0, 0, 0, 1, 0}
},
// ... and so on for digits 2-9
};
void drawNumber(int num, int x, int y) {
if (num < 0 || num > 9) return;
for (int row = 0; row < 7; row++) {
for (int col = 0; col < 5; col++) {
if (numberFont[num][col][row]) {
matrix.setPixel(x + col, y + row, GREEN);
}
}
}
}
Complete Code
The complete code combines all these elements and adds more display modes and customization options. See the full code in our GitHub repository.
Extending the Project
Here are some ideas to enhance your digital clock:
- Weather Clock: Add weather information from an API
- Alarm Clock: Implement alarm functionality with the speaker
- Countdown Timer: Add a countdown mode for timing activities
- Animations: Create smooth transitions between digits
- Motion Activation: Use the MPU6050 to show the time when motion is detected
Troubleshooting
Clock won't sync time
- Check your WiFi credentials
- Ensure your network allows NTP traffic
- Try a different NTP server
Display is too dim or bright
- Adjust the brightness with
matrix.setBrightness(0-255)
Time is incorrect
- Double-check your GMT and daylight savings offsets
Conclusion
Congratulations! You've created a WiFi-connected digital clock with your MatriXDeck. This project demonstrates the power of combining the LED matrix with internet connectivity to create a practical and customizable timepiece.
As you become more comfortable with the MatriXDeck, you can add more features and create a truly personalized clock for your desk or bedside table.
Share your clock creations with us on our Discord community or tag us on social media with #MatriXDeck!