Internet Clock 1
Contents
Internet Clock[edit]
Internet Clock with ESP32 & OLED 128×64 Display
Base sur le travail de Techlogics.net (Blog) basé en Inde (GMT+5:30)
GMT Offsets
https://techlogics.net/how-to-use-gmt-offsets-in-your-arduino-projects-for-accurate-time-synchronization/
Internet Clock - Code 1 -[edit]
Code 1✅
Grove Base for XIAO
XIAO-ESP32S3
OLED 128x64 (SSD1308), Port I2c ✅
ou
OLED 128x64 (SSD1315), Port I2c ✅
// Initialize OLED display 0.96 inches (SSD1308) (Seeed-Studio) 128×64 U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); //
#include <U8g2lib.h>
#include <Wire.h>
#include <WiFi.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
#include <time.h>
// Replace with your WiFi credentials
const char* ssid = "Your_wifi_SSID";
const char* password = "Wifi_password";
// Initialize OLED display (128x128 SH1107)
// U8G2_SH1107_SEEED_128X128_1_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);
// Initialize OLED display (128x64 SH1106)
// U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
// Initialize OLED display (128x64 SSD1306) Ideaspark ESP32 0,96 OLED Board
U8G2_SSD1306_128X64_NONAME_F_SW_I2C
u8g2(U8G2_R0, /* clock=*/ 22, /* data=*/ 21, /* reset=*/ U8X8_PIN_NONE);
// NTP Client Setup
WiFiUDP ntpUDP;
// NTPClient timeClient(ntpUDP, "pool.ntp.org", 19800, 3600000); // Timezone offset (19800 seconds = UTC +5:30) Colombo
NTPClient timeClient(ntpUDP, "pool.ntp.org", 3600, 3600000); // Timezone offset (3600 seconds = UTC +1:00) Zurich
void setup() {
// Start serial communication for debugging
Serial.begin(115200);
// Connect to Wi-Fi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi...");
}
Serial.println("Connected to WiFi");
// Initialize the OLED
u8g2.begin();
// Start the NTP client
timeClient.begin();
//timeClient.setTimeOffset(19800); // Indian Standard Time colombo (UTC +5:30)
timeClient.setTimeOffset(3600); // Europe Standard Time Zurich (UTC +1:00)
}
void loop() {
timeClient.update(); // Update time from NTP server
// Get current time in seconds
unsigned long currentEpoch = timeClient.getEpochTime();
// Convert epoch time (unsigned long) to time_t (signed long)
time_t currentTime = (time_t)currentEpoch;
// Convert time to time structure
struct tm* timeInfo;
timeInfo = localtime(¤tTime); // Convert to time structure
// Extract time components
int hours = timeInfo->tm_hour;
int minutes = timeInfo->tm_min;
int seconds = timeInfo->tm_sec;
// Extract date components
int day = timeInfo->tm_mday;
int month = timeInfo->tm_mon + 1; // tm_mon is zero-based, so add 1
int year = timeInfo->tm_year + 1900; // tm_year is years since 1900, so add 1900
// Extract day of the week (0 = Sunday, 1 = Monday, etc.)
String daysOfWeek[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
String dayOfWeek = daysOfWeek[timeInfo->tm_wday];
// Clear the display
u8g2.clearBuffer();
// Set font size for the clock
u8g2.setFont(u8g2_font_ncenB18_tr); // Larger font (18px)
// Format the time
String timeStr = String(hours) + ":" + (minutes < 10 ? "0" + String(minutes) : String(minutes)) + ":" + (seconds < 10 ? "0" + String(seconds) : String(seconds));
// Calculate the width of the time text to center it
int textWidth = u8g2.getStrWidth(timeStr.c_str());
// Set the cursor position to center the time text
int x = (128 - textWidth) / 2; // Center horizontally on 128x64 screen
int y = 24; // Set Y position to the middle of the screen for time
// Draw the time at the center of the screen
u8g2.setCursor(x, y);
u8g2.print(timeStr);
// Set font size for the date
u8g2.setFont(u8g2_font_ncenB10_tr); // Smaller font (10px) for the date
// Format the date as DD/MM/YYYY with leading zeroes if necessary
String dayStr = (day < 10) ? "0" + String(day) : String(day);
String monthStr = (month < 10) ? "0" + String(month) : String(month);
String dateStr = dayStr + "/" + monthStr + "/" + String(year);
// Calculate the width of the date text to center it
int dateTextWidth = u8g2.getStrWidth(dateStr.c_str());
// Set the cursor position to center the date text
int dateX = (128 - dateTextWidth) / 2; // Center horizontally
int dateY = 40; // Move the date 2px up from the previous position
// Draw the date below the time
u8g2.setCursor(dateX, dateY);
u8g2.print(dateStr);
// Set font size for the day of the week
u8g2.setFont(u8g2_font_ncenB10_tr); // Smaller font (10px) for the day of the week
// Calculate the width of the day of the week text to center it
int dayOfWeekWidth = u8g2.getStrWidth(dayOfWeek.c_str());
// Set the cursor position to center the day of the week text
int dayOfWeekX = (128 - dayOfWeekWidth) / 2; // Center horizontally
int dayOfWeekY = 56; // Set Y position below the date text
// Draw the day of the week below the date
u8g2.setCursor(dayOfWeekX, dayOfWeekY);
u8g2.print(dayOfWeek);
// Send the buffer to the display
u8g2.sendBuffer();
delay(1000); // Update every second
}
Internet Clock - Code 2 - 128x64[edit]
Code adapté pour tenir compte du daylight✅
Code 2✅
Grove Base for XIAO
XIAO-ESP32S3
OLED 128x64 (SSD1308), Port I2c ✅
ou
OLED 128x64 (SSD1315), Port I2c ✅
// Initialize OLED display 0.96 inches (SSD1308) (Seeed-Studio) 128×64 U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); //
#include <U8g2lib.h>
#include <Wire.h>
#include <WiFi.h>
#include <time.h>
// WiFi credentials
const char* ssid = "Your_wifi_SSID";
const char* password = "Wifi_password";
// OLED display (SSD1306 128x64)
U8G2_SSD1306_128X64_NONAME_F_SW_I2C
u8g2(U8G2_R0, /* clock=*/ 22, /* data=*/ 21, /* reset=*/ U8X8_PIN_NONE);
void setup() {
Serial.begin(115200);
// Connexion Wi-Fi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi...");
}
Serial.println("Connected to WiFi");
// Initialisation OLED
u8g2.begin();
// Configuration NTP + fuseau horaire Europe/Zurich avec DST
configTime(0, 0, "pool.ntp.org", "time.nist.gov");
setenv("TZ", "CET-1CEST,M3.5.0,M10.5.0/3", 1);
tzset();
}
void loop() {
struct tm timeinfo;
if (!getLocalTime(&timeinfo)) {
Serial.println("Failed to obtain time");
return;
}
// Extraction des composants
int hours = timeinfo.tm_hour;
int minutes = timeinfo.tm_min;
int seconds = timeinfo.tm_sec;
int day = timeinfo.tm_mday;
int month = timeinfo.tm_mon + 1;
int year = timeinfo.tm_year + 1900;
String daysOfWeek[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
String dayOfWeek = daysOfWeek[timeinfo.tm_wday];
// Effacer l'écran
u8g2.clearBuffer();
// Heure
u8g2.setFont(u8g2_font_ncenB18_tr);
String timeStr = String(hours) + ":" +
(minutes < 10 ? "0" + String(minutes) : String(minutes)) + ":" +
(seconds < 10 ? "0" + String(seconds) : String(seconds));
int textWidth = u8g2.getStrWidth(timeStr.c_str());
u8g2.setCursor((128 - textWidth) / 2, 24);
u8g2.print(timeStr);
// Date
u8g2.setFont(u8g2_font_ncenB10_tr);
String dateStr = (day < 10 ? "0" + String(day) : String(day)) + "/" +
(month < 10 ? "0" + String(month) : String(month)) + "/" +
String(year);
int dateTextWidth = u8g2.getStrWidth(dateStr.c_str());
u8g2.setCursor((128 - dateTextWidth) / 2, 40);
u8g2.print(dateStr);
// Jour de la semaine
int dayOfWeekWidth = u8g2.getStrWidth(dayOfWeek.c_str());
u8g2.setCursor((128 - dayOfWeekWidth) / 2, 56);
u8g2.print(dayOfWeek);
u8g2.sendBuffer();
delay(1000);
}
Internet Clock - Code 2 - 128x128[edit]
// Initialize OLED constructeur **adapté au SH1107 128x128** U8G2_SH1107_SEEED_128X128_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
#include <U8g2lib.h>
#include <Wire.h>
#include <WiFi.h>
#include <time.h>
// WiFi credentials
const char* ssid = "Your_wifi_SSID";
const char* password = "Wifi_password";
// Initialize OLED constructeur **adapté au SH1107 128x128**
U8G2_SH1107_SEEED_128X128_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
void setup() {
Serial.begin(115200);
// Connexion Wi-Fi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi...");
}
Serial.println("Connected to WiFi");
// Initialisation OLED
u8g2.begin();
// Configuration NTP + fuseau horaire Europe/Zurich avec DST
configTime(0, 0, "pool.ntp.org", "time.nist.gov");
setenv("TZ", "CET-1CEST,M3.5.0,M10.5.0/3", 1);
tzset();
}
void loop() {
struct tm timeinfo;
if (!getLocalTime(&timeinfo)) {
Serial.println("Failed to obtain time");
return;
}
// Extraction des composants
int hours = timeinfo.tm_hour;
int minutes = timeinfo.tm_min;
int seconds = timeinfo.tm_sec;
int day = timeinfo.tm_mday;
int month = timeinfo.tm_mon + 1;
int year = timeinfo.tm_year + 1900;
String daysOfWeek[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
String dayOfWeek = daysOfWeek[timeinfo.tm_wday];
// Effacer l'écran
u8g2.clearBuffer();
// Heure
u8g2.setFont(u8g2_font_ncenB18_tr);
String timeStr = String(hours) + ":" +
(minutes < 10 ? "0" + String(minutes) : String(minutes)) + ":" +
(seconds < 10 ? "0" + String(seconds) : String(seconds));
int textWidth = u8g2.getStrWidth(timeStr.c_str());
u8g2.setCursor((128 - textWidth) / 2, 50);
u8g2.print(timeStr);
// Date
u8g2.setFont(u8g2_font_ncenB10_tr);
String dateStr = (day < 10 ? "0" + String(day) : String(day)) + "/" +
(month < 10 ? "0" + String(month) : String(month)) + "/" +
String(year);
int dateTextWidth = u8g2.getStrWidth(dateStr.c_str());
u8g2.setCursor((128 - dateTextWidth) / 2, 80);
u8g2.print(dateStr);
// Jour de la semaine
int dayOfWeekWidth = u8g2.getStrWidth(dayOfWeek.c_str());
u8g2.setCursor((128 - dayOfWeekWidth) / 2, 100);
u8g2.print(dayOfWeek);
u8g2.sendBuffer();
delay(1000);
}
Internet Clock - Code 3 -[edit]
Oled 128X64 avec une version daylight & une page html de configuration
#include <U8g2lib.h>
#include <Wire.h>
#include <WiFi.h>
#include <time.h>
#include <ESPAsyncWebServer.h>
#include <Preferences.h>
// === OLED ===
U8G2_SSD1306_128X64_NONAME_F_SW_I2C
u8g2(U8G2_R0, /* clock=*/ 22, /* data=*/ 21, /* reset=*/ U8X8_PIN_NONE);
// === Stockage paramètres ===
Preferences prefs;
// === Variables config ===
String wifiSSID;
String wifiPASS;
String timezone;
int alarmHour;
int alarmMinute;
// === Serveur Web ===
AsyncWebServer server(80);
// === Page HTML ===
const char* htmlPage PROGMEM = R"rawliteral(
<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>ESP32 Config</title></head>
<body>
<h1>Configuration ESP32</h1>
<form action="/save" method="GET">
<label>WiFi SSID:</label><br>
<input type="text" name="ssid" value="%SSID%"><br>
<label>WiFi Password:</label><br>
<input type="password" name="pass" value="%PASS%"><br><br>
<label>Fuseau horaire:</label><br>
<select name="tz">
<option value="CET-1CEST,M3.5.0,M10.5.0/3" %TZ1%>Europe/Zurich</option>
<option value="UTC0" %TZ2%>UTC</option>
</select><br><br>
<label>Heure alarme:</label><br>
<input type="number" name="ah" min="0" max="23" value="%AH%"> :
<input type="number" name="am" min="0" max="59" value="%AM%"><br><br>
<input type="submit" value="Enregistrer">
</form>
</body>
</html>
)rawliteral";
// Remplacement des balises %VAR%
String processor(const String& var) {
if (var == "SSID") return wifiSSID;
if (var == "PASS") return wifiPASS;
if (var == "AH") return String(alarmHour);
if (var == "AM") return String(alarmMinute);
if (var == "TZ1") return (timezone == "CET-1CEST,M3.5.0,M10.5.0/3") ? "selected" : "";
if (var == "TZ2") return (timezone == "UTC0") ? "selected" : "";
return String();
}
void setup() {
Serial.begin(115200);
// Charger paramètres
prefs.begin("config", false);
wifiSSID = prefs.getString("ssid", "Your_wifi_SSID");
wifiPASS = prefs.getString("pass", "Wifi_password");
timezone = prefs.getString("tz", "CET-1CEST,M3.5.0,M10.5.0/3");
alarmHour = prefs.getInt("ah", 7);
alarmMinute = prefs.getInt("am", 0);
// Connexion Wi-Fi
WiFi.begin(wifiSSID.c_str(), wifiPASS.c_str());
if (WiFi.waitForConnectResult() != WL_CONNECTED) {
Serial.println("WiFi non trouvé, démarrage en AP...");
WiFi.softAP("ESP32_Config", "12345678");
} else {
Serial.println("Connecté au WiFi");
}
// Serveur Web
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/html", htmlPage, processor);
});
server.on("/save", HTTP_GET, [](AsyncWebServerRequest *request){
if (request->hasParam("ssid")) wifiSSID = request->getParam("ssid")->value();
if (request->hasParam("pass")) wifiPASS = request->getParam("pass")->value();
if (request->hasParam("tz")) timezone = request->getParam("tz")->value();
if (request->hasParam("ah")) alarmHour = request->getParam("ah")->value().toInt();
if (request->hasParam("am")) alarmMinute = request->getParam("am")->value().toInt();
prefs.putString("ssid", wifiSSID);
prefs.putString("pass", wifiPASS);
prefs.putString("tz", timezone);
prefs.putInt("ah", alarmHour);
prefs.putInt("am", alarmMinute);
request->send(200, "text/html", "<h1>Paramètres enregistrés. Redémarrage...</h1>");
delay(2000);
ESP.restart();
});
server.begin();
// Initialisation OLED
u8g2.begin();
// Config NTP avec fuseau horaire choisi
configTime(0, 0, "pool.ntp.org", "time.nist.gov");
setenv("TZ", timezone.c_str(), 1);
tzset();
}
void loop() {
struct tm timeinfo;
if (!getLocalTime(&timeinfo)) {
Serial.println("Impossible d'obtenir l'heure");
return;
}
// Extraction
int hours = timeinfo.tm_hour;
int minutes = timeinfo.tm_min;
int seconds = timeinfo.tm_sec;
int day = timeinfo.tm_mday;
int month = timeinfo.tm_mon + 1;
int year = timeinfo.tm_year + 1900;
String daysOfWeek[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
String dayOfWeek = daysOfWeek[timeinfo.tm_wday];
// Affichage OLED
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_ncenB18_tr);
String timeStr = String(hours) + ":" +
(minutes < 10 ? "0" + String(minutes) : String(minutes)) + ":" +
(seconds < 10 ? "0" + String(seconds) : String(seconds));
int textWidth = u8g2.getStrWidth(timeStr.c_str());
u8g2.setCursor((128 - textWidth) / 2, 24);
u8g2.print(timeStr);
u8g2.setFont(u8g2_font_ncenB10_tr);
String dateStr = (day < 10 ? "0" + String(day) : String(day)) + "/" +
(month < 10 ? "0" + String(month) : String(month)) + "/" +
String(year);
int dateTextWidth = u8g2.getStrWidth(dateStr.c_str());
u8g2.setCursor((128 - dateTextWidth) / 2, 40);
u8g2.print(dateStr);
int dayOfWeekWidth = u8g2.getStrWidth(dayOfWeek.c_str());
u8g2.setCursor((128 - dayOfWeekWidth) / 2, 56);
u8g2.print(dayOfWeek);
u8g2.sendBuffer();
// Exemple : déclenchement alarme
if (hours == alarmHour && minutes == alarmMinute && seconds == 0) {
Serial.println("ALARM!");
// Ici tu peux activer un buzzer ou LED
}
delay(1000);
}
Internet Clock - Code 4 -[edit]
Basé sur le code 3, la même version daylight & une page html de configuration mais pour un écran Oled 128 x 128
#include <U8g2lib.h>
#include <Wire.h>
#include <WiFi.h>
#include <time.h>
#include <ESPAsyncWebServer.h>
#include <Preferences.h>
// === OLED 128x128 SH1107 ===
U8G2_SH1107_SEEED_128X128_1_SW_I2C
u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);
// === Stockage paramètres ===
Preferences prefs;
// === Variables config ===
String wifiSSID;
String wifiPASS;
String timezone;
int alarmHour;
int alarmMinute;
// === Serveur Web ===
AsyncWebServer server(80);
// === Page HTML ===
const char* htmlPage PROGMEM = R"rawliteral(
<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>ESP32 Config</title></head>
<body>
<h1>Configuration ESP32</h1>
<form action="/save" method="GET">
<label>WiFi SSID:</label><br>
<input type="text" name="ssid" value="%SSID%"><br>
<label>WiFi Password:</label><br>
<input type="password" name="pass" value="%PASS%"><br><br>
<label>Fuseau horaire:</label><br>
<select name="tz">
<option value="CET-1CEST,M3.5.0,M10.5.0/3" %TZ1%>Europe/Zurich</option>
<option value="UTC0" %TZ2%>UTC</option>
</select><br><br>
<label>Heure alarme:</label><br>
<input type="number" name="ah" min="0" max="23" value="%AH%"> :
<input type="number" name="am" min="0" max="59" value="%AM%"><br><br>
<input type="submit" value="Enregistrer">
</form>
</body>
</html>
)rawliteral";
// Remplacement des balises %VAR%
String processor(const String& var) {
if (var == "SSID") return wifiSSID;
if (var == "PASS") return wifiPASS;
if (var == "AH") return String(alarmHour);
if (var == "AM") return String(alarmMinute);
if (var == "TZ1") return (timezone == "CET-1CEST,M3.5.0,M10.5.0/3") ? "selected" : "";
if (var == "TZ2") return (timezone == "UTC0") ? "selected" : "";
return String();
}
void setup() {
Serial.begin(115200);
// Charger paramètres
prefs.begin("config", false);
wifiSSID = prefs.getString("ssid", "Your_wifi_SSID");
wifiPASS = prefs.getString("pass", "Wifi_password");
timezone = prefs.getString("tz", "CET-1CEST,M3.5.0,M10.5.0/3");
alarmHour = prefs.getInt("ah", 7);
alarmMinute = prefs.getInt("am", 0);
// Connexion Wi-Fi
WiFi.begin(wifiSSID.c_str(), wifiPASS.c_str());
if (WiFi.waitForConnectResult() != WL_CONNECTED) {
Serial.println("WiFi non trouvé, démarrage en AP...");
WiFi.softAP("ESP32_Config", "12345678");
} else {
Serial.println("Connecté au WiFi");
}
// Serveur Web
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/html", htmlPage, processor);
});
server.on("/save", HTTP_GET, [](AsyncWebServerRequest *request){
if (request->hasParam("ssid")) wifiSSID = request->getParam("ssid")->value();
if (request->hasParam("pass")) wifiPASS = request->getParam("pass")->value();
if (request->hasParam("tz")) timezone = request->getParam("tz")->value();
if (request->hasParam("ah")) alarmHour = request->getParam("ah")->value().toInt();
if (request->hasParam("am")) alarmMinute = request->getParam("am")->value().toInt();
prefs.putString("ssid", wifiSSID);
prefs.putString("pass", wifiPASS);
prefs.putString("tz", timezone);
prefs.putInt("ah", alarmHour);
prefs.putInt("am", alarmMinute);
request->send(200, "text/html", "<h1>Paramètres enregistrés. Redémarrage...</h1>");
delay(2000);
ESP.restart();
});
server.begin();
// Initialisation OLED
u8g2.begin();
// Config NTP avec fuseau horaire choisi
configTime(0, 0, "pool.ntp.org", "time.nist.gov");
setenv("TZ", timezone.c_str(), 1);
tzset();
}
void loop() {
struct tm timeinfo;
if (!getLocalTime(&timeinfo)) {
Serial.println("Impossible d'obtenir l'heure");
return;
}
// Extraction
int hours = timeinfo.tm_hour;
int minutes = timeinfo.tm_min;
int seconds = timeinfo.tm_sec;
int day = timeinfo.tm_mday;
int month = timeinfo.tm_mon + 1;
int year = timeinfo.tm_year + 1900;
String daysOfWeek[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
String dayOfWeek = daysOfWeek[timeinfo.tm_wday];
// Affichage OLED 128x128
u8g2.clearBuffer();
// Heure (plus grande police)
u8g2.setFont(u8g2_font_fub30_tr); // Police large pour 128x128
String timeStr = String(hours) + ":" +
(minutes < 10 ? "0" + String(minutes) : String(minutes));
int textWidth = u8g2.getStrWidth(timeStr.c_str());
u8g2.setCursor((128 - textWidth) / 2, 50);
u8g2.print(timeStr);
// Secondes plus petites à côté
u8g2.setFont(u8g2_font_fub14_tr);
String secStr = (seconds < 10 ? "0" + String(seconds) : String(seconds));
u8g2.setCursor((128 - textWidth) / 2 + textWidth + 4, 50);
u8g2.print(secStr);
// Date
u8g2.setFont(u8g2_font_ncenB14_tr);
String dateStr = (day < 10 ? "0" + String(day) : String(day)) + "/" +
(month < 10 ? "0" + String(month) : String(month)) + "/" +
String(year);
int dateTextWidth = u8g2.getStrWidth(dateStr.c_str());
u8g2.setCursor((128 - dateTextWidth) / 2, 80);
u8g2.print(dateStr);
// Jour de la semaine
int dayOfWeekWidth = u8g2.getStrWidth(dayOfWeek.c_str());
u8g2.setCursor((128 - dayOfWeekWidth) / 2, 100);
u8g2.print(dayOfWeek);
u8g2.sendBuffer();
// Déclenchement alarme
if (hours == alarmHour && minutes == alarmMinute && seconds == 0) {
Serial.println("ALARM!");
// Ici tu peux activer un buzzer ou LED
}
delay(1000);
}
Internet Clock - Code 5 -[edit]
avec 128x128