What about an NTP WiFi clock automatically updating the current time?
I did this a few months ago replacing an old broken digital clock in the living room, using just a Wemos D1 mini board (I know you don't have it, but it's very common, cheap, and small) and a standard 16x2 LCD with I2C interface.
This is the code, if you dare to build it (just connect the LCD to SDA/SCL pins):
netclock.ino:
#define PRJVER "NetClock1"
// change to your network SSID
const char* W_SSID = "myssid";
// change to your network key
const char* W_PASSW = "mypassword";
// Change to your nearest NTP pool
const char* NTPSERVER = "0.pool.ntp.org";
// Change to your timezone real name
const char* MYTIMEZONE = "Europe/Rome";
#include <ezTime.h>
#include <ESP8266WiFi.h>
Timezone myTZ;
// Data ed ora corrente
int Year, Month, Day;
int Hour, Min, Sec;
// Data ed ora precedenti
int prevYear, prevMonth, prevDay;
int prevHour, prevMin, prevSec;
// Library for LCD DIsplay with I2C
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
#include "LargeNumbers.h"
unsigned long nextUpdTime;
bool dots = true;
void setup() {
Serial.begin(115200);
Serial.println("STARTING...");
// initialize the LCD
initLcd();
WiFi.mode(WIFI_STA);
WiFi.disconnect();
delay(100);
// Attempt to connect to Wifi network:
Serial.print("Connecting Wifi");
lcd.setCursor(0,0);
lcd.print("Connecting Wifi");
lcd.setCursor(0,1);
lcd.print(W_SSID);
WiFi.begin(W_SSID, W_PASSW);
delay(1000);
while (WiFi.status() != WL_CONNECTED) {
lcd.setCursor(15, 1);
lcd.print("x");
delay(500);
lcd.setCursor(15, 1);
lcd.print("+");
delay(500);
Serial.print(".");
}
Serial.println();
lcd.setCursor(0, 0);
lcd.print("WiFi connected! ");
delay(2000);
// ezTime init
waitForSync();
// Set time zone change it
myTZ.setLocation(MYTIMEZONE);
lcd.clear();
UpdateDisplay();
Serial.println("STARTED");
}
void loop() {
UpdateDisplay();
delay(1000);
}
void UpdateDisplay()
{
if (Min != myTZ.minute())
{
Hour = myTZ.hour();
Min = myTZ.minute();
Sec = myTZ.second();
lcd.clear();
printValue(1, Hour);
printValue(8, Min);
Serial.print(Hour);Serial.print(":");Serial.println(Min);
}
if (dots)
printDots(7);
else
noDots(7);
dots = !dots;
//Serial.println(dots);
}
LargeNumbers.h:
// the 8 arrays that form each segment of the custom numbers
byte bar1[8] =
{
B11100,
B11110,
B11110,
B11110,
B11110,
B11110,
B11110,
B11100
};
byte bar2[8] =
{
B00111,
B01111,
B01111,
B01111,
B01111,
B01111,
B01111,
B00111
};
byte bar3[8] =
{
B11111,
B11111,
B00000,
B00000,
B00000,
B00000,
B11111,
B11111
};
byte bar4[8] =
{
B11110,
B11100,
B00000,
B00000,
B00000,
B00000,
B11000,
B11100
};
byte bar5[8] =
{
B01111,
B00111,
B00000,
B00000,
B00000,
B00000,
B00011,
B00111
};
byte bar6[8] =
{
B00000,
B00000,
B00000,
B00000,
B00000,
B00000,
B11111,
B11111
};
byte bar7[8] =
{
B00000,
B00000,
B00000,
B00000,
B00000,
B00000,
B00111,
B01111
};
byte bar8[8] =
{
B11111,
B11111,
B00000,
B00000,
B00000,
B00000,
B00000,
B00000
};
void initLcd() {
lcd.init();
lcd.backlight();
lcd.createChar(1,bar1);
lcd.createChar(2,bar2);
lcd.createChar(3,bar3);
lcd.createChar(4,bar4);
lcd.createChar(5,bar5);
lcd.createChar(6,bar6);
lcd.createChar(7,bar7);
lcd.createChar(8,bar8);
}
// Le cifre da 0 a 9, mentre 10 è lo spazio
byte custom[11][6] = {
{2,8,1,2,6,1}, // 0
{32,32,1,32,32,1}, // 1
{5,3,1,2,6,6}, // 2
{5,3,1,7,6,1}, // 3
{2,6,1,32,32,1}, // 4
{2,3,4,7,6,1}, // 5
{2,3,4,2,6,1}, // 6
{2,8,1,32,32,1}, // 7
{2,3,1,2,6,1}, // 8
{2,3,1,7,6,1}, // 9
{32,3,32,32,3,32} // :
};
void printChar(byte col, char value) {
int i = value - '0';
if ( value == ' ' ) i = 10;
lcd.setCursor(col, 0);
for (int j=0; j<=5; ++j) {
if ( j == 3 ) lcd.setCursor(col, 1);
lcd.write(custom[i][j]);
}
}
void printDots(byte col) {
lcd.setCursor(col, 0);
lcd.write('.');
lcd.setCursor(col, 1);
lcd.write('.');
}
void noDots(byte col) {
lcd.setCursor(col, 0);
lcd.write(' ');
lcd.setCursor(col, 1);
lcd.write(' ');
}
void printValue(byte col, int v) {
char buf[3];
sprintf(buf, "%02d", v);
for(byte c=0; c<2; ++c) {
printChar(col, buf[c]);
col += 3;
}
}