<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.myows.top/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=178.197.194.241&amp;*</id>
	<title> - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.myows.top/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=178.197.194.241&amp;*"/>
	<link rel="alternate" type="text/html" href="https://wiki.myows.top/index.php?title=Special:Contributions/178.197.194.241"/>
	<updated>2026-05-13T19:22:56Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.31.0</generator>
	<entry>
		<id>https://wiki.myows.top/index.php?title=Internet_Clock_1&amp;diff=1477</id>
		<title>Internet Clock 1</title>
		<link rel="alternate" type="text/html" href="https://wiki.myows.top/index.php?title=Internet_Clock_1&amp;diff=1477"/>
		<updated>2025-09-19T17:39:01Z</updated>

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

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

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

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

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

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

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

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