<?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=144.2.107.134&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=144.2.107.134&amp;*"/>
	<link rel="alternate" type="text/html" href="https://wiki.myows.top/index.php?title=Special:Contributions/144.2.107.134"/>
	<updated>2026-05-13T14:45:30Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.31.0</generator>
	<entry>
		<id>https://wiki.myows.top/index.php?title=Wi-Fi-ESP32-E-Paper&amp;diff=2059</id>
		<title>Wi-Fi-ESP32-E-Paper</title>
		<link rel="alternate" type="text/html" href="https://wiki.myows.top/index.php?title=Wi-Fi-ESP32-E-Paper&amp;diff=2059"/>
		<updated>2025-12-20T00:06:55Z</updated>

		<summary type="html">&lt;p&gt;144.2.107.134: /* Code Wi-Fi &amp;amp; ESP32 &amp;amp; E-Paper */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Code Wi-Fi &amp;amp; ESP32 &amp;amp; E-Paper ===&lt;br /&gt;
&lt;br /&gt;
Wi-Fi-ESP32-E-Paper&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;lt;WebServer.h&amp;gt;&lt;br /&gt;
#include &amp;lt;Preferences.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Preferences prefs;&lt;br /&gt;
WebServer server(80);&lt;br /&gt;
&lt;br /&gt;
String ssid, pass;&lt;br /&gt;
&lt;br /&gt;
const char* configPage = 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;body&amp;gt;&lt;br /&gt;
    &amp;lt;h2&amp;gt;Configuration WiFi&amp;lt;/h2&amp;gt;&lt;br /&gt;
    &amp;lt;form action=&amp;quot;/save&amp;quot; method=&amp;quot;POST&amp;quot;&amp;gt;&lt;br /&gt;
      SSID: &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;ssid&amp;quot;&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
      Password: &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;pass&amp;quot;&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
      &amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Save&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;
void handleRoot() {&lt;br /&gt;
  server.send(200, &amp;quot;text/html&amp;quot;, configPage);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void handleSave() {&lt;br /&gt;
  if (server.hasArg(&amp;quot;ssid&amp;quot;) &amp;amp;&amp;amp; server.hasArg(&amp;quot;pass&amp;quot;)) {&lt;br /&gt;
    ssid = server.arg(&amp;quot;ssid&amp;quot;);&lt;br /&gt;
    pass = server.arg(&amp;quot;pass&amp;quot;);&lt;br /&gt;
    prefs.begin(&amp;quot;wifi&amp;quot;, false);&lt;br /&gt;
    prefs.putString(&amp;quot;ssid&amp;quot;, ssid);&lt;br /&gt;
    prefs.putString(&amp;quot;pass&amp;quot;, pass);&lt;br /&gt;
    prefs.end();&lt;br /&gt;
    server.send(200, &amp;quot;text/html&amp;quot;, &amp;quot;Paramètres sauvegardés. Redémarrage...&amp;quot;);&lt;br /&gt;
    delay(2000);&lt;br /&gt;
    ESP.restart();&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
bool connectToWiFi() {&lt;br /&gt;
  prefs.begin(&amp;quot;wifi&amp;quot;, true);&lt;br /&gt;
  ssid = prefs.getString(&amp;quot;ssid&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
  pass = prefs.getString(&amp;quot;pass&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
  prefs.end();&lt;br /&gt;
&lt;br /&gt;
  if (ssid == &amp;quot;&amp;quot;) return false;&lt;br /&gt;
&lt;br /&gt;
  WiFi.begin(ssid.c_str(), pass.c_str());&lt;br /&gt;
  Serial.print(&amp;quot;Connexion à &amp;quot;); Serial.println(ssid);&lt;br /&gt;
&lt;br /&gt;
  unsigned long start = millis();&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED &amp;amp;&amp;amp; millis() - start &amp;lt; 10000) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return WiFi.status() == WL_CONNECTED;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void startAP() {&lt;br /&gt;
  WiFi.softAP(&amp;quot;XIAO_Config&amp;quot;, &amp;quot;12345678&amp;quot;);&lt;br /&gt;
  Serial.println(&amp;quot;AP démarré. IP: &amp;quot; + WiFi.softAPIP().toString());&lt;br /&gt;
  server.on(&amp;quot;/&amp;quot;, handleRoot);&lt;br /&gt;
  server.on(&amp;quot;/save&amp;quot;, HTTP_POST, handleSave);&lt;br /&gt;
  server.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  if (!connectToWiFi()) {&lt;br /&gt;
    Serial.println(&amp;quot;Échec connexion. Passage en mode AP.&amp;quot;);&lt;br /&gt;
    startAP();&lt;br /&gt;
  } else {&lt;br /&gt;
    Serial.println(&amp;quot;Connecté au WiFi. IP: &amp;quot; + WiFi.localIP().toString());&lt;br /&gt;
    // Ici vous pouvez lancer un serveur web normal ou autre logique&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  server.handleClient();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## ⚙️ Fonctionnement&lt;br /&gt;
- **Premier démarrage** : pas de SSID enregistré → le module crée un AP `XIAO_Config`.  &lt;br /&gt;
- **Page web** : accessible via l’IP du point d’accès (souvent `192.168.4.1`).  &lt;br /&gt;
- **Sauvegarde** : SSID et mot de passe sont stockés dans `Preferences`.  &lt;br /&gt;
- **Redémarrage** : le module tente de se connecter au Wi Fi enregistré.  &lt;br /&gt;
- **Fallback** : si la connexion échoue, retour en mode AP pour reconfigurer.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
- **Mode AP (point d’accès)** au démarrage → permet de configurer les paramètres Wi Fi via une page web.  &lt;br /&gt;
- **Sauvegarde des paramètres** (SSID, mot de passe, etc.) dans la mémoire non volatile (Preferences).  &lt;br /&gt;
- **Redémarrage automatique en mode station** → le XIAO se connecte au réseau configuré.  &lt;br /&gt;
- **Fallback** : si la connexion échoue, il revient en mode AP pour reconfigurer.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Code Modifié&lt;br /&gt;
&lt;br /&gt;
[[File:CONFIGURATION-WI-FI.PNG|250px]]&lt;br /&gt;
[[File:STATUS-WI-FI.PNG|250px]]&lt;br /&gt;
[[File:OUTPUT SERIAL-Wi-Fi.PNG|250px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;lt;WebServer.h&amp;gt;&lt;br /&gt;
#include &amp;lt;Preferences.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Preferences prefs;&lt;br /&gt;
WebServer server(80);&lt;br /&gt;
&lt;br /&gt;
// ---- CONFIG WIFI DOMESTIQUE PAR DÉFAUT ----&lt;br /&gt;
const char* DEFAULT_STA_SSID = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* DEFAULT_STA_PASS = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- CONFIG AP ----&lt;br /&gt;
const char* AP_SSID = &amp;quot;XIAO_Config&amp;quot;;&lt;br /&gt;
const char* AP_PASS = &amp;quot;12345678&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
String ssid, pass;&lt;br /&gt;
&lt;br /&gt;
// ---- PAGE HTML DE CONFIG WIFI ----&lt;br /&gt;
const char* configPage = R&amp;quot;rawliteral(&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;fr&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;title&amp;gt;Configuration WiFi&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
  body {&lt;br /&gt;
    font-family: Arial, sans-serif;&lt;br /&gt;
    background: linear-gradient(135deg, #4c8bf5, #6dd5fa);&lt;br /&gt;
    height: 100vh;&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .card {&lt;br /&gt;
    background: white;&lt;br /&gt;
    padding: 25px;&lt;br /&gt;
    border-radius: 15px;&lt;br /&gt;
    width: 320px;&lt;br /&gt;
    box-shadow: 0 8px 20px rgba(0,0,0,0.2);&lt;br /&gt;
    text-align: center;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  h2 {&lt;br /&gt;
    margin-top: 0;&lt;br /&gt;
    color: #333;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  input[type=&amp;quot;text&amp;quot;], input[type=&amp;quot;password&amp;quot;] {&lt;br /&gt;
    width: 90%;&lt;br /&gt;
    padding: 10px;&lt;br /&gt;
    margin: 10px 0;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    border: 1px solid #aaa;&lt;br /&gt;
    font-size: 16px;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  input[type=&amp;quot;submit&amp;quot;] {&lt;br /&gt;
    background: #4c8bf5;&lt;br /&gt;
    color: white;&lt;br /&gt;
    border: none;&lt;br /&gt;
    padding: 12px 20px;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    font-size: 16px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    margin-top: 10px;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  input[type=&amp;quot;submit&amp;quot;]:hover {&lt;br /&gt;
    background: #3a6fd8;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .links {&lt;br /&gt;
    margin-top: 15px;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .links a {&lt;br /&gt;
    color: #4c8bf5;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .links a:hover {&lt;br /&gt;
    text-decoration: underline;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;card&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;h2&amp;gt;Configuration WiFi&amp;lt;/h2&amp;gt;&lt;br /&gt;
    &amp;lt;form action=&amp;quot;/save&amp;quot; method=&amp;quot;POST&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;ssid&amp;quot; placeholder=&amp;quot;Nom du réseau (SSID)&amp;quot; required&amp;gt;&lt;br /&gt;
      &amp;lt;input type=&amp;quot;password&amp;quot; name=&amp;quot;pass&amp;quot; placeholder=&amp;quot;Mot de passe&amp;quot; required&amp;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;div class=&amp;quot;links&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;a href=&amp;quot;/status&amp;quot;&amp;gt;Voir le statut&amp;lt;/a&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;/div&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;
// ---- HANDLERS HTTP ----&lt;br /&gt;
&lt;br /&gt;
void handleRoot() {&lt;br /&gt;
  server.send(200, &amp;quot;text/html&amp;quot;, configPage);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void handleSave() {&lt;br /&gt;
  if (server.hasArg(&amp;quot;ssid&amp;quot;) &amp;amp;&amp;amp; server.hasArg(&amp;quot;pass&amp;quot;)) {&lt;br /&gt;
    prefs.begin(&amp;quot;wifi&amp;quot;, false);&lt;br /&gt;
    prefs.putString(&amp;quot;ssid&amp;quot;, server.arg(&amp;quot;ssid&amp;quot;));&lt;br /&gt;
    prefs.putString(&amp;quot;pass&amp;quot;, server.arg(&amp;quot;pass&amp;quot;));&lt;br /&gt;
    prefs.end();&lt;br /&gt;
&lt;br /&gt;
    String page = R&amp;quot;rawliteral(&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;fr&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;title&amp;gt;Paramètres enregistrés&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
  body {&lt;br /&gt;
    font-family: Arial, sans-serif;&lt;br /&gt;
    background: linear-gradient(135deg, #4c8bf5, #6dd5fa);&lt;br /&gt;
    height: 100vh;&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
  }&lt;br /&gt;
  .card {&lt;br /&gt;
    background: white;&lt;br /&gt;
    padding: 25px;&lt;br /&gt;
    border-radius: 15px;&lt;br /&gt;
    width: 320px;&lt;br /&gt;
    box-shadow: 0 8px 20px rgba(0,0,0,0.2);&lt;br /&gt;
    text-align: center;&lt;br /&gt;
  }&lt;br /&gt;
  h2 { margin-top: 0; color: #333; }&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;card&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;h2&amp;gt;Paramètres sauvegardés&amp;lt;/h2&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;L&amp;#039;appareil va redémarrer&amp;lt;br&amp;gt;et tenter de se connecter au nouveau réseau.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/div&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;
    server.send(200, &amp;quot;text/html&amp;quot;, page);&lt;br /&gt;
    delay(1500);&lt;br /&gt;
    ESP.restart();&lt;br /&gt;
  } else {&lt;br /&gt;
    server.send(400, &amp;quot;text/plain&amp;quot;, &amp;quot;SSID ou mot de passe manquant&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void handleStatus() {&lt;br /&gt;
  String mode = &amp;quot;&amp;quot;;&lt;br /&gt;
  wifi_mode_t currentMode = WiFi.getMode();&lt;br /&gt;
&lt;br /&gt;
  if (currentMode == WIFI_STA) mode = &amp;quot;Station (STA)&amp;quot;;&lt;br /&gt;
  else if (currentMode == WIFI_AP) mode = &amp;quot;Point d&amp;#039;accès (AP)&amp;quot;;&lt;br /&gt;
  else if (currentMode == WIFI_AP_STA) mode = &amp;quot;AP + Station (AP_STA)&amp;quot;;&lt;br /&gt;
  else mode = &amp;quot;Inconnu&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  String page = R&amp;quot;rawliteral(&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;fr&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;title&amp;gt;Statut WiFi&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
  body {&lt;br /&gt;
    font-family: Arial, sans-serif;&lt;br /&gt;
    background: linear-gradient(135deg, #6dd5fa, #4c8bf5);&lt;br /&gt;
    height: 100vh;&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .card {&lt;br /&gt;
    background: white;&lt;br /&gt;
    padding: 25px;&lt;br /&gt;
    border-radius: 15px;&lt;br /&gt;
    width: 350px;&lt;br /&gt;
    box-shadow: 0 8px 20px rgba(0,0,0,0.2);&lt;br /&gt;
    text-align: center;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  h2 {&lt;br /&gt;
    margin-top: 0;&lt;br /&gt;
    color: #333;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .info {&lt;br /&gt;
    text-align: left;&lt;br /&gt;
    margin-top: 15px;&lt;br /&gt;
    font-size: 16px;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .info div {&lt;br /&gt;
    margin-bottom: 8px;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .btn {&lt;br /&gt;
    margin-top: 15px;&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    padding: 10px 20px;&lt;br /&gt;
    background: #4c8bf5;&lt;br /&gt;
    color: white;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .btn:hover {&lt;br /&gt;
    background: #3a6fd8;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .btn-danger {&lt;br /&gt;
    background: #f56d6d;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .btn-danger:hover {&lt;br /&gt;
    background: #d84a4a;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;card&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;h2&amp;gt;Statut WiFi&amp;lt;/h2&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;info&amp;quot;&amp;gt;&lt;br /&gt;
)rawliteral&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  page += &amp;quot;&amp;lt;div&amp;gt;&amp;lt;b&amp;gt;Mode :&amp;lt;/b&amp;gt; &amp;quot; + mode + &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
  page += &amp;quot;&amp;lt;div&amp;gt;&amp;lt;b&amp;gt;IP (STA) :&amp;lt;/b&amp;gt; &amp;quot; + WiFi.localIP().toString() + &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
  page += &amp;quot;&amp;lt;div&amp;gt;&amp;lt;b&amp;gt;IP (AP) :&amp;lt;/b&amp;gt; &amp;quot; + WiFi.softAPIP().toString() + &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  if (WiFi.status() == WL_CONNECTED) {&lt;br /&gt;
    page += &amp;quot;&amp;lt;div&amp;gt;&amp;lt;b&amp;gt;RSSI :&amp;lt;/b&amp;gt; &amp;quot; + String(WiFi.RSSI()) + &amp;quot; dBm&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
  } else {&lt;br /&gt;
    page += &amp;quot;&amp;lt;div&amp;gt;&amp;lt;b&amp;gt;RSSI :&amp;lt;/b&amp;gt; Non connecté&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  unsigned long ms = millis();&lt;br /&gt;
  unsigned long sec = ms / 1000;&lt;br /&gt;
  unsigned long min = sec / 60;&lt;br /&gt;
  unsigned long hr  = min / 60;&lt;br /&gt;
&lt;br /&gt;
  page += &amp;quot;&amp;lt;div&amp;gt;&amp;lt;b&amp;gt;Uptime :&amp;lt;/b&amp;gt; &amp;quot; + String(hr) + &amp;quot;h &amp;quot; + String(min % 60) + &amp;quot;m &amp;quot; + String(sec % 60) + &amp;quot;s&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  page += R&amp;quot;rawliteral(&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;a class=&amp;quot;btn&amp;quot; href=&amp;quot;/&amp;quot;&amp;gt;Config WiFi&amp;lt;/a&amp;gt;&lt;br /&gt;
    &amp;lt;a class=&amp;quot;btn&amp;quot; href=&amp;quot;/reboot&amp;quot;&amp;gt;Redémarrer&amp;lt;/a&amp;gt;&lt;br /&gt;
    &amp;lt;a class=&amp;quot;btn btn-danger&amp;quot; href=&amp;quot;/resetwifi&amp;quot;&amp;gt;Reset Wi‑Fi&amp;lt;/a&amp;gt;&lt;br /&gt;
  &amp;lt;/div&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;
  server.send(200, &amp;quot;text/html&amp;quot;, page);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void handleReboot() {&lt;br /&gt;
  String page = R&amp;quot;rawliteral(&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;fr&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;title&amp;gt;Redémarrage&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
  body {&lt;br /&gt;
    font-family: Arial, sans-serif;&lt;br /&gt;
    background: linear-gradient(135deg, #4c8bf5, #6dd5fa);&lt;br /&gt;
    height: 100vh;&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .card {&lt;br /&gt;
    background: white;&lt;br /&gt;
    padding: 25px;&lt;br /&gt;
    border-radius: 15px;&lt;br /&gt;
    width: 320px;&lt;br /&gt;
    box-shadow: 0 8px 20px rgba(0,0,0,0.2);&lt;br /&gt;
    text-align: center;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  h2 {&lt;br /&gt;
    margin-top: 0;&lt;br /&gt;
    color: #333;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;card&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;h2&amp;gt;Redémarrage en cours…&amp;lt;/h2&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;L&amp;#039;appareil va redémarrer dans quelques secondes.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/div&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;
  server.send(200, &amp;quot;text/html&amp;quot;, page);&lt;br /&gt;
  delay(1500);&lt;br /&gt;
  ESP.restart();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void handleResetWiFi() {&lt;br /&gt;
  // Effacer les identifiants WiFi stockés&lt;br /&gt;
  prefs.begin(&amp;quot;wifi&amp;quot;, false);&lt;br /&gt;
  prefs.clear();&lt;br /&gt;
  prefs.end();&lt;br /&gt;
&lt;br /&gt;
  String page = R&amp;quot;rawliteral(&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;fr&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;title&amp;gt;Reset WiFi&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
  body {&lt;br /&gt;
    font-family: Arial, sans-serif;&lt;br /&gt;
    background: linear-gradient(135deg, #f56d6d, #fa9a6d);&lt;br /&gt;
    height: 100vh;&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .card {&lt;br /&gt;
    background: white;&lt;br /&gt;
    padding: 25px;&lt;br /&gt;
    border-radius: 15px;&lt;br /&gt;
    width: 320px;&lt;br /&gt;
    box-shadow: 0 8px 20px rgba(0,0,0,0.2);&lt;br /&gt;
    text-align: center;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  h2 {&lt;br /&gt;
    margin-top: 0;&lt;br /&gt;
    color: #333;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;card&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;h2&amp;gt;Réinitialisation WiFi…&amp;lt;/h2&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Les paramètres WiFi ont été effacés.&amp;lt;br&amp;gt;Redémarrage en cours…&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/div&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;
  server.send(200, &amp;quot;text/html&amp;quot;, page);&lt;br /&gt;
&lt;br /&gt;
  // Résumé sur le moniteur série&lt;br /&gt;
  Serial.println(&amp;quot;\n===== RESET WIFI =====&amp;quot;);&lt;br /&gt;
  Serial.println(&amp;quot;IP STA : &amp;quot; + WiFi.localIP().toString());&lt;br /&gt;
  Serial.println(&amp;quot;IP AP  : &amp;quot; + WiFi.softAPIP().toString());&lt;br /&gt;
  Serial.println(&amp;quot;AP SSID : &amp;quot; + String(AP_SSID));&lt;br /&gt;
  Serial.println(&amp;quot;AP PASS : &amp;quot; + String(AP_PASS));&lt;br /&gt;
&lt;br /&gt;
  if (WiFi.status() == WL_CONNECTED)&lt;br /&gt;
    Serial.println(&amp;quot;RSSI : &amp;quot; + String(WiFi.RSSI()) + &amp;quot; dBm&amp;quot;);&lt;br /&gt;
  else&lt;br /&gt;
    Serial.println(&amp;quot;RSSI : Non connecté&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;=======================\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  delay(1500);&lt;br /&gt;
  ESP.restart();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ---- LOGIQUE WIFI ----&lt;br /&gt;
&lt;br /&gt;
bool connectToWiFi() {&lt;br /&gt;
  // Charger les valeurs enregistrées (ou défaut)&lt;br /&gt;
  prefs.begin(&amp;quot;wifi&amp;quot;, true);&lt;br /&gt;
  ssid = prefs.getString(&amp;quot;ssid&amp;quot;, DEFAULT_STA_SSID);&lt;br /&gt;
  pass = prefs.getString(&amp;quot;pass&amp;quot;, DEFAULT_STA_PASS);&lt;br /&gt;
  prefs.end();&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;Connexion à &amp;quot;); Serial.println(ssid);&lt;br /&gt;
&lt;br /&gt;
  WiFi.begin(ssid.c_str(), pass.c_str());&lt;br /&gt;
&lt;br /&gt;
  unsigned long start = millis();&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED &amp;amp;&amp;amp; millis() - start &amp;lt; 10000) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  if (WiFi.status() == WL_CONNECTED) {&lt;br /&gt;
    Serial.println(&amp;quot;\n[WiFi] Connecté en STA&amp;quot;);&lt;br /&gt;
    Serial.println(&amp;quot;IP STA : &amp;quot; + WiFi.localIP().toString());&lt;br /&gt;
    Serial.println(&amp;quot;RSSI   : &amp;quot; + String(WiFi.RSSI()) + &amp;quot; dBm&amp;quot;);&lt;br /&gt;
    return true;&lt;br /&gt;
  } else {&lt;br /&gt;
    Serial.println(&amp;quot;\n[WiFi] Échec connexion STA&amp;quot;);&lt;br /&gt;
    return false;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ---- SETUP / LOOP ----&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
  delay(500);&lt;br /&gt;
  Serial.println(&amp;quot;\n==== DÉMARRAGE XIAO ESP32C3 ====&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Mode AP + STA&lt;br /&gt;
  WiFi.mode(WIFI_AP_STA);&lt;br /&gt;
&lt;br /&gt;
  // Lancer AP&lt;br /&gt;
  WiFi.softAP(AP_SSID, AP_PASS);&lt;br /&gt;
  Serial.println(&amp;quot;[WiFi] AP actif&amp;quot;);&lt;br /&gt;
  Serial.println(&amp;quot;  SSID : &amp;quot; + String(AP_SSID));&lt;br /&gt;
  Serial.println(&amp;quot;  PASS : &amp;quot; + String(AP_PASS));&lt;br /&gt;
  Serial.println(&amp;quot;  IP AP: &amp;quot; + WiFi.softAPIP().toString());&lt;br /&gt;
&lt;br /&gt;
  // Tenter connexion STA&lt;br /&gt;
  connectToWiFi();&lt;br /&gt;
&lt;br /&gt;
  // Routes HTTP&lt;br /&gt;
  server.on(&amp;quot;/&amp;quot;, handleRoot);&lt;br /&gt;
  server.on(&amp;quot;/save&amp;quot;, HTTP_POST, handleSave);&lt;br /&gt;
  server.on(&amp;quot;/status&amp;quot;, handleStatus);&lt;br /&gt;
  server.on(&amp;quot;/reboot&amp;quot;, handleReboot);&lt;br /&gt;
  server.on(&amp;quot;/resetwifi&amp;quot;, handleResetWiFi);&lt;br /&gt;
&lt;br /&gt;
  server.begin();&lt;br /&gt;
  Serial.println(&amp;quot;[HTTP] Serveur web démarré&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  server.handleClient();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
✅ Mode AP + STA simultané&lt;br /&gt;
&lt;br /&gt;
✅ STA avec SSID/mot de passe par défaut, surchargeables via la page de config&lt;br /&gt;
&lt;br /&gt;
✅ AP fixe : SSID XIAO_Config / mot de passe 12345678&lt;br /&gt;
&lt;br /&gt;
✅ Page de configuration Wi‑Fi stylée (/)&lt;br /&gt;
&lt;br /&gt;
✅ Page de statut (/status) : IP STA, IP AP, RSSI, mode, uptime&lt;br /&gt;
&lt;br /&gt;
✅ Bouton Reboot (/reboot)&lt;br /&gt;
&lt;br /&gt;
✅ Bouton Reset Wi‑Fi (/resetwifi) qui efface Preferences + reboot&lt;br /&gt;
&lt;br /&gt;
✅ Résumé sur le moniteur série au reset Wi‑Fi&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Code Wi-Fi &amp;amp; ESP32 &amp;amp; E-Paper 3 onglets ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;lt;WebServer.h&amp;gt;&lt;br /&gt;
#include &amp;lt;Preferences.h&amp;gt;&lt;br /&gt;
#include &amp;quot;TimeDisplayEPaper.h&amp;quot;   // ✅ Ajout pour l’e-paper&lt;br /&gt;
&lt;br /&gt;
Preferences prefs;&lt;br /&gt;
WebServer server(80);&lt;br /&gt;
&lt;br /&gt;
// ---- CONFIG WIFI DOMESTIQUE PAR DÉFAUT ----&lt;br /&gt;
const char* DEFAULT_STA_SSID = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* DEFAULT_STA_PASS = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- CONFIG AP ----&lt;br /&gt;
const char* AP_SSID = &amp;quot;XIAO_Config&amp;quot;;&lt;br /&gt;
const char* AP_PASS = &amp;quot;12345678&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
String ssid, pass;&lt;br /&gt;
&lt;br /&gt;
// ---- PAGE HTML DE CONFIG WIFI ----&lt;br /&gt;
const char* configPage = R&amp;quot;rawliteral(&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;fr&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;title&amp;gt;Configuration WiFi&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
  body {&lt;br /&gt;
    font-family: Arial, sans-serif;&lt;br /&gt;
    background: linear-gradient(135deg, #4c8bf5, #6dd5fa);&lt;br /&gt;
    height: 100vh;&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .card {&lt;br /&gt;
    background: white;&lt;br /&gt;
    padding: 25px;&lt;br /&gt;
    border-radius: 15px;&lt;br /&gt;
    width: 320px;&lt;br /&gt;
    box-shadow: 0 8px 20px rgba(0,0,0,0.2);&lt;br /&gt;
    text-align: center;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  h2 {&lt;br /&gt;
    margin-top: 0;&lt;br /&gt;
    color: #333;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  input[type=&amp;quot;text&amp;quot;], input[type=&amp;quot;password&amp;quot;] {&lt;br /&gt;
    width: 90%;&lt;br /&gt;
    padding: 10px;&lt;br /&gt;
    margin: 10px 0;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    border: 1px solid #aaa;&lt;br /&gt;
    font-size: 16px;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  input[type=&amp;quot;submit&amp;quot;] {&lt;br /&gt;
    background: #4c8bf5;&lt;br /&gt;
    color: white;&lt;br /&gt;
    border: none;&lt;br /&gt;
    padding: 12px 20px;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    font-size: 16px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    margin-top: 10px;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  input[type=&amp;quot;submit&amp;quot;]:hover {&lt;br /&gt;
    background: #3a6fd8;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .links {&lt;br /&gt;
    margin-top: 15px;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .links a {&lt;br /&gt;
    color: #4c8bf5;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .links a:hover {&lt;br /&gt;
    text-decoration: underline;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;card&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;h2&amp;gt;Configuration WiFi&amp;lt;/h2&amp;gt;&lt;br /&gt;
    &amp;lt;form action=&amp;quot;/save&amp;quot; method=&amp;quot;POST&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;ssid&amp;quot; placeholder=&amp;quot;Nom du réseau (SSID)&amp;quot; required&amp;gt;&lt;br /&gt;
      &amp;lt;input type=&amp;quot;password&amp;quot; name=&amp;quot;pass&amp;quot; placeholder=&amp;quot;Mot de passe&amp;quot; required&amp;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;div class=&amp;quot;links&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;a href=&amp;quot;/status&amp;quot;&amp;gt;Voir le statut&amp;lt;/a&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;/div&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;
// ---- HANDLERS HTTP ----&lt;br /&gt;
&lt;br /&gt;
void handleRoot() {&lt;br /&gt;
  server.send(200, &amp;quot;text/html&amp;quot;, configPage);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void handleSave() {&lt;br /&gt;
  if (server.hasArg(&amp;quot;ssid&amp;quot;) &amp;amp;&amp;amp; server.hasArg(&amp;quot;pass&amp;quot;)) {&lt;br /&gt;
    prefs.begin(&amp;quot;wifi&amp;quot;, false);&lt;br /&gt;
    prefs.putString(&amp;quot;ssid&amp;quot;, server.arg(&amp;quot;ssid&amp;quot;));&lt;br /&gt;
    prefs.putString(&amp;quot;pass&amp;quot;, server.arg(&amp;quot;pass&amp;quot;));&lt;br /&gt;
    prefs.end();&lt;br /&gt;
&lt;br /&gt;
    String page = R&amp;quot;rawliteral(&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;fr&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;title&amp;gt;Paramètres enregistrés&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
  body {&lt;br /&gt;
    font-family: Arial, sans-serif;&lt;br /&gt;
    background: linear-gradient(135deg, #4c8bf5, #6dd5fa);&lt;br /&gt;
    height: 100vh;&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
  }&lt;br /&gt;
  .card {&lt;br /&gt;
    background: white;&lt;br /&gt;
    padding: 25px;&lt;br /&gt;
    border-radius: 15px;&lt;br /&gt;
    width: 320px;&lt;br /&gt;
    box-shadow: 0 8px 20px rgba(0,0,0,0.2);&lt;br /&gt;
    text-align: center;&lt;br /&gt;
  }&lt;br /&gt;
  h2 { margin-top: 0; color: #333; }&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;card&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;h2&amp;gt;Paramètres sauvegardés&amp;lt;/h2&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;L&amp;#039;appareil va redémarrer&amp;lt;br&amp;gt;et tenter de se connecter au nouveau réseau.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/div&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;
    server.send(200, &amp;quot;text/html&amp;quot;, page);&lt;br /&gt;
    delay(1500);&lt;br /&gt;
    ESP.restart();&lt;br /&gt;
  } else {&lt;br /&gt;
    server.send(400, &amp;quot;text/plain&amp;quot;, &amp;quot;SSID ou mot de passe manquant&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void handleStatus() {&lt;br /&gt;
  String mode = &amp;quot;&amp;quot;;&lt;br /&gt;
  wifi_mode_t currentMode = WiFi.getMode();&lt;br /&gt;
&lt;br /&gt;
  if (currentMode == WIFI_STA) mode = &amp;quot;Station (STA)&amp;quot;;&lt;br /&gt;
  else if (currentMode == WIFI_AP) mode = &amp;quot;Point d&amp;#039;accès (AP)&amp;quot;;&lt;br /&gt;
  else if (currentMode == WIFI_AP_STA) mode = &amp;quot;AP + Station (AP_STA)&amp;quot;;&lt;br /&gt;
  else mode = &amp;quot;Inconnu&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  String page = R&amp;quot;rawliteral(&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;fr&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;title&amp;gt;Statut WiFi&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
  body {&lt;br /&gt;
    font-family: Arial, sans-serif;&lt;br /&gt;
    background: linear-gradient(135deg, #6dd5fa, #4c8bf5);&lt;br /&gt;
    height: 100vh;&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .card {&lt;br /&gt;
    background: white;&lt;br /&gt;
    padding: 25px;&lt;br /&gt;
    border-radius: 15px;&lt;br /&gt;
    width: 350px;&lt;br /&gt;
    box-shadow: 0 8px 20px rgba(0,0,0,0.2);&lt;br /&gt;
    text-align: center;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  h2 {&lt;br /&gt;
    margin-top: 0;&lt;br /&gt;
    color: #333;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .info {&lt;br /&gt;
    text-align: left;&lt;br /&gt;
    margin-top: 15px;&lt;br /&gt;
    font-size: 16px;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .info div {&lt;br /&gt;
    margin-bottom: 8px;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .btn {&lt;br /&gt;
    margin-top: 15px;&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    padding: 10px 20px;&lt;br /&gt;
    background: #4c8bf5;&lt;br /&gt;
    color: white;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .btn:hover {&lt;br /&gt;
    background: #3a6fd8;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .btn-danger {&lt;br /&gt;
    background: #f56d6d;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .btn-danger:hover {&lt;br /&gt;
    background: #d84a4a;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;card&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;h2&amp;gt;Statut WiFi&amp;lt;/h2&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;info&amp;quot;&amp;gt;&lt;br /&gt;
)rawliteral&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  page += &amp;quot;&amp;lt;div&amp;gt;&amp;lt;b&amp;gt;Mode :&amp;lt;/b&amp;gt; &amp;quot; + mode + &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
  page += &amp;quot;&amp;lt;div&amp;gt;&amp;lt;b&amp;gt;IP (STA) :&amp;lt;/b&amp;gt; &amp;quot; + WiFi.localIP().toString() + &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
  page += &amp;quot;&amp;lt;div&amp;gt;&amp;lt;b&amp;gt;IP (AP) :&amp;lt;/b&amp;gt; &amp;quot; + WiFi.softAPIP().toString() + &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  if (WiFi.status() == WL_CONNECTED) {&lt;br /&gt;
    page += &amp;quot;&amp;lt;div&amp;gt;&amp;lt;b&amp;gt;RSSI :&amp;lt;/b&amp;gt; &amp;quot; + String(WiFi.RSSI()) + &amp;quot; dBm&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
  } else {&lt;br /&gt;
    page += &amp;quot;&amp;lt;div&amp;gt;&amp;lt;b&amp;gt;RSSI :&amp;lt;/b&amp;gt; Non connecté&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  unsigned long ms = millis();&lt;br /&gt;
  unsigned long sec = ms / 1000;&lt;br /&gt;
  unsigned long min = sec / 60;&lt;br /&gt;
  unsigned long hr  = min / 60;&lt;br /&gt;
&lt;br /&gt;
  page += &amp;quot;&amp;lt;div&amp;gt;&amp;lt;b&amp;gt;Uptime :&amp;lt;/b&amp;gt; &amp;quot; + String(hr) + &amp;quot;h &amp;quot; + String(min % 60) + &amp;quot;m &amp;quot; + String(sec % 60) + &amp;quot;s&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  page += R&amp;quot;rawliteral(&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;a class=&amp;quot;btn&amp;quot; href=&amp;quot;/&amp;quot;&amp;gt;Config WiFi&amp;lt;/a&amp;gt;&lt;br /&gt;
    &amp;lt;a class=&amp;quot;btn&amp;quot; href=&amp;quot;/reboot&amp;quot;&amp;gt;Redémarrer&amp;lt;/a&amp;gt;&lt;br /&gt;
    &amp;lt;a class=&amp;quot;btn btn-danger&amp;quot; href=&amp;quot;/resetwifi&amp;quot;&amp;gt;Reset Wi‑Fi&amp;lt;/a&amp;gt;&lt;br /&gt;
  &amp;lt;/div&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;
  server.send(200, &amp;quot;text/html&amp;quot;, page);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void handleReboot() {&lt;br /&gt;
  String page = R&amp;quot;rawliteral(&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;fr&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;title&amp;gt;Redémarrage&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
  body {&lt;br /&gt;
    font-family: Arial, sans-serif;&lt;br /&gt;
    background: linear-gradient(135deg, #4c8bf5, #6dd5fa);&lt;br /&gt;
    height: 100vh;&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .card {&lt;br /&gt;
    background: white;&lt;br /&gt;
    padding: 25px;&lt;br /&gt;
    border-radius: 15px;&lt;br /&gt;
    width: 320px;&lt;br /&gt;
    box-shadow: 0 8px 20px rgba(0,0,0,0.2);&lt;br /&gt;
    text-align: center;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  h2 {&lt;br /&gt;
    margin-top: 0;&lt;br /&gt;
    color: #333;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;card&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;h2&amp;gt;Redémarrage en cours…&amp;lt;/h2&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;L&amp;#039;appareil va redémarrer dans quelques secondes.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/div&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;
  server.send(200, &amp;quot;text/html&amp;quot;, page);&lt;br /&gt;
  delay(1500);&lt;br /&gt;
  ESP.restart();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void handleResetWiFi() {&lt;br /&gt;
  prefs.begin(&amp;quot;wifi&amp;quot;, false);&lt;br /&gt;
  prefs.clear();&lt;br /&gt;
  prefs.end();&lt;br /&gt;
&lt;br /&gt;
  String page = R&amp;quot;rawliteral(&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;fr&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;title&amp;gt;Reset WiFi&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
  body {&lt;br /&gt;
    font-family: Arial, sans-serif;&lt;br /&gt;
    background: linear-gradient(135deg, #f56d6d, #fa9a6d);&lt;br /&gt;
    height: 100vh;&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .card {&lt;br /&gt;
    background: white;&lt;br /&gt;
    padding: 25px;&lt;br /&gt;
    border-radius: 15px;&lt;br /&gt;
    width: 320px;&lt;br /&gt;
    box-shadow: 0 8px 20px rgba(0,0,0,0.2);&lt;br /&gt;
    text-align: center;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  h2 {&lt;br /&gt;
    margin-top: 0;&lt;br /&gt;
    color: #333;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;card&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;h2&amp;gt;Réinitialisation WiFi…&amp;lt;/h2&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Les paramètres WiFi ont été effacés.&amp;lt;br&amp;gt;Redémarrage en cours…&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/div&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;
  server.send(200, &amp;quot;text/html&amp;quot;, page);&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;\n===== RESET WIFI =====&amp;quot;);&lt;br /&gt;
  Serial.println(&amp;quot;IP STA : &amp;quot; + WiFi.localIP().toString());&lt;br /&gt;
  Serial.println(&amp;quot;IP AP  : &amp;quot; + WiFi.softAPIP().toString());&lt;br /&gt;
  Serial.println(&amp;quot;AP SSID : &amp;quot; + String(AP_SSID));&lt;br /&gt;
  Serial.println(&amp;quot;AP PASS : &amp;quot; + String(AP_PASS));&lt;br /&gt;
&lt;br /&gt;
  if (WiFi.status() == WL_CONNECTED)&lt;br /&gt;
    Serial.println(&amp;quot;RSSI : &amp;quot; + String(WiFi.RSSI()) + &amp;quot; dBm&amp;quot;);&lt;br /&gt;
  else&lt;br /&gt;
    Serial.println(&amp;quot;RSSI : Non connecté&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;=======================\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  delay(1500);&lt;br /&gt;
  ESP.restart();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ---- LOGIQUE WIFI ----&lt;br /&gt;
&lt;br /&gt;
bool connectToWiFi() {&lt;br /&gt;
  prefs.begin(&amp;quot;wifi&amp;quot;, true);&lt;br /&gt;
  ssid = prefs.getString(&amp;quot;ssid&amp;quot;, DEFAULT_STA_SSID);&lt;br /&gt;
  pass = prefs.getString(&amp;quot;pass&amp;quot;, DEFAULT_STA_PASS);&lt;br /&gt;
  prefs.end();&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;Connexion à &amp;quot;); Serial.println(ssid);&lt;br /&gt;
&lt;br /&gt;
  WiFi.begin(ssid.c_str(), pass.c_str());&lt;br /&gt;
&lt;br /&gt;
  unsigned long start = millis();&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED &amp;amp;&amp;amp; millis() - start &amp;lt; 10000) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  if (WiFi.status() == WL_CONNECTED) {&lt;br /&gt;
    Serial.println(&amp;quot;\n[WiFi] Connecté en STA&amp;quot;);&lt;br /&gt;
    Serial.println(&amp;quot;IP STA : &amp;quot; + WiFi.localIP().toString());&lt;br /&gt;
    Serial.println(&amp;quot;RSSI   : &amp;quot; + String(WiFi.RSSI()) + &amp;quot; dBm&amp;quot;);&lt;br /&gt;
    return true;&lt;br /&gt;
  } else {&lt;br /&gt;
    Serial.println(&amp;quot;\n[WiFi] Échec connexion STA&amp;quot;);&lt;br /&gt;
    return false;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ---- SETUP / LOOP ----&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
  delay(500);&lt;br /&gt;
  Serial.println(&amp;quot;\n==== DÉMARRAGE XIAO ESP32C3 ====&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  WiFi.mode(WIFI_AP_STA);&lt;br /&gt;
&lt;br /&gt;
  WiFi.softAP(AP_SSID, AP_PASS);&lt;br /&gt;
  Serial.println(&amp;quot;[WiFi] AP actif&amp;quot;);&lt;br /&gt;
  Serial.println(&amp;quot;  SSID : &amp;quot; + String(AP_SSID));&lt;br /&gt;
  Serial.println(&amp;quot;  PASS : &amp;quot; + String(AP_PASS));&lt;br /&gt;
  Serial.println(&amp;quot;  IP AP: &amp;quot; + WiFi.softAPIP().toString());&lt;br /&gt;
&lt;br /&gt;
  connectToWiFi();&lt;br /&gt;
&lt;br /&gt;
  server.on(&amp;quot;/&amp;quot;, handleRoot);&lt;br /&gt;
  server.on(&amp;quot;/save&amp;quot;, HTTP_POST, handleSave);&lt;br /&gt;
  server.on(&amp;quot;/status&amp;quot;, handleStatus);&lt;br /&gt;
  server.on(&amp;quot;/reboot&amp;quot;, handleReboot);&lt;br /&gt;
  server.on(&amp;quot;/resetwifi&amp;quot;, handleResetWiFi);&lt;br /&gt;
&lt;br /&gt;
  server.begin();&lt;br /&gt;
  Serial.println(&amp;quot;[HTTP] Serveur web démarré&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  initEPaper();   // ✅ Ajout&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  server.handleClient();&lt;br /&gt;
  updateEPaperTime();  // ✅ Ajout&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// Onglet TimeDisplayEPaper.h&lt;br /&gt;
#pragma once&lt;br /&gt;
#include &amp;lt;time.h&amp;gt;&lt;br /&gt;
#include &amp;lt;TFT_eSPI.h&amp;gt;&lt;br /&gt;
#include &amp;lt;SPI.h&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
EPaper epaper = EPaper();  // Pins définis dans User_Setup.h&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// ⚙️ Paramètres NTP&lt;br /&gt;
const char* ntpServer = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const long  gmtOffset_sec = 3600;       // +1h (Suisse en hiver)&lt;br /&gt;
const int   daylightOffset_sec = 3600;  // +1h (DST été)&lt;br /&gt;
&lt;br /&gt;
// Variables pour éviter scintillement&lt;br /&gt;
int lastMinute = -1;&lt;br /&gt;
&lt;br /&gt;
// --- Initialisation de l’e-paper ---&lt;br /&gt;
void initEPaper() {&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
  epaper.begin();&lt;br /&gt;
  epaper.setRotation(1);&lt;br /&gt;
  epaper.fillScreen(TFT_WHITE);&lt;br /&gt;
  epaper.setTextColor(TFT_BLACK, TFT_WHITE);&lt;br /&gt;
  epaper.update();&lt;br /&gt;
  epaper.sleep();&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
  // Initialisation NTP&lt;br /&gt;
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// --- Fonction pour dessiner un pictogramme Wi-Fi ---&lt;br /&gt;
void drawWiFiIcon(int x, int y, int rssi) {&lt;br /&gt;
  int bars = 0;&lt;br /&gt;
  if (rssi &amp;gt; -50) bars = 4;&lt;br /&gt;
  else if (rssi &amp;gt; -60) bars = 3;&lt;br /&gt;
  else if (rssi &amp;gt; -70) bars = 2;&lt;br /&gt;
  else if (rssi &amp;gt; -80) bars = 1;&lt;br /&gt;
  else bars = 0;&lt;br /&gt;
&lt;br /&gt;
  int barWidth = 6;&lt;br /&gt;
  int spacing = 3;&lt;br /&gt;
  for (int i = 0; i &amp;lt; 4; i++) {&lt;br /&gt;
    int barHeight = (i+1) * 6;&lt;br /&gt;
    int bx = x + i * (barWidth + spacing);&lt;br /&gt;
    int by = y + (24 - barHeight);&lt;br /&gt;
    if (i &amp;lt; bars) {&lt;br /&gt;
      epaper.fillRect(bx, by, barWidth, barHeight, TFT_BLACK);&lt;br /&gt;
    } else {&lt;br /&gt;
      epaper.drawRect(bx, by, barWidth, barHeight, TFT_BLACK);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// --- Mise à jour de l’affichage ---&lt;br /&gt;
void updateEPaperTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Erreur récupération heure NTP&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  if (timeinfo.tm_min != lastMinute) {&lt;br /&gt;
    lastMinute = timeinfo.tm_min;&lt;br /&gt;
&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
    epaper.fillScreen(TFT_WHITE);&lt;br /&gt;
&lt;br /&gt;
    // --- Affichage DATE ---&lt;br /&gt;
    epaper.setTextDatum(TC_DATUM);&lt;br /&gt;
    epaper.drawString(&lt;br /&gt;
      String(timeinfo.tm_mday) + &amp;quot;/&amp;quot; + &lt;br /&gt;
      String(timeinfo.tm_mon+1) + &amp;quot;/&amp;quot; + &lt;br /&gt;
      String(timeinfo.tm_year+1900),&lt;br /&gt;
      epaper.width()/2, 30, 4&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    // --- Affichage HEURE ---&lt;br /&gt;
    char buffer[6];&lt;br /&gt;
    sprintf(buffer, &amp;quot;%02d:%02d&amp;quot;, timeinfo.tm_hour, timeinfo.tm_min);&lt;br /&gt;
    epaper.setTextDatum(MC_DATUM);&lt;br /&gt;
    epaper.drawString(buffer, epaper.width()/2, epaper.height()/2, 7);&lt;br /&gt;
&lt;br /&gt;
    // --- Encadré infos réseau ---&lt;br /&gt;
    int boxX = 5;&lt;br /&gt;
    int boxY = epaper.height() - 70;&lt;br /&gt;
    int boxW = epaper.width() - 10;&lt;br /&gt;
    int boxH = 60;&lt;br /&gt;
&lt;br /&gt;
    epaper.fillRect(boxX, boxY, boxW, boxH, TFT_LIGHTGREY);&lt;br /&gt;
    epaper.drawRect(boxX, boxY, boxW, boxH, TFT_BLACK);&lt;br /&gt;
&lt;br /&gt;
    epaper.setTextColor(TFT_BLACK, TFT_LIGHTGREY);&lt;br /&gt;
    epaper.setTextDatum(TL_DATUM);&lt;br /&gt;
    epaper.drawString(&amp;quot;IP STA: &amp;quot; + WiFi.localIP().toString(), boxX + 10, boxY + 12, 2);&lt;br /&gt;
&lt;br /&gt;
    // --- Pictogramme Wi-Fi centré ---&lt;br /&gt;
    int iconX = boxX + (boxW/2) - 15;&lt;br /&gt;
    int iconY = boxY + 5;&lt;br /&gt;
    drawWiFiIcon(iconX, iconY, WiFi.RSSI());&lt;br /&gt;
&lt;br /&gt;
    // --- RSSI sous l’icône ---&lt;br /&gt;
    epaper.setTextDatum(TC_DATUM);&lt;br /&gt;
    epaper.drawString(&amp;quot;RSSI: &amp;quot; + String(WiFi.RSSI()) + &amp;quot; dBm&amp;quot;, boxX + boxW/2, boxY + 40, 2);&lt;br /&gt;
&lt;br /&gt;
    epaper.update();&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
    // --- Sortie série ---&lt;br /&gt;
    Serial.printf(&amp;quot;Heure actuelle : %02d:%02d:%02d\n&amp;quot;, &lt;br /&gt;
                  timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec);&lt;br /&gt;
    Serial.println(&amp;quot;IP STA : &amp;quot; + WiFi.localIP().toString());&lt;br /&gt;
    Serial.println(&amp;quot;RSSI   : &amp;quot; + String(WiFi.RSSI()) + &amp;quot; dBm&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// onglet driver.h&lt;br /&gt;
// driver.h file &lt;br /&gt;
#define BOARD_SCREEN_COMBO 505 // 1.54 inch monochrome ePaper Screen （SSD1681）&lt;br /&gt;
#define USE_XIAO_EPAPER_BREAKOUT_BOARD&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>144.2.107.134</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.myows.top/index.php?title=Wi-Fi-ESP32-E-Paper&amp;diff=2058</id>
		<title>Wi-Fi-ESP32-E-Paper</title>
		<link rel="alternate" type="text/html" href="https://wiki.myows.top/index.php?title=Wi-Fi-ESP32-E-Paper&amp;diff=2058"/>
		<updated>2025-12-20T00:03:59Z</updated>

		<summary type="html">&lt;p&gt;144.2.107.134: /* Code Wi-Fi &amp;amp; ESP32 &amp;amp; E-Paper 3 onglets */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Code Wi-Fi &amp;amp; ESP32 &amp;amp; E-Paper ===&lt;br /&gt;
&lt;br /&gt;
Wi-Fi-ESP32-E-Paper&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;lt;WebServer.h&amp;gt;&lt;br /&gt;
#include &amp;lt;Preferences.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Preferences prefs;&lt;br /&gt;
WebServer server(80);&lt;br /&gt;
&lt;br /&gt;
String ssid, pass;&lt;br /&gt;
&lt;br /&gt;
const char* configPage = 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;body&amp;gt;&lt;br /&gt;
    &amp;lt;h2&amp;gt;Configuration WiFi&amp;lt;/h2&amp;gt;&lt;br /&gt;
    &amp;lt;form action=&amp;quot;/save&amp;quot; method=&amp;quot;POST&amp;quot;&amp;gt;&lt;br /&gt;
      SSID: &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;ssid&amp;quot;&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
      Password: &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;pass&amp;quot;&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
      &amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Save&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;
void handleRoot() {&lt;br /&gt;
  server.send(200, &amp;quot;text/html&amp;quot;, configPage);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void handleSave() {&lt;br /&gt;
  if (server.hasArg(&amp;quot;ssid&amp;quot;) &amp;amp;&amp;amp; server.hasArg(&amp;quot;pass&amp;quot;)) {&lt;br /&gt;
    ssid = server.arg(&amp;quot;ssid&amp;quot;);&lt;br /&gt;
    pass = server.arg(&amp;quot;pass&amp;quot;);&lt;br /&gt;
    prefs.begin(&amp;quot;wifi&amp;quot;, false);&lt;br /&gt;
    prefs.putString(&amp;quot;ssid&amp;quot;, ssid);&lt;br /&gt;
    prefs.putString(&amp;quot;pass&amp;quot;, pass);&lt;br /&gt;
    prefs.end();&lt;br /&gt;
    server.send(200, &amp;quot;text/html&amp;quot;, &amp;quot;Paramètres sauvegardés. Redémarrage...&amp;quot;);&lt;br /&gt;
    delay(2000);&lt;br /&gt;
    ESP.restart();&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
bool connectToWiFi() {&lt;br /&gt;
  prefs.begin(&amp;quot;wifi&amp;quot;, true);&lt;br /&gt;
  ssid = prefs.getString(&amp;quot;ssid&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
  pass = prefs.getString(&amp;quot;pass&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
  prefs.end();&lt;br /&gt;
&lt;br /&gt;
  if (ssid == &amp;quot;&amp;quot;) return false;&lt;br /&gt;
&lt;br /&gt;
  WiFi.begin(ssid.c_str(), pass.c_str());&lt;br /&gt;
  Serial.print(&amp;quot;Connexion à &amp;quot;); Serial.println(ssid);&lt;br /&gt;
&lt;br /&gt;
  unsigned long start = millis();&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED &amp;amp;&amp;amp; millis() - start &amp;lt; 10000) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  return WiFi.status() == WL_CONNECTED;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void startAP() {&lt;br /&gt;
  WiFi.softAP(&amp;quot;XIAO_Config&amp;quot;, &amp;quot;12345678&amp;quot;);&lt;br /&gt;
  Serial.println(&amp;quot;AP démarré. IP: &amp;quot; + WiFi.softAPIP().toString());&lt;br /&gt;
  server.on(&amp;quot;/&amp;quot;, handleRoot);&lt;br /&gt;
  server.on(&amp;quot;/save&amp;quot;, HTTP_POST, handleSave);&lt;br /&gt;
  server.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  if (!connectToWiFi()) {&lt;br /&gt;
    Serial.println(&amp;quot;Échec connexion. Passage en mode AP.&amp;quot;);&lt;br /&gt;
    startAP();&lt;br /&gt;
  } else {&lt;br /&gt;
    Serial.println(&amp;quot;Connecté au WiFi. IP: &amp;quot; + WiFi.localIP().toString());&lt;br /&gt;
    // Ici vous pouvez lancer un serveur web normal ou autre logique&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  server.handleClient();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## ⚙️ Fonctionnement&lt;br /&gt;
- **Premier démarrage** : pas de SSID enregistré → le module crée un AP `XIAO_Config`.  &lt;br /&gt;
- **Page web** : accessible via l’IP du point d’accès (souvent `192.168.4.1`).  &lt;br /&gt;
- **Sauvegarde** : SSID et mot de passe sont stockés dans `Preferences`.  &lt;br /&gt;
- **Redémarrage** : le module tente de se connecter au Wi Fi enregistré.  &lt;br /&gt;
- **Fallback** : si la connexion échoue, retour en mode AP pour reconfigurer.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
- **Mode AP (point d’accès)** au démarrage → permet de configurer les paramètres Wi Fi via une page web.  &lt;br /&gt;
- **Sauvegarde des paramètres** (SSID, mot de passe, etc.) dans la mémoire non volatile (Preferences).  &lt;br /&gt;
- **Redémarrage automatique en mode station** → le XIAO se connecte au réseau configuré.  &lt;br /&gt;
- **Fallback** : si la connexion échoue, il revient en mode AP pour reconfigurer.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Code Modifié&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;lt;WebServer.h&amp;gt;&lt;br /&gt;
#include &amp;lt;Preferences.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Preferences prefs;&lt;br /&gt;
WebServer server(80);&lt;br /&gt;
&lt;br /&gt;
// ---- CONFIG WIFI DOMESTIQUE PAR DÉFAUT ----&lt;br /&gt;
const char* DEFAULT_STA_SSID = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* DEFAULT_STA_PASS = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- CONFIG AP ----&lt;br /&gt;
const char* AP_SSID = &amp;quot;XIAO_Config&amp;quot;;&lt;br /&gt;
const char* AP_PASS = &amp;quot;12345678&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
String ssid, pass;&lt;br /&gt;
&lt;br /&gt;
// ---- PAGE HTML DE CONFIG WIFI ----&lt;br /&gt;
const char* configPage = R&amp;quot;rawliteral(&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;fr&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;title&amp;gt;Configuration WiFi&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
  body {&lt;br /&gt;
    font-family: Arial, sans-serif;&lt;br /&gt;
    background: linear-gradient(135deg, #4c8bf5, #6dd5fa);&lt;br /&gt;
    height: 100vh;&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .card {&lt;br /&gt;
    background: white;&lt;br /&gt;
    padding: 25px;&lt;br /&gt;
    border-radius: 15px;&lt;br /&gt;
    width: 320px;&lt;br /&gt;
    box-shadow: 0 8px 20px rgba(0,0,0,0.2);&lt;br /&gt;
    text-align: center;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  h2 {&lt;br /&gt;
    margin-top: 0;&lt;br /&gt;
    color: #333;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  input[type=&amp;quot;text&amp;quot;], input[type=&amp;quot;password&amp;quot;] {&lt;br /&gt;
    width: 90%;&lt;br /&gt;
    padding: 10px;&lt;br /&gt;
    margin: 10px 0;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    border: 1px solid #aaa;&lt;br /&gt;
    font-size: 16px;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  input[type=&amp;quot;submit&amp;quot;] {&lt;br /&gt;
    background: #4c8bf5;&lt;br /&gt;
    color: white;&lt;br /&gt;
    border: none;&lt;br /&gt;
    padding: 12px 20px;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    font-size: 16px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    margin-top: 10px;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  input[type=&amp;quot;submit&amp;quot;]:hover {&lt;br /&gt;
    background: #3a6fd8;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .links {&lt;br /&gt;
    margin-top: 15px;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .links a {&lt;br /&gt;
    color: #4c8bf5;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .links a:hover {&lt;br /&gt;
    text-decoration: underline;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;card&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;h2&amp;gt;Configuration WiFi&amp;lt;/h2&amp;gt;&lt;br /&gt;
    &amp;lt;form action=&amp;quot;/save&amp;quot; method=&amp;quot;POST&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;ssid&amp;quot; placeholder=&amp;quot;Nom du réseau (SSID)&amp;quot; required&amp;gt;&lt;br /&gt;
      &amp;lt;input type=&amp;quot;password&amp;quot; name=&amp;quot;pass&amp;quot; placeholder=&amp;quot;Mot de passe&amp;quot; required&amp;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;div class=&amp;quot;links&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;a href=&amp;quot;/status&amp;quot;&amp;gt;Voir le statut&amp;lt;/a&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;/div&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;
// ---- HANDLERS HTTP ----&lt;br /&gt;
&lt;br /&gt;
void handleRoot() {&lt;br /&gt;
  server.send(200, &amp;quot;text/html&amp;quot;, configPage);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void handleSave() {&lt;br /&gt;
  if (server.hasArg(&amp;quot;ssid&amp;quot;) &amp;amp;&amp;amp; server.hasArg(&amp;quot;pass&amp;quot;)) {&lt;br /&gt;
    prefs.begin(&amp;quot;wifi&amp;quot;, false);&lt;br /&gt;
    prefs.putString(&amp;quot;ssid&amp;quot;, server.arg(&amp;quot;ssid&amp;quot;));&lt;br /&gt;
    prefs.putString(&amp;quot;pass&amp;quot;, server.arg(&amp;quot;pass&amp;quot;));&lt;br /&gt;
    prefs.end();&lt;br /&gt;
&lt;br /&gt;
    String page = R&amp;quot;rawliteral(&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;fr&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;title&amp;gt;Paramètres enregistrés&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
  body {&lt;br /&gt;
    font-family: Arial, sans-serif;&lt;br /&gt;
    background: linear-gradient(135deg, #4c8bf5, #6dd5fa);&lt;br /&gt;
    height: 100vh;&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
  }&lt;br /&gt;
  .card {&lt;br /&gt;
    background: white;&lt;br /&gt;
    padding: 25px;&lt;br /&gt;
    border-radius: 15px;&lt;br /&gt;
    width: 320px;&lt;br /&gt;
    box-shadow: 0 8px 20px rgba(0,0,0,0.2);&lt;br /&gt;
    text-align: center;&lt;br /&gt;
  }&lt;br /&gt;
  h2 { margin-top: 0; color: #333; }&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;card&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;h2&amp;gt;Paramètres sauvegardés&amp;lt;/h2&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;L&amp;#039;appareil va redémarrer&amp;lt;br&amp;gt;et tenter de se connecter au nouveau réseau.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/div&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;
    server.send(200, &amp;quot;text/html&amp;quot;, page);&lt;br /&gt;
    delay(1500);&lt;br /&gt;
    ESP.restart();&lt;br /&gt;
  } else {&lt;br /&gt;
    server.send(400, &amp;quot;text/plain&amp;quot;, &amp;quot;SSID ou mot de passe manquant&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void handleStatus() {&lt;br /&gt;
  String mode = &amp;quot;&amp;quot;;&lt;br /&gt;
  wifi_mode_t currentMode = WiFi.getMode();&lt;br /&gt;
&lt;br /&gt;
  if (currentMode == WIFI_STA) mode = &amp;quot;Station (STA)&amp;quot;;&lt;br /&gt;
  else if (currentMode == WIFI_AP) mode = &amp;quot;Point d&amp;#039;accès (AP)&amp;quot;;&lt;br /&gt;
  else if (currentMode == WIFI_AP_STA) mode = &amp;quot;AP + Station (AP_STA)&amp;quot;;&lt;br /&gt;
  else mode = &amp;quot;Inconnu&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  String page = R&amp;quot;rawliteral(&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;fr&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;title&amp;gt;Statut WiFi&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
  body {&lt;br /&gt;
    font-family: Arial, sans-serif;&lt;br /&gt;
    background: linear-gradient(135deg, #6dd5fa, #4c8bf5);&lt;br /&gt;
    height: 100vh;&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .card {&lt;br /&gt;
    background: white;&lt;br /&gt;
    padding: 25px;&lt;br /&gt;
    border-radius: 15px;&lt;br /&gt;
    width: 350px;&lt;br /&gt;
    box-shadow: 0 8px 20px rgba(0,0,0,0.2);&lt;br /&gt;
    text-align: center;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  h2 {&lt;br /&gt;
    margin-top: 0;&lt;br /&gt;
    color: #333;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .info {&lt;br /&gt;
    text-align: left;&lt;br /&gt;
    margin-top: 15px;&lt;br /&gt;
    font-size: 16px;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .info div {&lt;br /&gt;
    margin-bottom: 8px;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .btn {&lt;br /&gt;
    margin-top: 15px;&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    padding: 10px 20px;&lt;br /&gt;
    background: #4c8bf5;&lt;br /&gt;
    color: white;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .btn:hover {&lt;br /&gt;
    background: #3a6fd8;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .btn-danger {&lt;br /&gt;
    background: #f56d6d;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .btn-danger:hover {&lt;br /&gt;
    background: #d84a4a;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;card&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;h2&amp;gt;Statut WiFi&amp;lt;/h2&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;info&amp;quot;&amp;gt;&lt;br /&gt;
)rawliteral&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  page += &amp;quot;&amp;lt;div&amp;gt;&amp;lt;b&amp;gt;Mode :&amp;lt;/b&amp;gt; &amp;quot; + mode + &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
  page += &amp;quot;&amp;lt;div&amp;gt;&amp;lt;b&amp;gt;IP (STA) :&amp;lt;/b&amp;gt; &amp;quot; + WiFi.localIP().toString() + &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
  page += &amp;quot;&amp;lt;div&amp;gt;&amp;lt;b&amp;gt;IP (AP) :&amp;lt;/b&amp;gt; &amp;quot; + WiFi.softAPIP().toString() + &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  if (WiFi.status() == WL_CONNECTED) {&lt;br /&gt;
    page += &amp;quot;&amp;lt;div&amp;gt;&amp;lt;b&amp;gt;RSSI :&amp;lt;/b&amp;gt; &amp;quot; + String(WiFi.RSSI()) + &amp;quot; dBm&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
  } else {&lt;br /&gt;
    page += &amp;quot;&amp;lt;div&amp;gt;&amp;lt;b&amp;gt;RSSI :&amp;lt;/b&amp;gt; Non connecté&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  unsigned long ms = millis();&lt;br /&gt;
  unsigned long sec = ms / 1000;&lt;br /&gt;
  unsigned long min = sec / 60;&lt;br /&gt;
  unsigned long hr  = min / 60;&lt;br /&gt;
&lt;br /&gt;
  page += &amp;quot;&amp;lt;div&amp;gt;&amp;lt;b&amp;gt;Uptime :&amp;lt;/b&amp;gt; &amp;quot; + String(hr) + &amp;quot;h &amp;quot; + String(min % 60) + &amp;quot;m &amp;quot; + String(sec % 60) + &amp;quot;s&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  page += R&amp;quot;rawliteral(&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;a class=&amp;quot;btn&amp;quot; href=&amp;quot;/&amp;quot;&amp;gt;Config WiFi&amp;lt;/a&amp;gt;&lt;br /&gt;
    &amp;lt;a class=&amp;quot;btn&amp;quot; href=&amp;quot;/reboot&amp;quot;&amp;gt;Redémarrer&amp;lt;/a&amp;gt;&lt;br /&gt;
    &amp;lt;a class=&amp;quot;btn btn-danger&amp;quot; href=&amp;quot;/resetwifi&amp;quot;&amp;gt;Reset Wi‑Fi&amp;lt;/a&amp;gt;&lt;br /&gt;
  &amp;lt;/div&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;
  server.send(200, &amp;quot;text/html&amp;quot;, page);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void handleReboot() {&lt;br /&gt;
  String page = R&amp;quot;rawliteral(&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;fr&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;title&amp;gt;Redémarrage&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
  body {&lt;br /&gt;
    font-family: Arial, sans-serif;&lt;br /&gt;
    background: linear-gradient(135deg, #4c8bf5, #6dd5fa);&lt;br /&gt;
    height: 100vh;&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .card {&lt;br /&gt;
    background: white;&lt;br /&gt;
    padding: 25px;&lt;br /&gt;
    border-radius: 15px;&lt;br /&gt;
    width: 320px;&lt;br /&gt;
    box-shadow: 0 8px 20px rgba(0,0,0,0.2);&lt;br /&gt;
    text-align: center;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  h2 {&lt;br /&gt;
    margin-top: 0;&lt;br /&gt;
    color: #333;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;card&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;h2&amp;gt;Redémarrage en cours…&amp;lt;/h2&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;L&amp;#039;appareil va redémarrer dans quelques secondes.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/div&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;
  server.send(200, &amp;quot;text/html&amp;quot;, page);&lt;br /&gt;
  delay(1500);&lt;br /&gt;
  ESP.restart();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void handleResetWiFi() {&lt;br /&gt;
  // Effacer les identifiants WiFi stockés&lt;br /&gt;
  prefs.begin(&amp;quot;wifi&amp;quot;, false);&lt;br /&gt;
  prefs.clear();&lt;br /&gt;
  prefs.end();&lt;br /&gt;
&lt;br /&gt;
  String page = R&amp;quot;rawliteral(&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;fr&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;title&amp;gt;Reset WiFi&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
  body {&lt;br /&gt;
    font-family: Arial, sans-serif;&lt;br /&gt;
    background: linear-gradient(135deg, #f56d6d, #fa9a6d);&lt;br /&gt;
    height: 100vh;&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .card {&lt;br /&gt;
    background: white;&lt;br /&gt;
    padding: 25px;&lt;br /&gt;
    border-radius: 15px;&lt;br /&gt;
    width: 320px;&lt;br /&gt;
    box-shadow: 0 8px 20px rgba(0,0,0,0.2);&lt;br /&gt;
    text-align: center;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  h2 {&lt;br /&gt;
    margin-top: 0;&lt;br /&gt;
    color: #333;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;card&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;h2&amp;gt;Réinitialisation WiFi…&amp;lt;/h2&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Les paramètres WiFi ont été effacés.&amp;lt;br&amp;gt;Redémarrage en cours…&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/div&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;
  server.send(200, &amp;quot;text/html&amp;quot;, page);&lt;br /&gt;
&lt;br /&gt;
  // Résumé sur le moniteur série&lt;br /&gt;
  Serial.println(&amp;quot;\n===== RESET WIFI =====&amp;quot;);&lt;br /&gt;
  Serial.println(&amp;quot;IP STA : &amp;quot; + WiFi.localIP().toString());&lt;br /&gt;
  Serial.println(&amp;quot;IP AP  : &amp;quot; + WiFi.softAPIP().toString());&lt;br /&gt;
  Serial.println(&amp;quot;AP SSID : &amp;quot; + String(AP_SSID));&lt;br /&gt;
  Serial.println(&amp;quot;AP PASS : &amp;quot; + String(AP_PASS));&lt;br /&gt;
&lt;br /&gt;
  if (WiFi.status() == WL_CONNECTED)&lt;br /&gt;
    Serial.println(&amp;quot;RSSI : &amp;quot; + String(WiFi.RSSI()) + &amp;quot; dBm&amp;quot;);&lt;br /&gt;
  else&lt;br /&gt;
    Serial.println(&amp;quot;RSSI : Non connecté&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;=======================\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  delay(1500);&lt;br /&gt;
  ESP.restart();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ---- LOGIQUE WIFI ----&lt;br /&gt;
&lt;br /&gt;
bool connectToWiFi() {&lt;br /&gt;
  // Charger les valeurs enregistrées (ou défaut)&lt;br /&gt;
  prefs.begin(&amp;quot;wifi&amp;quot;, true);&lt;br /&gt;
  ssid = prefs.getString(&amp;quot;ssid&amp;quot;, DEFAULT_STA_SSID);&lt;br /&gt;
  pass = prefs.getString(&amp;quot;pass&amp;quot;, DEFAULT_STA_PASS);&lt;br /&gt;
  prefs.end();&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;Connexion à &amp;quot;); Serial.println(ssid);&lt;br /&gt;
&lt;br /&gt;
  WiFi.begin(ssid.c_str(), pass.c_str());&lt;br /&gt;
&lt;br /&gt;
  unsigned long start = millis();&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED &amp;amp;&amp;amp; millis() - start &amp;lt; 10000) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  if (WiFi.status() == WL_CONNECTED) {&lt;br /&gt;
    Serial.println(&amp;quot;\n[WiFi] Connecté en STA&amp;quot;);&lt;br /&gt;
    Serial.println(&amp;quot;IP STA : &amp;quot; + WiFi.localIP().toString());&lt;br /&gt;
    Serial.println(&amp;quot;RSSI   : &amp;quot; + String(WiFi.RSSI()) + &amp;quot; dBm&amp;quot;);&lt;br /&gt;
    return true;&lt;br /&gt;
  } else {&lt;br /&gt;
    Serial.println(&amp;quot;\n[WiFi] Échec connexion STA&amp;quot;);&lt;br /&gt;
    return false;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ---- SETUP / LOOP ----&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
  delay(500);&lt;br /&gt;
  Serial.println(&amp;quot;\n==== DÉMARRAGE XIAO ESP32C3 ====&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Mode AP + STA&lt;br /&gt;
  WiFi.mode(WIFI_AP_STA);&lt;br /&gt;
&lt;br /&gt;
  // Lancer AP&lt;br /&gt;
  WiFi.softAP(AP_SSID, AP_PASS);&lt;br /&gt;
  Serial.println(&amp;quot;[WiFi] AP actif&amp;quot;);&lt;br /&gt;
  Serial.println(&amp;quot;  SSID : &amp;quot; + String(AP_SSID));&lt;br /&gt;
  Serial.println(&amp;quot;  PASS : &amp;quot; + String(AP_PASS));&lt;br /&gt;
  Serial.println(&amp;quot;  IP AP: &amp;quot; + WiFi.softAPIP().toString());&lt;br /&gt;
&lt;br /&gt;
  // Tenter connexion STA&lt;br /&gt;
  connectToWiFi();&lt;br /&gt;
&lt;br /&gt;
  // Routes HTTP&lt;br /&gt;
  server.on(&amp;quot;/&amp;quot;, handleRoot);&lt;br /&gt;
  server.on(&amp;quot;/save&amp;quot;, HTTP_POST, handleSave);&lt;br /&gt;
  server.on(&amp;quot;/status&amp;quot;, handleStatus);&lt;br /&gt;
  server.on(&amp;quot;/reboot&amp;quot;, handleReboot);&lt;br /&gt;
  server.on(&amp;quot;/resetwifi&amp;quot;, handleResetWiFi);&lt;br /&gt;
&lt;br /&gt;
  server.begin();&lt;br /&gt;
  Serial.println(&amp;quot;[HTTP] Serveur web démarré&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  server.handleClient();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
✅ Mode AP + STA simultané&lt;br /&gt;
&lt;br /&gt;
✅ STA avec SSID/mot de passe par défaut, surchargeables via la page de config&lt;br /&gt;
&lt;br /&gt;
✅ AP fixe : SSID XIAO_Config / mot de passe 12345678&lt;br /&gt;
&lt;br /&gt;
✅ Page de configuration Wi‑Fi stylée (/)&lt;br /&gt;
&lt;br /&gt;
✅ Page de statut (/status) : IP STA, IP AP, RSSI, mode, uptime&lt;br /&gt;
&lt;br /&gt;
✅ Bouton Reboot (/reboot)&lt;br /&gt;
&lt;br /&gt;
✅ Bouton Reset Wi‑Fi (/resetwifi) qui efface Preferences + reboot&lt;br /&gt;
&lt;br /&gt;
✅ Résumé sur le moniteur série au reset Wi‑Fi&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Code Wi-Fi &amp;amp; ESP32 &amp;amp; E-Paper 3 onglets ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;lt;WebServer.h&amp;gt;&lt;br /&gt;
#include &amp;lt;Preferences.h&amp;gt;&lt;br /&gt;
#include &amp;quot;TimeDisplayEPaper.h&amp;quot;   // ✅ Ajout pour l’e-paper&lt;br /&gt;
&lt;br /&gt;
Preferences prefs;&lt;br /&gt;
WebServer server(80);&lt;br /&gt;
&lt;br /&gt;
// ---- CONFIG WIFI DOMESTIQUE PAR DÉFAUT ----&lt;br /&gt;
const char* DEFAULT_STA_SSID = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* DEFAULT_STA_PASS = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- CONFIG AP ----&lt;br /&gt;
const char* AP_SSID = &amp;quot;XIAO_Config&amp;quot;;&lt;br /&gt;
const char* AP_PASS = &amp;quot;12345678&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
String ssid, pass;&lt;br /&gt;
&lt;br /&gt;
// ---- PAGE HTML DE CONFIG WIFI ----&lt;br /&gt;
const char* configPage = R&amp;quot;rawliteral(&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;fr&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;title&amp;gt;Configuration WiFi&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
  body {&lt;br /&gt;
    font-family: Arial, sans-serif;&lt;br /&gt;
    background: linear-gradient(135deg, #4c8bf5, #6dd5fa);&lt;br /&gt;
    height: 100vh;&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .card {&lt;br /&gt;
    background: white;&lt;br /&gt;
    padding: 25px;&lt;br /&gt;
    border-radius: 15px;&lt;br /&gt;
    width: 320px;&lt;br /&gt;
    box-shadow: 0 8px 20px rgba(0,0,0,0.2);&lt;br /&gt;
    text-align: center;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  h2 {&lt;br /&gt;
    margin-top: 0;&lt;br /&gt;
    color: #333;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  input[type=&amp;quot;text&amp;quot;], input[type=&amp;quot;password&amp;quot;] {&lt;br /&gt;
    width: 90%;&lt;br /&gt;
    padding: 10px;&lt;br /&gt;
    margin: 10px 0;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    border: 1px solid #aaa;&lt;br /&gt;
    font-size: 16px;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  input[type=&amp;quot;submit&amp;quot;] {&lt;br /&gt;
    background: #4c8bf5;&lt;br /&gt;
    color: white;&lt;br /&gt;
    border: none;&lt;br /&gt;
    padding: 12px 20px;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    font-size: 16px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    margin-top: 10px;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  input[type=&amp;quot;submit&amp;quot;]:hover {&lt;br /&gt;
    background: #3a6fd8;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .links {&lt;br /&gt;
    margin-top: 15px;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .links a {&lt;br /&gt;
    color: #4c8bf5;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .links a:hover {&lt;br /&gt;
    text-decoration: underline;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;card&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;h2&amp;gt;Configuration WiFi&amp;lt;/h2&amp;gt;&lt;br /&gt;
    &amp;lt;form action=&amp;quot;/save&amp;quot; method=&amp;quot;POST&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;ssid&amp;quot; placeholder=&amp;quot;Nom du réseau (SSID)&amp;quot; required&amp;gt;&lt;br /&gt;
      &amp;lt;input type=&amp;quot;password&amp;quot; name=&amp;quot;pass&amp;quot; placeholder=&amp;quot;Mot de passe&amp;quot; required&amp;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;div class=&amp;quot;links&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;a href=&amp;quot;/status&amp;quot;&amp;gt;Voir le statut&amp;lt;/a&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;/div&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;
// ---- HANDLERS HTTP ----&lt;br /&gt;
&lt;br /&gt;
void handleRoot() {&lt;br /&gt;
  server.send(200, &amp;quot;text/html&amp;quot;, configPage);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void handleSave() {&lt;br /&gt;
  if (server.hasArg(&amp;quot;ssid&amp;quot;) &amp;amp;&amp;amp; server.hasArg(&amp;quot;pass&amp;quot;)) {&lt;br /&gt;
    prefs.begin(&amp;quot;wifi&amp;quot;, false);&lt;br /&gt;
    prefs.putString(&amp;quot;ssid&amp;quot;, server.arg(&amp;quot;ssid&amp;quot;));&lt;br /&gt;
    prefs.putString(&amp;quot;pass&amp;quot;, server.arg(&amp;quot;pass&amp;quot;));&lt;br /&gt;
    prefs.end();&lt;br /&gt;
&lt;br /&gt;
    String page = R&amp;quot;rawliteral(&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;fr&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;title&amp;gt;Paramètres enregistrés&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
  body {&lt;br /&gt;
    font-family: Arial, sans-serif;&lt;br /&gt;
    background: linear-gradient(135deg, #4c8bf5, #6dd5fa);&lt;br /&gt;
    height: 100vh;&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
  }&lt;br /&gt;
  .card {&lt;br /&gt;
    background: white;&lt;br /&gt;
    padding: 25px;&lt;br /&gt;
    border-radius: 15px;&lt;br /&gt;
    width: 320px;&lt;br /&gt;
    box-shadow: 0 8px 20px rgba(0,0,0,0.2);&lt;br /&gt;
    text-align: center;&lt;br /&gt;
  }&lt;br /&gt;
  h2 { margin-top: 0; color: #333; }&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;card&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;h2&amp;gt;Paramètres sauvegardés&amp;lt;/h2&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;L&amp;#039;appareil va redémarrer&amp;lt;br&amp;gt;et tenter de se connecter au nouveau réseau.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/div&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;
    server.send(200, &amp;quot;text/html&amp;quot;, page);&lt;br /&gt;
    delay(1500);&lt;br /&gt;
    ESP.restart();&lt;br /&gt;
  } else {&lt;br /&gt;
    server.send(400, &amp;quot;text/plain&amp;quot;, &amp;quot;SSID ou mot de passe manquant&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void handleStatus() {&lt;br /&gt;
  String mode = &amp;quot;&amp;quot;;&lt;br /&gt;
  wifi_mode_t currentMode = WiFi.getMode();&lt;br /&gt;
&lt;br /&gt;
  if (currentMode == WIFI_STA) mode = &amp;quot;Station (STA)&amp;quot;;&lt;br /&gt;
  else if (currentMode == WIFI_AP) mode = &amp;quot;Point d&amp;#039;accès (AP)&amp;quot;;&lt;br /&gt;
  else if (currentMode == WIFI_AP_STA) mode = &amp;quot;AP + Station (AP_STA)&amp;quot;;&lt;br /&gt;
  else mode = &amp;quot;Inconnu&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  String page = R&amp;quot;rawliteral(&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;fr&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;title&amp;gt;Statut WiFi&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
  body {&lt;br /&gt;
    font-family: Arial, sans-serif;&lt;br /&gt;
    background: linear-gradient(135deg, #6dd5fa, #4c8bf5);&lt;br /&gt;
    height: 100vh;&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .card {&lt;br /&gt;
    background: white;&lt;br /&gt;
    padding: 25px;&lt;br /&gt;
    border-radius: 15px;&lt;br /&gt;
    width: 350px;&lt;br /&gt;
    box-shadow: 0 8px 20px rgba(0,0,0,0.2);&lt;br /&gt;
    text-align: center;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  h2 {&lt;br /&gt;
    margin-top: 0;&lt;br /&gt;
    color: #333;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .info {&lt;br /&gt;
    text-align: left;&lt;br /&gt;
    margin-top: 15px;&lt;br /&gt;
    font-size: 16px;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .info div {&lt;br /&gt;
    margin-bottom: 8px;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .btn {&lt;br /&gt;
    margin-top: 15px;&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    padding: 10px 20px;&lt;br /&gt;
    background: #4c8bf5;&lt;br /&gt;
    color: white;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .btn:hover {&lt;br /&gt;
    background: #3a6fd8;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .btn-danger {&lt;br /&gt;
    background: #f56d6d;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .btn-danger:hover {&lt;br /&gt;
    background: #d84a4a;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;card&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;h2&amp;gt;Statut WiFi&amp;lt;/h2&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;info&amp;quot;&amp;gt;&lt;br /&gt;
)rawliteral&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  page += &amp;quot;&amp;lt;div&amp;gt;&amp;lt;b&amp;gt;Mode :&amp;lt;/b&amp;gt; &amp;quot; + mode + &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
  page += &amp;quot;&amp;lt;div&amp;gt;&amp;lt;b&amp;gt;IP (STA) :&amp;lt;/b&amp;gt; &amp;quot; + WiFi.localIP().toString() + &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
  page += &amp;quot;&amp;lt;div&amp;gt;&amp;lt;b&amp;gt;IP (AP) :&amp;lt;/b&amp;gt; &amp;quot; + WiFi.softAPIP().toString() + &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  if (WiFi.status() == WL_CONNECTED) {&lt;br /&gt;
    page += &amp;quot;&amp;lt;div&amp;gt;&amp;lt;b&amp;gt;RSSI :&amp;lt;/b&amp;gt; &amp;quot; + String(WiFi.RSSI()) + &amp;quot; dBm&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
  } else {&lt;br /&gt;
    page += &amp;quot;&amp;lt;div&amp;gt;&amp;lt;b&amp;gt;RSSI :&amp;lt;/b&amp;gt; Non connecté&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  unsigned long ms = millis();&lt;br /&gt;
  unsigned long sec = ms / 1000;&lt;br /&gt;
  unsigned long min = sec / 60;&lt;br /&gt;
  unsigned long hr  = min / 60;&lt;br /&gt;
&lt;br /&gt;
  page += &amp;quot;&amp;lt;div&amp;gt;&amp;lt;b&amp;gt;Uptime :&amp;lt;/b&amp;gt; &amp;quot; + String(hr) + &amp;quot;h &amp;quot; + String(min % 60) + &amp;quot;m &amp;quot; + String(sec % 60) + &amp;quot;s&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  page += R&amp;quot;rawliteral(&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;a class=&amp;quot;btn&amp;quot; href=&amp;quot;/&amp;quot;&amp;gt;Config WiFi&amp;lt;/a&amp;gt;&lt;br /&gt;
    &amp;lt;a class=&amp;quot;btn&amp;quot; href=&amp;quot;/reboot&amp;quot;&amp;gt;Redémarrer&amp;lt;/a&amp;gt;&lt;br /&gt;
    &amp;lt;a class=&amp;quot;btn btn-danger&amp;quot; href=&amp;quot;/resetwifi&amp;quot;&amp;gt;Reset Wi‑Fi&amp;lt;/a&amp;gt;&lt;br /&gt;
  &amp;lt;/div&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;
  server.send(200, &amp;quot;text/html&amp;quot;, page);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void handleReboot() {&lt;br /&gt;
  String page = R&amp;quot;rawliteral(&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;fr&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;title&amp;gt;Redémarrage&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
  body {&lt;br /&gt;
    font-family: Arial, sans-serif;&lt;br /&gt;
    background: linear-gradient(135deg, #4c8bf5, #6dd5fa);&lt;br /&gt;
    height: 100vh;&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .card {&lt;br /&gt;
    background: white;&lt;br /&gt;
    padding: 25px;&lt;br /&gt;
    border-radius: 15px;&lt;br /&gt;
    width: 320px;&lt;br /&gt;
    box-shadow: 0 8px 20px rgba(0,0,0,0.2);&lt;br /&gt;
    text-align: center;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  h2 {&lt;br /&gt;
    margin-top: 0;&lt;br /&gt;
    color: #333;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;card&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;h2&amp;gt;Redémarrage en cours…&amp;lt;/h2&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;L&amp;#039;appareil va redémarrer dans quelques secondes.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/div&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;
  server.send(200, &amp;quot;text/html&amp;quot;, page);&lt;br /&gt;
  delay(1500);&lt;br /&gt;
  ESP.restart();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void handleResetWiFi() {&lt;br /&gt;
  prefs.begin(&amp;quot;wifi&amp;quot;, false);&lt;br /&gt;
  prefs.clear();&lt;br /&gt;
  prefs.end();&lt;br /&gt;
&lt;br /&gt;
  String page = R&amp;quot;rawliteral(&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;fr&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;title&amp;gt;Reset WiFi&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
  body {&lt;br /&gt;
    font-family: Arial, sans-serif;&lt;br /&gt;
    background: linear-gradient(135deg, #f56d6d, #fa9a6d);&lt;br /&gt;
    height: 100vh;&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .card {&lt;br /&gt;
    background: white;&lt;br /&gt;
    padding: 25px;&lt;br /&gt;
    border-radius: 15px;&lt;br /&gt;
    width: 320px;&lt;br /&gt;
    box-shadow: 0 8px 20px rgba(0,0,0,0.2);&lt;br /&gt;
    text-align: center;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  h2 {&lt;br /&gt;
    margin-top: 0;&lt;br /&gt;
    color: #333;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;card&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;h2&amp;gt;Réinitialisation WiFi…&amp;lt;/h2&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Les paramètres WiFi ont été effacés.&amp;lt;br&amp;gt;Redémarrage en cours…&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/div&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;
  server.send(200, &amp;quot;text/html&amp;quot;, page);&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;\n===== RESET WIFI =====&amp;quot;);&lt;br /&gt;
  Serial.println(&amp;quot;IP STA : &amp;quot; + WiFi.localIP().toString());&lt;br /&gt;
  Serial.println(&amp;quot;IP AP  : &amp;quot; + WiFi.softAPIP().toString());&lt;br /&gt;
  Serial.println(&amp;quot;AP SSID : &amp;quot; + String(AP_SSID));&lt;br /&gt;
  Serial.println(&amp;quot;AP PASS : &amp;quot; + String(AP_PASS));&lt;br /&gt;
&lt;br /&gt;
  if (WiFi.status() == WL_CONNECTED)&lt;br /&gt;
    Serial.println(&amp;quot;RSSI : &amp;quot; + String(WiFi.RSSI()) + &amp;quot; dBm&amp;quot;);&lt;br /&gt;
  else&lt;br /&gt;
    Serial.println(&amp;quot;RSSI : Non connecté&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;=======================\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  delay(1500);&lt;br /&gt;
  ESP.restart();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ---- LOGIQUE WIFI ----&lt;br /&gt;
&lt;br /&gt;
bool connectToWiFi() {&lt;br /&gt;
  prefs.begin(&amp;quot;wifi&amp;quot;, true);&lt;br /&gt;
  ssid = prefs.getString(&amp;quot;ssid&amp;quot;, DEFAULT_STA_SSID);&lt;br /&gt;
  pass = prefs.getString(&amp;quot;pass&amp;quot;, DEFAULT_STA_PASS);&lt;br /&gt;
  prefs.end();&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;Connexion à &amp;quot;); Serial.println(ssid);&lt;br /&gt;
&lt;br /&gt;
  WiFi.begin(ssid.c_str(), pass.c_str());&lt;br /&gt;
&lt;br /&gt;
  unsigned long start = millis();&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED &amp;amp;&amp;amp; millis() - start &amp;lt; 10000) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  if (WiFi.status() == WL_CONNECTED) {&lt;br /&gt;
    Serial.println(&amp;quot;\n[WiFi] Connecté en STA&amp;quot;);&lt;br /&gt;
    Serial.println(&amp;quot;IP STA : &amp;quot; + WiFi.localIP().toString());&lt;br /&gt;
    Serial.println(&amp;quot;RSSI   : &amp;quot; + String(WiFi.RSSI()) + &amp;quot; dBm&amp;quot;);&lt;br /&gt;
    return true;&lt;br /&gt;
  } else {&lt;br /&gt;
    Serial.println(&amp;quot;\n[WiFi] Échec connexion STA&amp;quot;);&lt;br /&gt;
    return false;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ---- SETUP / LOOP ----&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
  delay(500);&lt;br /&gt;
  Serial.println(&amp;quot;\n==== DÉMARRAGE XIAO ESP32C3 ====&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  WiFi.mode(WIFI_AP_STA);&lt;br /&gt;
&lt;br /&gt;
  WiFi.softAP(AP_SSID, AP_PASS);&lt;br /&gt;
  Serial.println(&amp;quot;[WiFi] AP actif&amp;quot;);&lt;br /&gt;
  Serial.println(&amp;quot;  SSID : &amp;quot; + String(AP_SSID));&lt;br /&gt;
  Serial.println(&amp;quot;  PASS : &amp;quot; + String(AP_PASS));&lt;br /&gt;
  Serial.println(&amp;quot;  IP AP: &amp;quot; + WiFi.softAPIP().toString());&lt;br /&gt;
&lt;br /&gt;
  connectToWiFi();&lt;br /&gt;
&lt;br /&gt;
  server.on(&amp;quot;/&amp;quot;, handleRoot);&lt;br /&gt;
  server.on(&amp;quot;/save&amp;quot;, HTTP_POST, handleSave);&lt;br /&gt;
  server.on(&amp;quot;/status&amp;quot;, handleStatus);&lt;br /&gt;
  server.on(&amp;quot;/reboot&amp;quot;, handleReboot);&lt;br /&gt;
  server.on(&amp;quot;/resetwifi&amp;quot;, handleResetWiFi);&lt;br /&gt;
&lt;br /&gt;
  server.begin();&lt;br /&gt;
  Serial.println(&amp;quot;[HTTP] Serveur web démarré&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  initEPaper();   // ✅ Ajout&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  server.handleClient();&lt;br /&gt;
  updateEPaperTime();  // ✅ Ajout&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// Onglet TimeDisplayEPaper.h&lt;br /&gt;
#pragma once&lt;br /&gt;
#include &amp;lt;time.h&amp;gt;&lt;br /&gt;
#include &amp;lt;TFT_eSPI.h&amp;gt;&lt;br /&gt;
#include &amp;lt;SPI.h&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
EPaper epaper = EPaper();  // Pins définis dans User_Setup.h&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// ⚙️ Paramètres NTP&lt;br /&gt;
const char* ntpServer = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const long  gmtOffset_sec = 3600;       // +1h (Suisse en hiver)&lt;br /&gt;
const int   daylightOffset_sec = 3600;  // +1h (DST été)&lt;br /&gt;
&lt;br /&gt;
// Variables pour éviter scintillement&lt;br /&gt;
int lastMinute = -1;&lt;br /&gt;
&lt;br /&gt;
// --- Initialisation de l’e-paper ---&lt;br /&gt;
void initEPaper() {&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
  epaper.begin();&lt;br /&gt;
  epaper.setRotation(1);&lt;br /&gt;
  epaper.fillScreen(TFT_WHITE);&lt;br /&gt;
  epaper.setTextColor(TFT_BLACK, TFT_WHITE);&lt;br /&gt;
  epaper.update();&lt;br /&gt;
  epaper.sleep();&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
  // Initialisation NTP&lt;br /&gt;
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// --- Fonction pour dessiner un pictogramme Wi-Fi ---&lt;br /&gt;
void drawWiFiIcon(int x, int y, int rssi) {&lt;br /&gt;
  int bars = 0;&lt;br /&gt;
  if (rssi &amp;gt; -50) bars = 4;&lt;br /&gt;
  else if (rssi &amp;gt; -60) bars = 3;&lt;br /&gt;
  else if (rssi &amp;gt; -70) bars = 2;&lt;br /&gt;
  else if (rssi &amp;gt; -80) bars = 1;&lt;br /&gt;
  else bars = 0;&lt;br /&gt;
&lt;br /&gt;
  int barWidth = 6;&lt;br /&gt;
  int spacing = 3;&lt;br /&gt;
  for (int i = 0; i &amp;lt; 4; i++) {&lt;br /&gt;
    int barHeight = (i+1) * 6;&lt;br /&gt;
    int bx = x + i * (barWidth + spacing);&lt;br /&gt;
    int by = y + (24 - barHeight);&lt;br /&gt;
    if (i &amp;lt; bars) {&lt;br /&gt;
      epaper.fillRect(bx, by, barWidth, barHeight, TFT_BLACK);&lt;br /&gt;
    } else {&lt;br /&gt;
      epaper.drawRect(bx, by, barWidth, barHeight, TFT_BLACK);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// --- Mise à jour de l’affichage ---&lt;br /&gt;
void updateEPaperTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Erreur récupération heure NTP&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  if (timeinfo.tm_min != lastMinute) {&lt;br /&gt;
    lastMinute = timeinfo.tm_min;&lt;br /&gt;
&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
    epaper.fillScreen(TFT_WHITE);&lt;br /&gt;
&lt;br /&gt;
    // --- Affichage DATE ---&lt;br /&gt;
    epaper.setTextDatum(TC_DATUM);&lt;br /&gt;
    epaper.drawString(&lt;br /&gt;
      String(timeinfo.tm_mday) + &amp;quot;/&amp;quot; + &lt;br /&gt;
      String(timeinfo.tm_mon+1) + &amp;quot;/&amp;quot; + &lt;br /&gt;
      String(timeinfo.tm_year+1900),&lt;br /&gt;
      epaper.width()/2, 30, 4&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    // --- Affichage HEURE ---&lt;br /&gt;
    char buffer[6];&lt;br /&gt;
    sprintf(buffer, &amp;quot;%02d:%02d&amp;quot;, timeinfo.tm_hour, timeinfo.tm_min);&lt;br /&gt;
    epaper.setTextDatum(MC_DATUM);&lt;br /&gt;
    epaper.drawString(buffer, epaper.width()/2, epaper.height()/2, 7);&lt;br /&gt;
&lt;br /&gt;
    // --- Encadré infos réseau ---&lt;br /&gt;
    int boxX = 5;&lt;br /&gt;
    int boxY = epaper.height() - 70;&lt;br /&gt;
    int boxW = epaper.width() - 10;&lt;br /&gt;
    int boxH = 60;&lt;br /&gt;
&lt;br /&gt;
    epaper.fillRect(boxX, boxY, boxW, boxH, TFT_LIGHTGREY);&lt;br /&gt;
    epaper.drawRect(boxX, boxY, boxW, boxH, TFT_BLACK);&lt;br /&gt;
&lt;br /&gt;
    epaper.setTextColor(TFT_BLACK, TFT_LIGHTGREY);&lt;br /&gt;
    epaper.setTextDatum(TL_DATUM);&lt;br /&gt;
    epaper.drawString(&amp;quot;IP STA: &amp;quot; + WiFi.localIP().toString(), boxX + 10, boxY + 12, 2);&lt;br /&gt;
&lt;br /&gt;
    // --- Pictogramme Wi-Fi centré ---&lt;br /&gt;
    int iconX = boxX + (boxW/2) - 15;&lt;br /&gt;
    int iconY = boxY + 5;&lt;br /&gt;
    drawWiFiIcon(iconX, iconY, WiFi.RSSI());&lt;br /&gt;
&lt;br /&gt;
    // --- RSSI sous l’icône ---&lt;br /&gt;
    epaper.setTextDatum(TC_DATUM);&lt;br /&gt;
    epaper.drawString(&amp;quot;RSSI: &amp;quot; + String(WiFi.RSSI()) + &amp;quot; dBm&amp;quot;, boxX + boxW/2, boxY + 40, 2);&lt;br /&gt;
&lt;br /&gt;
    epaper.update();&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
    // --- Sortie série ---&lt;br /&gt;
    Serial.printf(&amp;quot;Heure actuelle : %02d:%02d:%02d\n&amp;quot;, &lt;br /&gt;
                  timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec);&lt;br /&gt;
    Serial.println(&amp;quot;IP STA : &amp;quot; + WiFi.localIP().toString());&lt;br /&gt;
    Serial.println(&amp;quot;RSSI   : &amp;quot; + String(WiFi.RSSI()) + &amp;quot; dBm&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// onglet driver.h&lt;br /&gt;
// driver.h file &lt;br /&gt;
#define BOARD_SCREEN_COMBO 505 // 1.54 inch monochrome ePaper Screen （SSD1681）&lt;br /&gt;
#define USE_XIAO_EPAPER_BREAKOUT_BOARD&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>144.2.107.134</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.myows.top/index.php?title=1.54-inch_E-paper_Display&amp;diff=2045</id>
		<title>1.54-inch E-paper Display</title>
		<link rel="alternate" type="text/html" href="https://wiki.myows.top/index.php?title=1.54-inch_E-paper_Display&amp;diff=2045"/>
		<updated>2025-12-18T22:44:08Z</updated>

		<summary type="html">&lt;p&gt;144.2.107.134: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
=== Support ===&lt;br /&gt;
&lt;br /&gt;
1.54-inch E-paper Display&lt;br /&gt;
&lt;br /&gt;
[[File:EPaper-Display-1.54.PNG|250px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Setup&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 Install Seeed &amp;lt;b&amp;gt;GFX Library&amp;lt;/b&amp;gt;&lt;br /&gt;
 https://github.com/Seeed-Studio/Seeed_GFX&lt;br /&gt;
&lt;br /&gt;
This library has same function as TFT library and no compatible with it. If you have installed TFT library or other similary display libraries, please uninstall it first.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Create a driver.h file&amp;lt;/b&amp;gt; and paste the following code into it.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Seeed GFX Library - &amp;lt;b&amp;gt;Online Configuration Generator&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
https://seeed-studio.github.io/Seeed_GFX/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// driver.h file &lt;br /&gt;
#define BOARD_SCREEN_COMBO 505 // 1.54 inch monochrome ePaper Screen （SSD1681）&lt;br /&gt;
#define USE_XIAO_EPAPER_BREAKOUT_BOARD&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sketch -&amp;gt; &amp;lt;b&amp;gt;Include Library&amp;lt;/b&amp;gt; -&amp;gt; Add .ZIP&amp;lt;br&amp;gt;&lt;br /&gt;
Seeed_GFX-master.zip&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Upload the Code&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
driver.h&amp;lt;br&amp;gt;&lt;br /&gt;
HelloWorld.ino&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Liens externes ====&lt;br /&gt;
&lt;br /&gt;
https://www.seeedstudio.com/1-54-Monochrome-ePaper-Display-with-200x200-Pixels-p-5776.html &amp;lt;font color=red&amp;gt;Shop&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://wiki.seeedstudio.com/XIAO-eInk-Expansion-Board/ &amp;lt;font color=red&amp;gt;Wiki&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exemples ===&lt;br /&gt;
&lt;br /&gt;
/examples/ePaper/Basic&lt;br /&gt;
&lt;br /&gt;
1 Bitmap: Display a bitmap image.&amp;lt;br&amp;gt;&lt;br /&gt;
2 Clock: Display a clock.&amp;lt;br&amp;gt;&lt;br /&gt;
3 Clock_digital: Display a digital clock.&amp;lt;br&amp;gt;&lt;br /&gt;
4 HelloWorld: &amp;lt;br&amp;gt;&lt;br /&gt;
5 Shape: Display different sizes of words and shape randomly.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Code Wi-Fi ===&lt;br /&gt;
&lt;br /&gt;
dd&lt;br /&gt;
&lt;br /&gt;
=== [Code 1] Display a bitmap image ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;quot;TFT_eSPI.h&amp;quot;&lt;br /&gt;
#include &amp;quot;image.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
EPaper epaper;&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
  delay(2000);&lt;br /&gt;
  Serial.println(&amp;quot;1.54\&amp;quot; E-Paper Bitmap Display Example&amp;quot;);&lt;br /&gt;
  &lt;br /&gt;
  epaper.begin();&lt;br /&gt;
  &lt;br /&gt;
  // Clear screen to white&lt;br /&gt;
  epaper.fillScreen(TFT_WHITE);&lt;br /&gt;
  epaper.update();&lt;br /&gt;
  delay(1000);&lt;br /&gt;
  &lt;br /&gt;
  // Display bitmap image using drawBitmap API&lt;br /&gt;
  // drawBitmap(x, y, bitmap_data, width, height, color)&lt;br /&gt;
  epaper.drawBitmap(0, 0, gImage_1inch54, 200, 200, TFT_BLACK);&lt;br /&gt;
  epaper.update();&lt;br /&gt;
  &lt;br /&gt;
  Serial.println(&amp;quot;Bitmap displayed successfully&amp;quot;);&lt;br /&gt;
  &lt;br /&gt;
  // Put display to sleep to save power&lt;br /&gt;
  epaper.sleep();&lt;br /&gt;
#else&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
  Serial.println(&amp;quot;EPAPER_ENABLE not defined. Please select the correct setup file.&amp;quot;);&lt;br /&gt;
#endif&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop()&lt;br /&gt;
{&lt;br /&gt;
  // Nothing to do here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;onglet driver.h&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// driver.h file &lt;br /&gt;
#define BOARD_SCREEN_COMBO 505 // 1.54 inch monochrome ePaper Screen （SSD1681）&lt;br /&gt;
#define USE_XIAO_EPAPER_BREAKOUT_BOARD&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;onglet image.h&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * Image header file for 1.54&amp;quot; E-Paper Display&lt;br /&gt;
 * &lt;br /&gt;
 * Image specifications:&lt;br /&gt;
 * - Size: 200x200 pixels&lt;br /&gt;
 * - Format: 1-bit monochrome bitmap&lt;br /&gt;
 * - Color depth: Black and White&lt;br /&gt;
 * &lt;br /&gt;
 * To generate your own image:&lt;br /&gt;
 * 1. Prepare a 200x200 pixel image&lt;br /&gt;
 * 2. Convert to 1-bit monochrome bitmap&lt;br /&gt;
 * 3. Use image2cpp or similar tool to generate C array&lt;br /&gt;
 * 4. Replace the array below with your generated data&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
#ifndef _IMAGE_H_&lt;br /&gt;
#define _IMAGE_H_&lt;br /&gt;
&lt;br /&gt;
// Placeholder for 200x200 bitmap image&lt;br /&gt;
// Replace this with your actual image data&lt;br /&gt;
const unsigned char gImage_1inch54[] PROGMEM = {&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0xC0, 0x00, 0x00,&lt;br /&gt;
  0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x07, 0xC0,&lt;br /&gt;
  0x7C, 0x07, 0xC0, 0xFD, 0x81, 0xFC, 0xC6, 0x18, 0x7E, 0xC0, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x0F, 0xF0, 0xFE, 0x1F, 0xE1, 0xFF, 0x83, 0xFC, 0xEE,&lt;br /&gt;
  0x18, 0xFF, 0xCC, 0x7F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,&lt;br /&gt;
  0x1C, 0x71, 0xC7, 0x1C, 0x73, 0xC7, 0x83, 0x00, 0xEE, 0x19, 0xE3, 0xCC, 0xE3, 0xC0, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x18, 0x3B, 0x83, 0x38, 0x33, 0x83, 0x83,&lt;br /&gt;
  0x80, 0xCE, 0x19, 0xC1, 0xCD, 0xC1, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x7C, 0x3F, 0xFB, 0xFF, 0xBF, 0xF3, 0x03, 0x83, 0xF0, 0xCE, 0x19, 0x81, 0xCD, 0xC0, 0xC0,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0xFB, 0xFF, 0xBF, 0xF3,&lt;br /&gt;
  0x03, 0x81, 0xFC, 0xCE, 0x19, 0x81, 0xCD, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x07, 0xB8, 0x03, 0x80, 0x38, 0x03, 0x03, 0x80, 0x1C, 0xCE, 0x19, 0x81, 0xCD,&lt;br /&gt;
  0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x9C, 0x01, 0x80,&lt;br /&gt;
  0x38, 0x03, 0x87, 0x80, 0x0C, 0xC6, 0x19, 0xC3, 0xCC, 0xE1, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x9F, 0xF1, 0xFF, 0x1F, 0xE1, 0xFF, 0x83, 0x1C, 0xE7, 0xF8,&lt;br /&gt;
  0xFF, 0xCC, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x0F,&lt;br /&gt;
  0xE0, 0xFE, 0x0F, 0xE0, 0xFF, 0x83, 0xF8, 0xE3, 0xF0, 0x7F, 0xCC, 0x7F, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x03, 0x80, 0x38, 0x03, 0x80, 0x39, 0x80, 0xE0,&lt;br /&gt;
  0x20, 0xC0, 0x1C, 0xCC, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0xC0, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79,&lt;br /&gt;
  0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x38, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0xC0, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0xDC, 0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x18, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFE, 0xFC, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x01, 0x80, 0x13, 0xC6, 0xE6, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xC0, 0xB7, 0xE6, 0x66, 0xE4,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0xF8, 0xE6, 0x66, 0x66, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xFC, 0xC6, 0x76,&lt;br /&gt;
  0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xF0,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x04, 0x3C, 0xCC, 0xC6, 0x66, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x30, 0xCC,&lt;br /&gt;
  0xC3, 0xE6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,&lt;br /&gt;
  0xFF, 0xF8, 0x00, 0x03, 0x00, 0x3F, 0x3B, 0x70, 0xCE, 0xC1, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFF, 0xF8, 0x00, 0x43, 0x06, 0x3F, 0x33,&lt;br /&gt;
  0xB0, 0xE6, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFE,&lt;br /&gt;
  0x00, 0x00, 0xFF, 0xF8, 0x00, 0xE3, 0x9F, 0xBB, 0xB3, 0xBE, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0xF8, 0x00, 0xF7, 0x99,&lt;br /&gt;
  0x99, 0xBB, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F,&lt;br /&gt;
  0xFF, 0xFF, 0x00, 0x01, 0xFF, 0xF8, 0x00, 0xF7, 0x99, 0x99, 0x9F, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0xFC, 0x00,&lt;br /&gt;
  0x7F, 0x99, 0x99, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x1F, 0xFF, 0xFF, 0x00, 0x03, 0xFB, 0xFC, 0x00, 0x7D, 0x9F, 0x98, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x30, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0x00, 0x03, 0xFB,&lt;br /&gt;
  0xFC, 0x00, 0x6C, 0xCF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0xE7, 0x60, 0x00, 0x00,&lt;br /&gt;
  0x0C, 0x00, 0x00, 0x1F, 0xFF, 0xE0, 0x00, 0x07, 0xF3, 0xFC, 0x00, 0x64, 0xC0, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0xC0, 0x02, 0x31, 0x33, 0x60, 0x00, 0x01, 0xFC, 0x00, 0x00, 0x1F, 0xF8, 0x00, 0x00,&lt;br /&gt;
  0x07, 0xF3, 0xFC, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x1F, 0xB8, 0x71, 0xE0,&lt;br /&gt;
  0x00, 0x03, 0xFC, 0x00, 0x00, 0x1F, 0xE0, 0x00, 0x00, 0x07, 0xF3, 0xFE, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0xFC, 0x07, 0x99, 0x99, 0xB1, 0xC0, 0x00, 0x07, 0xFC, 0x00, 0x00, 0x1F, 0xE0,&lt;br /&gt;
  0x00, 0x00, 0x0F, 0xF3, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x66, 0x19, 0x99,&lt;br /&gt;
  0xB8, 0xC0, 0x00, 0x1F, 0xFE, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0x0F, 0xE3, 0xFE, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0x67, 0x19, 0x99, 0xF8, 0xC1, 0x00, 0x7F, 0xFE, 0x00, 0x00,&lt;br /&gt;
  0x0F, 0xF0, 0x00, 0x00, 0x0F, 0xE1, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xC6, 0x67,&lt;br /&gt;
  0xD9, 0x9C, 0xC1, 0xFF, 0x01, 0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0x1F, 0xE1, 0xFE,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xE7, 0x60, 0xDF, 0x80, 0x0F, 0xFF, 0x01, 0xFF, 0xFE,&lt;br /&gt;
  0x00, 0x00, 0x0F, 0xF7, 0xFC, 0x00, 0x1F, 0xC1, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0xE0,&lt;br /&gt;
  0x66, 0x77, 0xDE, 0x01, 0xFF, 0xFF, 0x01, 0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x3F,&lt;br /&gt;
  0xC1, 0xFF, 0x00, 0x00, 0x04, 0x00, 0x3E, 0x66, 0xC0, 0x66, 0x37, 0x8C, 0x7F, 0xFF, 0xFF, 0x01,&lt;br /&gt;
  0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xC0, 0x3F, 0x81, 0xFF, 0xF0, 0x00, 0x3F, 0x0E, 0x7F,&lt;br /&gt;
  0x7E, 0xE0, 0x7C, 0x20, 0x0F, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x0F, 0xFF, 0xFF,&lt;br /&gt;
  0xC0, 0x3F, 0x81, 0xFF, 0xF0, 0x00, 0x3B, 0xBE, 0x73, 0x78, 0x60, 0x78, 0x03, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0x00, 0x81, 0xFF, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xE0, 0x7F, 0x9F, 0xFF, 0xF0, 0x00, 0x31,&lt;br /&gt;
  0x87, 0x73, 0x70, 0x60, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x07,&lt;br /&gt;
  0xFF, 0xFF, 0xF0, 0x7F, 0xFF, 0xFF, 0xF0, 0x0F, 0x3B, 0x8F, 0x33, 0x3E, 0x40, 0x0F, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x07, 0xF8, 0x7F, 0xF0, 0x7F, 0xFF, 0xFF, 0xF8,&lt;br /&gt;
  0x0D, 0x9F, 0x1B, 0x3F, 0x18, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0x00,&lt;br /&gt;
  0x00, 0x07, 0xE0, 0x3F, 0xF0, 0xFF, 0xFF, 0xFF, 0xF8, 0x19, 0x9C, 0x3B, 0x3E, 0x00, 0x7F, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x00, 0xC0, 0x1F, 0xF8, 0x7F, 0xFF,&lt;br /&gt;
  0xFF, 0xF0, 0x1F, 0x98, 0x1F, 0x30, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,&lt;br /&gt;
  0xFF, 0x80, 0x00, 0x00, 0x00, 0x0F, 0xF8, 0x7F, 0xFF, 0xFF, 0x80, 0x1C, 0x18, 0x00, 0x33, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x0F, 0xF8,&lt;br /&gt;
  0x7F, 0xFF, 0xFF, 0x80, 0x0F, 0x98, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0x00, 0x00, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x0F, 0xF8, 0x7F, 0xC0, 0x7F, 0x80, 0x07, 0x00, 0x1F,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x80, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x0F, 0xF8, 0x78, 0x00, 0x7F, 0xC0, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0x7F, 0xC0, 0x00,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x7F, 0xC0, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0x7F, 0xC0, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x00, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0x3F,&lt;br /&gt;
  0xC7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x7F,&lt;br /&gt;
  0xC0, 0x00, 0x01, 0x80, 0x1F, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x03, 0xE0, 0x7F, 0xF0, 0x00,&lt;br /&gt;
  0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,&lt;br /&gt;
  0x00, 0x7F, 0xC0, 0x00, 0x03, 0xFF, 0xFF, 0xE0, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x07, 0xFF, 0xFF,&lt;br /&gt;
  0xE0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0x00, 0x00, 0x3F, 0xE0, 0x00, 0x07, 0xFF, 0xFF, 0xC0, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0xE0, 0x00, 0x07,&lt;br /&gt;
  0xFF, 0xFF, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0xE7, 0xC1, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0xFF,&lt;br /&gt;
  0xC3, 0xC1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0xFF, 0xC3, 0xE0, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x0F,&lt;br /&gt;
  0xFF, 0xFF, 0xC3, 0xE1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0x00, 0x1F, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x7F, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFE, 0x7F, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xEF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xC1, 0xFF, 0xFF, 0xFE, 0x7F, 0xF7, 0x3F, 0xFF, 0xFF,&lt;br /&gt;
  0xF1, 0xE3, 0xE7, 0xF2, 0x39, 0x3F, 0xFF, 0xC7, 0x8F, 0x9F, 0xCC, 0xE7, 0x7F, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xC0, 0xFF, 0xFF, 0xFE, 0x7F, 0xE7, 0xFF, 0xFF, 0xFF, 0xC0, 0xC1, 0xC3, 0xF3, 0x39, 0xBC, 0xF3,&lt;br /&gt;
  0x03, 0x07, 0x0F, 0xCC, 0xE7, 0x3F, 0xFF, 0xFF, 0xFF, 0xCE, 0x61, 0xC3, 0x8E, 0x66, 0x41, 0x38,&lt;br /&gt;
  0x70, 0x73, 0xFC, 0xCC, 0x99, 0xF7, 0x33, 0xBE, 0x67, 0xF3, 0x32, 0x67, 0xDC, 0xE7, 0x3F, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xCC, 0x40, 0x83, 0x06, 0x66, 0x41, 0x30, 0x30, 0x33, 0xFC, 0xCC, 0x99, 0xF7, 0x33,&lt;br /&gt;
  0x9F, 0x0F, 0xF3, 0x32, 0x67, 0xDC, 0x67, 0xBF, 0xFF, 0xFF, 0xFF, 0xC0, 0xCC, 0x8E, 0x62, 0x66,&lt;br /&gt;
  0x67, 0x33, 0x33, 0x33, 0xF8, 0xCC, 0x99, 0xE7, 0x13, 0x9F, 0x9F, 0xE3, 0x32, 0x67, 0x9C, 0x07,&lt;br /&gt;
  0xBF, 0xFF, 0xFF, 0xFF, 0xC1, 0xC0, 0xC2, 0x72, 0x66, 0x67, 0x33, 0x33, 0x3F, 0xF9, 0xCC, 0x99,&lt;br /&gt;
  0xE7, 0x97, 0x9F, 0x0F, 0xE7, 0x32, 0x67, 0x9C, 0x67, 0xBF, 0xFF, 0xFF, 0xFF, 0xCC, 0xCF, 0xF2,&lt;br /&gt;
  0x62, 0x66, 0x67, 0x33, 0x33, 0x3F, 0xF3, 0xCC, 0x99, 0xF7, 0x87, 0x9E, 0x67, 0xCF, 0x32, 0x67,&lt;br /&gt;
  0xDC, 0xE7, 0xBF, 0xFF, 0xFF, 0xFF, 0xCC, 0xC5, 0x93, 0x06, 0x20, 0x63, 0x30, 0x33, 0x33, 0xE0,&lt;br /&gt;
  0xC1, 0x81, 0xF7, 0x87, 0x9C, 0xF3, 0x83, 0x06, 0x07, 0xDC, 0xE7, 0x3F, 0xFF, 0xFF, 0xFF, 0xCE,&lt;br /&gt;
  0x61, 0x87, 0x0F, 0x30, 0x71, 0x38, 0x73, 0x33, 0xC0, 0xE1, 0xC3, 0xF3, 0xC7, 0xBF, 0xFF, 0x03,&lt;br /&gt;
  0x8F, 0x0F, 0xCC, 0xE7, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xF3, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xFF, 0x3F, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xFF, 0x7F,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0xFE, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0x8F, 0xCE, 0x0E, 0x7F, 0xFC,&lt;br /&gt;
  0x18, 0x3E, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFE, 0x7F, 0xFF, 0xFF, 0x07, 0x86, 0x07, 0xFF, 0xFC, 0x18, 0x1C, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xE1, 0xD1, 0x91, 0xC3, 0xC4, 0x18, 0x74, 0xDF, 0xE7, 0x86, 0x62,&lt;br /&gt;
  0x60, 0xFC, 0xF9, 0x98, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xC0, 0xC0,&lt;br /&gt;
  0x81, 0xC1, 0x84, 0x10, 0x60, 0x8F, 0xE7, 0x26, 0x62, 0x60, 0x7C, 0xF9, 0x99, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xCC, 0xCC, 0x88, 0x99, 0x1E, 0x73, 0x23, 0xDF, 0xE6,&lt;br /&gt;
  0x66, 0x06, 0x66, 0x7C, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF,&lt;br /&gt;
  0xCC, 0xCC, 0x8C, 0x81, 0x3E, 0x63, 0x23, 0xFF, 0xCE, 0x06, 0x0E, 0x66, 0x7C, 0x38, 0x39, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xCC, 0xCC, 0x8C, 0x9F, 0x3E, 0x73, 0x23,&lt;br /&gt;
  0xFF, 0x8E, 0x06, 0x7E, 0x66, 0x7C, 0xF9, 0xF9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xC0, 0xC0, 0xCC, 0x8C, 0x8B, 0x86, 0x30, 0x23, 0x8F, 0x03, 0xE6, 0x7E, 0x66, 0x7C, 0xF9,&lt;br /&gt;
  0xFC, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xE1, 0xCC, 0x8C, 0xC3, 0x87,&lt;br /&gt;
  0x18, 0x63, 0x9F, 0x03, 0xE6, 0x7E, 0x66, 0x7C, 0xF9, 0xFE, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xCF, 0xFF, 0xFE, 0x7C, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xFF, 0xFC, 0x7C,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF,&lt;br /&gt;
  0xE9, 0x0E, 0x66, 0x1C, 0x61, 0xCE, 0x1D, 0xF8, 0x7C, 0xE1, 0x99, 0xC7, 0x30, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xE1, 0x06, 0x64, 0x18, 0x60, 0xCC, 0x18,&lt;br /&gt;
  0xF8, 0x7C, 0xC0, 0x99, 0x83, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xCC, 0x67, 0xE6, 0x64, 0x71, 0xFC, 0xCC, 0xCD, 0xF2, 0x7C, 0xCC, 0x99, 0x33, 0x23, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCC, 0x67, 0x07, 0x0E, 0x13, 0xE0,&lt;br /&gt;
  0xCC, 0x0F, 0xF0, 0x3C, 0xC0, 0xCB, 0x03, 0x30, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xCE, 0x67, 0x27, 0x0F, 0x93, 0xE4, 0xCC, 0xFF, 0xF0, 0x3C, 0xCF, 0xC3, 0x3F,&lt;br /&gt;
  0x3C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x67, 0x07, 0x9C,&lt;br /&gt;
  0x98, 0x60, 0xC4, 0x58, 0xFE, 0x7C, 0x45, 0xC3, 0x17, 0x24, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xE7, 0x07, 0x9C, 0x38, 0x60, 0xE6, 0x19, 0xFE, 0x7E, 0x61,&lt;br /&gt;
  0xE7, 0x83, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFE, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xFE, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0x87, 0x07, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xCF, 0xFC, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0x07, 0x03, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCC, 0x98, 0x30, 0xC8, 0x18, 0x78,&lt;br /&gt;
  0xE3, 0x9F, 0x3F, 0x33, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xCC, 0x08, 0x20, 0xC0, 0x18, 0x30, 0xC1, 0x9F, 0x1F, 0x33, 0x3F, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCC, 0xCC, 0xE6, 0x47,&lt;br /&gt;
  0x3E, 0x23, 0x89, 0x9F, 0x07, 0x03, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCC, 0xCC, 0xE0, 0x4F, 0x38, 0x27, 0x81, 0xFF, 0xE3, 0x07, 0x3F,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCC, 0xCC,&lt;br /&gt;
  0xE7, 0xCF, 0x33, 0x23, 0x8F, 0xFF, 0xF3, 0x3F, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCC, 0xCC, 0x62, 0xCF, 0x30, 0x30, 0xC1, 0x9F, 0x03,&lt;br /&gt;
  0x3F, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xCC, 0xCE, 0x30, 0xCF, 0x38, 0x30, 0xE1, 0x9F, 0x07, 0x3F, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [Code 2 Display a clock] ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 An example digital clock using a TFT LCD screen to show the time.&lt;br /&gt;
 Demonstrates use of the font printing routines. (Time updates but date does not.)&lt;br /&gt;
 &lt;br /&gt;
 For a more accurate clock, it would be better to use the RTClib library.&lt;br /&gt;
 But this is just a demo. &lt;br /&gt;
 &lt;br /&gt;
 This examples uses the hardware SPI only. Non-hardware SPI&lt;br /&gt;
 is just too slow (~8 times slower!)&lt;br /&gt;
 &lt;br /&gt;
 Based on clock sketch by Gilchrist 6/2/2014 1.0&lt;br /&gt;
 Updated by Bodmer&lt;br /&gt;
A few colour codes:&lt;br /&gt;
 &lt;br /&gt;
code	color&lt;br /&gt;
0x0000	Black&lt;br /&gt;
0xFFFF	White&lt;br /&gt;
0xBDF7	Light Gray&lt;br /&gt;
0x7BEF	Dark Gray&lt;br /&gt;
0xF800	Red&lt;br /&gt;
0xFFE0	Yellow&lt;br /&gt;
0xFBE0	Orange&lt;br /&gt;
0x79E0	Brown&lt;br /&gt;
0x7E0	Green&lt;br /&gt;
0x7FF	Cyan&lt;br /&gt;
0x1F	Blue&lt;br /&gt;
0xF81F	Pink&lt;br /&gt;
&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;TFT_eSPI.h&amp;gt; // Graphics and font library for ST7735 driver chip&lt;br /&gt;
#include &amp;lt;SPI.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#ifdef EPAPER_ENABLE // Only compile this code if the EPAPER_ENABLE is defined in User_Setup.h&lt;br /&gt;
&lt;br /&gt;
EPaper epaper = EPaper();  // Invoke library, pins defined in User_Setup.h&lt;br /&gt;
&lt;br /&gt;
uint32_t targetTime = 0;       // for next 1 second timeout&lt;br /&gt;
&lt;br /&gt;
byte omm = 99;&lt;br /&gt;
bool initial = 1;&lt;br /&gt;
byte xcolon = 0;&lt;br /&gt;
unsigned int colour = 0;&lt;br /&gt;
&lt;br /&gt;
static uint8_t conv2d(const char* p) {&lt;br /&gt;
  uint8_t v = 0;&lt;br /&gt;
  if (&amp;#039;0&amp;#039; &amp;lt;= *p &amp;amp;&amp;amp; *p &amp;lt;= &amp;#039;9&amp;#039;)&lt;br /&gt;
    v = *p - &amp;#039;0&amp;#039;;&lt;br /&gt;
  return 10 * v + *++p - &amp;#039;0&amp;#039;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
uint8_t hh=conv2d(__TIME__), mm=conv2d(__TIME__+3), ss=conv2d(__TIME__+6);  // Get H, M, S from compile time&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
void setup(void) {&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
  epaper.begin();&lt;br /&gt;
  epaper.setRotation(1);&lt;br /&gt;
  epaper.fillScreen(TFT_BLACK);&lt;br /&gt;
&lt;br /&gt;
  epaper.setTextColor(TFT_YELLOW, TFT_BLACK); // Note: the new fonts do not draw the background colour&lt;br /&gt;
  epaper.update(); // update the display&lt;br /&gt;
  targetTime = millis() + 1000; &lt;br /&gt;
#endif&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
  if (targetTime &amp;lt; millis()) {&lt;br /&gt;
    targetTime = millis()+1000;&lt;br /&gt;
    ss++;              // Advance second&lt;br /&gt;
    if (ss==60) {&lt;br /&gt;
      ss=0;&lt;br /&gt;
      omm = mm;&lt;br /&gt;
      mm++;            // Advance minute&lt;br /&gt;
      if(mm&amp;gt;59) {&lt;br /&gt;
        mm=0;&lt;br /&gt;
        hh++;          // Advance hour&lt;br /&gt;
        if (hh&amp;gt;23) {&lt;br /&gt;
          hh=0;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (ss==0 || initial) {&lt;br /&gt;
      initial = 0;&lt;br /&gt;
      epaper.setTextColor(TFT_GREEN, TFT_BLACK);&lt;br /&gt;
      epaper.setCursor (8, 52);&lt;br /&gt;
      epaper.print(__DATE__); // This uses the standard ADAFruit small font&lt;br /&gt;
&lt;br /&gt;
      epaper.setTextColor(TFT_BLUE, TFT_BLACK);&lt;br /&gt;
      epaper.drawCentreString(&amp;quot;It is windy&amp;quot;,120,48,2); // Next size up font 2&lt;br /&gt;
&lt;br /&gt;
      //epaper.setTextColor(0xF81F, TFT_BLACK); // Pink&lt;br /&gt;
      //epaper.drawCentreString(&amp;quot;12.34&amp;quot;,80,100,6); // Large font 6 only contains characters [space] 0 1 2 3 4 5 6 7 8 9 . : a p m&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Update digital time&lt;br /&gt;
    byte xpos = 6;&lt;br /&gt;
    byte ypos = 0;&lt;br /&gt;
    if (omm != mm) { // Only redraw every minute to minimise flicker&lt;br /&gt;
      // Uncomment ONE of the next 2 lines, using the ghost image demonstrates text overlay as time is drawn over it&lt;br /&gt;
      epaper.setTextColor(TFT_BLACK, TFT_BLACK);  // Leave a 7 segment ghost image, comment out next line!&lt;br /&gt;
      //epaper.setTextColor(TFT_BLACK, TFT_BLACK); // Set font colour to black to wipe image&lt;br /&gt;
      // Font 7 is to show a pseudo 7 segment display.&lt;br /&gt;
      // Font 7 only contains characters [space] 0 1 2 3 4 5 6 7 8 9 0 : .&lt;br /&gt;
      epaper.drawString(&amp;quot;88:88&amp;quot;,xpos,ypos,7); // Overwrite the text to clear it&lt;br /&gt;
      epaper.setTextColor(0xFBE0); // Orange&lt;br /&gt;
      omm = mm;&lt;br /&gt;
&lt;br /&gt;
      if (hh&amp;lt;10) xpos+= epaper.drawChar(&amp;#039;0&amp;#039;,xpos,ypos,7);&lt;br /&gt;
      xpos+= epaper.drawNumber(hh,xpos,ypos,7);&lt;br /&gt;
      xcolon=xpos;&lt;br /&gt;
      xpos+= epaper.drawChar(&amp;#039;:&amp;#039;,xpos,ypos,7);&lt;br /&gt;
      if (mm&amp;lt;10) xpos+= epaper.drawChar(&amp;#039;0&amp;#039;,xpos,ypos,7);&lt;br /&gt;
      epaper.drawNumber(mm,xpos,ypos,7);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (ss%2) { // Flash the colon&lt;br /&gt;
      epaper.setTextColor(TFT_BLACK, TFT_BLACK);&lt;br /&gt;
      xpos+= epaper.drawChar(&amp;#039;:&amp;#039;,xcolon,ypos,7);&lt;br /&gt;
      epaper.setTextColor(0xFBE0, TFT_BLACK);&lt;br /&gt;
    }&lt;br /&gt;
    else {&lt;br /&gt;
      epaper.drawChar(&amp;#039;:&amp;#039;,xcolon,ypos,7);&lt;br /&gt;
      colour = random(0xFFFF);&lt;br /&gt;
      // Erase the old text with a rectangle, the disadvantage of this method is increased display flicker&lt;br /&gt;
      epaper.fillRect (0, 64, 160, 20, TFT_BLACK);&lt;br /&gt;
      epaper.setTextColor(TFT_WHITE);&lt;br /&gt;
    }&lt;br /&gt;
    epaper.update(); // update the display&lt;br /&gt;
  }&lt;br /&gt;
#endif&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;onglet driver.h&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// driver.h file &lt;br /&gt;
#define BOARD_SCREEN_COMBO 505 // 1.54 inch monochrome ePaper Screen （SSD1681）&lt;br /&gt;
#define USE_XIAO_EPAPER_BREAKOUT_BOARD&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [Code 2 Display a clock - WIFI] ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;TFT_eSPI.h&amp;gt;   // Librairie pour ton écran E-paper&lt;br /&gt;
#include &amp;lt;SPI.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
EPaper epaper = EPaper();  // Pins définis dans User_Setup.h&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// ⚙️ Paramètres WiFi&lt;br /&gt;
const char* ssid     = &amp;quot;TON_SSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TON_MOTDEPASSE&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ⚙️ Paramètres NTP&lt;br /&gt;
const char* ntpServer = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const long  gmtOffset_sec = 3600;       // Décalage GMT (ex: +1h pour Suisse en hiver)&lt;br /&gt;
const int   daylightOffset_sec = 3600;  // Décalage été (DST)&lt;br /&gt;
&lt;br /&gt;
// Variables pour éviter scintillement&lt;br /&gt;
int lastMinute = -1;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
  epaper.begin();&lt;br /&gt;
  epaper.setRotation(1);&lt;br /&gt;
  epaper.fillScreen(TFT_BLACK);&lt;br /&gt;
  epaper.setTextColor(TFT_WHITE, TFT_BLACK);&lt;br /&gt;
  epaper.update();&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Initialisation NTP&lt;br /&gt;
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  // Récupérer l’heure système&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    return; // Si pas d’heure dispo&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Rafraîchir uniquement si la minute change&lt;br /&gt;
  if (timeinfo.tm_min != lastMinute) {&lt;br /&gt;
    lastMinute = timeinfo.tm_min;&lt;br /&gt;
&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
    epaper.fillScreen(TFT_BLACK);&lt;br /&gt;
&lt;br /&gt;
    // Afficher la date&lt;br /&gt;
    epaper.setTextColor(TFT_GREEN, TFT_BLACK);&lt;br /&gt;
    epaper.setCursor(10, 20);&lt;br /&gt;
    epaper.printf(&amp;quot;%02d/%02d/%04d&amp;quot;, timeinfo.tm_mday, timeinfo.tm_mon+1, timeinfo.tm_year+1900);&lt;br /&gt;
&lt;br /&gt;
    // Afficher l’heure&lt;br /&gt;
    epaper.setTextColor(TFT_ORANGE, TFT_BLACK);&lt;br /&gt;
    epaper.setCursor(10, 60);&lt;br /&gt;
    epaper.printf(&amp;quot;%02d:%02d&amp;quot;, timeinfo.tm_hour, timeinfo.tm_min);&lt;br /&gt;
&lt;br /&gt;
    epaper.update(); // Mise à jour écran&lt;br /&gt;
#endif&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  delay(1000); // Boucle chaque seconde mais rafraîchit seulement à chaque minute&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [Code 2 Display a clock - WIFI v2] ===&lt;br /&gt;
&lt;br /&gt;
version modifié&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;TFT_eSPI.h&amp;gt;   // Librairie pour ton écran E-paper&lt;br /&gt;
#include &amp;lt;SPI.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
EPaper epaper = EPaper();  // Pins définis dans User_Setup.h&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// ⚙️ Paramètres WiFi&lt;br /&gt;
const char* ssid     = &amp;quot;TON_SSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TON_MOTDEPASSE&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ⚙️ Paramètres NTP&lt;br /&gt;
const char* ntpServer = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const long  gmtOffset_sec = 3600;       // Décalage GMT (ex: +1h pour Suisse en hiver)&lt;br /&gt;
const int   daylightOffset_sec = 3600;  // Décalage été (DST)&lt;br /&gt;
&lt;br /&gt;
// Variables pour éviter scintillement&lt;br /&gt;
int lastMinute = -1;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
  epaper.begin();&lt;br /&gt;
  epaper.setRotation(1);&lt;br /&gt;
  epaper.fillScreen(TFT_WHITE);              // Fond blanc&lt;br /&gt;
  epaper.setTextColor(TFT_BLACK, TFT_WHITE); // Texte noir sur fond blanc&lt;br /&gt;
  epaper.update();&lt;br /&gt;
  epaper.sleep(); // Mise en veille après init&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  Serial.print(&amp;quot;Connexion au WiFi &amp;quot;);&lt;br /&gt;
  Serial.println(ssid);&lt;br /&gt;
&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot;\nWiFi connecté !&amp;quot;);&lt;br /&gt;
  Serial.print(&amp;quot;Adresse IP : &amp;quot;);&lt;br /&gt;
  Serial.println(WiFi.localIP());&lt;br /&gt;
  Serial.print(&amp;quot;Adresse MAC : &amp;quot;);&lt;br /&gt;
  Serial.println(WiFi.macAddress());&lt;br /&gt;
&lt;br /&gt;
  // Initialisation NTP&lt;br /&gt;
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  // Récupérer l’heure système&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Erreur récupération heure NTP&amp;quot;);&lt;br /&gt;
    return; // Si pas d’heure dispo&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Rafraîchir uniquement si la minute change&lt;br /&gt;
  if (timeinfo.tm_min != lastMinute) {&lt;br /&gt;
    lastMinute = timeinfo.tm_min;&lt;br /&gt;
&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
    //epaper.wakeup(); // Réveille l’écran avant mise à jour&lt;br /&gt;
    epaper.fillScreen(TFT_WHITE);&lt;br /&gt;
&lt;br /&gt;
    // --- Affichage DATE (plus petite, centrée en haut) ---&lt;br /&gt;
    epaper.setTextColor(TFT_BLACK, TFT_WHITE);&lt;br /&gt;
    epaper.setTextDatum(TC_DATUM); // Centrage horizontal (Top Center)&lt;br /&gt;
    epaper.drawString(&lt;br /&gt;
      String(timeinfo.tm_mday) + &amp;quot;/&amp;quot; + &lt;br /&gt;
      String(timeinfo.tm_mon+1) + &amp;quot;/&amp;quot; + &lt;br /&gt;
      String(timeinfo.tm_year+1900),&lt;br /&gt;
      epaper.width()/2, 30, 4   // police taille 2 -&amp;gt; 4&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    // --- Affichage HEURE (plus grande, centrée au milieu) ---&lt;br /&gt;
    char buffer[6];&lt;br /&gt;
    sprintf(buffer, &amp;quot;%02d:%02d&amp;quot;, timeinfo.tm_hour, timeinfo.tm_min);&lt;br /&gt;
    epaper.setTextDatum(MC_DATUM); // Centrage horizontal + vertical (Middle Center)&lt;br /&gt;
    epaper.drawString(buffer, epaper.width()/2, epaper.height()/2, 7); // police taille 6 -&amp;gt; 7&lt;br /&gt;
&lt;br /&gt;
    epaper.update(); // Mise à jour écran&lt;br /&gt;
    //epaper.sleep();  // Mise en veille après mise à jour&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
    // --- Sortie série ---&lt;br /&gt;
    Serial.printf(&amp;quot;Heure actuelle : %02d:%02d:%02d\n&amp;quot;, &lt;br /&gt;
                  timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  delay(1000); // Boucle chaque seconde mais rafraîchit seulement à chaque minute&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>144.2.107.134</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.myows.top/index.php?title=1.54-inch_E-paper_Display&amp;diff=2039</id>
		<title>1.54-inch E-paper Display</title>
		<link rel="alternate" type="text/html" href="https://wiki.myows.top/index.php?title=1.54-inch_E-paper_Display&amp;diff=2039"/>
		<updated>2025-12-12T22:56:44Z</updated>

		<summary type="html">&lt;p&gt;144.2.107.134: /* [Code 2 Display a clock - WIFI v2] */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
=== Support ===&lt;br /&gt;
&lt;br /&gt;
1.54-inch E-paper Display&lt;br /&gt;
&lt;br /&gt;
[[File:EPaper-Display-1.54.PNG|250px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Setup&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 Install Seeed &amp;lt;b&amp;gt;GFX Library&amp;lt;/b&amp;gt;&lt;br /&gt;
 https://github.com/Seeed-Studio/Seeed_GFX&lt;br /&gt;
&lt;br /&gt;
This library has same function as TFT library and no compatible with it. If you have installed TFT library or other similary display libraries, please uninstall it first.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Create a driver.h file&amp;lt;/b&amp;gt; and paste the following code into it.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Seeed GFX Library - &amp;lt;b&amp;gt;Online Configuration Generator&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
https://seeed-studio.github.io/Seeed_GFX/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// driver.h file &lt;br /&gt;
#define BOARD_SCREEN_COMBO 505 // 1.54 inch monochrome ePaper Screen （SSD1681）&lt;br /&gt;
#define USE_XIAO_EPAPER_BREAKOUT_BOARD&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sketch -&amp;gt; &amp;lt;b&amp;gt;Include Library&amp;lt;/b&amp;gt; -&amp;gt; Add .ZIP&amp;lt;br&amp;gt;&lt;br /&gt;
Seeed_GFX-master.zip&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Upload the Code&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
driver.h&amp;lt;br&amp;gt;&lt;br /&gt;
HelloWorld.ino&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Liens externes ====&lt;br /&gt;
&lt;br /&gt;
https://www.seeedstudio.com/1-54-Monochrome-ePaper-Display-with-200x200-Pixels-p-5776.html &amp;lt;font color=red&amp;gt;Shop&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://wiki.seeedstudio.com/XIAO-eInk-Expansion-Board/ &amp;lt;font color=red&amp;gt;Wiki&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exemples ===&lt;br /&gt;
&lt;br /&gt;
/examples/ePaper/Basic&lt;br /&gt;
&lt;br /&gt;
1 Bitmap: Display a bitmap image.&amp;lt;br&amp;gt;&lt;br /&gt;
2 Clock: Display a clock.&amp;lt;br&amp;gt;&lt;br /&gt;
3 Clock_digital: Display a digital clock.&amp;lt;br&amp;gt;&lt;br /&gt;
4 HelloWorld: &amp;lt;br&amp;gt;&lt;br /&gt;
5 Shape: Display different sizes of words and shape randomly.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [Code 1] Display a bitmap image ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;quot;TFT_eSPI.h&amp;quot;&lt;br /&gt;
#include &amp;quot;image.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
EPaper epaper;&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
  delay(2000);&lt;br /&gt;
  Serial.println(&amp;quot;1.54\&amp;quot; E-Paper Bitmap Display Example&amp;quot;);&lt;br /&gt;
  &lt;br /&gt;
  epaper.begin();&lt;br /&gt;
  &lt;br /&gt;
  // Clear screen to white&lt;br /&gt;
  epaper.fillScreen(TFT_WHITE);&lt;br /&gt;
  epaper.update();&lt;br /&gt;
  delay(1000);&lt;br /&gt;
  &lt;br /&gt;
  // Display bitmap image using drawBitmap API&lt;br /&gt;
  // drawBitmap(x, y, bitmap_data, width, height, color)&lt;br /&gt;
  epaper.drawBitmap(0, 0, gImage_1inch54, 200, 200, TFT_BLACK);&lt;br /&gt;
  epaper.update();&lt;br /&gt;
  &lt;br /&gt;
  Serial.println(&amp;quot;Bitmap displayed successfully&amp;quot;);&lt;br /&gt;
  &lt;br /&gt;
  // Put display to sleep to save power&lt;br /&gt;
  epaper.sleep();&lt;br /&gt;
#else&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
  Serial.println(&amp;quot;EPAPER_ENABLE not defined. Please select the correct setup file.&amp;quot;);&lt;br /&gt;
#endif&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop()&lt;br /&gt;
{&lt;br /&gt;
  // Nothing to do here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;onglet driver.h&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// driver.h file &lt;br /&gt;
#define BOARD_SCREEN_COMBO 505 // 1.54 inch monochrome ePaper Screen （SSD1681）&lt;br /&gt;
#define USE_XIAO_EPAPER_BREAKOUT_BOARD&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;onglet image.h&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * Image header file for 1.54&amp;quot; E-Paper Display&lt;br /&gt;
 * &lt;br /&gt;
 * Image specifications:&lt;br /&gt;
 * - Size: 200x200 pixels&lt;br /&gt;
 * - Format: 1-bit monochrome bitmap&lt;br /&gt;
 * - Color depth: Black and White&lt;br /&gt;
 * &lt;br /&gt;
 * To generate your own image:&lt;br /&gt;
 * 1. Prepare a 200x200 pixel image&lt;br /&gt;
 * 2. Convert to 1-bit monochrome bitmap&lt;br /&gt;
 * 3. Use image2cpp or similar tool to generate C array&lt;br /&gt;
 * 4. Replace the array below with your generated data&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
#ifndef _IMAGE_H_&lt;br /&gt;
#define _IMAGE_H_&lt;br /&gt;
&lt;br /&gt;
// Placeholder for 200x200 bitmap image&lt;br /&gt;
// Replace this with your actual image data&lt;br /&gt;
const unsigned char gImage_1inch54[] PROGMEM = {&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0xC0, 0x00, 0x00,&lt;br /&gt;
  0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x07, 0xC0,&lt;br /&gt;
  0x7C, 0x07, 0xC0, 0xFD, 0x81, 0xFC, 0xC6, 0x18, 0x7E, 0xC0, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x0F, 0xF0, 0xFE, 0x1F, 0xE1, 0xFF, 0x83, 0xFC, 0xEE,&lt;br /&gt;
  0x18, 0xFF, 0xCC, 0x7F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,&lt;br /&gt;
  0x1C, 0x71, 0xC7, 0x1C, 0x73, 0xC7, 0x83, 0x00, 0xEE, 0x19, 0xE3, 0xCC, 0xE3, 0xC0, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x18, 0x3B, 0x83, 0x38, 0x33, 0x83, 0x83,&lt;br /&gt;
  0x80, 0xCE, 0x19, 0xC1, 0xCD, 0xC1, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x7C, 0x3F, 0xFB, 0xFF, 0xBF, 0xF3, 0x03, 0x83, 0xF0, 0xCE, 0x19, 0x81, 0xCD, 0xC0, 0xC0,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0xFB, 0xFF, 0xBF, 0xF3,&lt;br /&gt;
  0x03, 0x81, 0xFC, 0xCE, 0x19, 0x81, 0xCD, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x07, 0xB8, 0x03, 0x80, 0x38, 0x03, 0x03, 0x80, 0x1C, 0xCE, 0x19, 0x81, 0xCD,&lt;br /&gt;
  0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x9C, 0x01, 0x80,&lt;br /&gt;
  0x38, 0x03, 0x87, 0x80, 0x0C, 0xC6, 0x19, 0xC3, 0xCC, 0xE1, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x9F, 0xF1, 0xFF, 0x1F, 0xE1, 0xFF, 0x83, 0x1C, 0xE7, 0xF8,&lt;br /&gt;
  0xFF, 0xCC, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x0F,&lt;br /&gt;
  0xE0, 0xFE, 0x0F, 0xE0, 0xFF, 0x83, 0xF8, 0xE3, 0xF0, 0x7F, 0xCC, 0x7F, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x03, 0x80, 0x38, 0x03, 0x80, 0x39, 0x80, 0xE0,&lt;br /&gt;
  0x20, 0xC0, 0x1C, 0xCC, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0xC0, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79,&lt;br /&gt;
  0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x38, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0xC0, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0xDC, 0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x18, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFE, 0xFC, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x01, 0x80, 0x13, 0xC6, 0xE6, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xC0, 0xB7, 0xE6, 0x66, 0xE4,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0xF8, 0xE6, 0x66, 0x66, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xFC, 0xC6, 0x76,&lt;br /&gt;
  0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xF0,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x04, 0x3C, 0xCC, 0xC6, 0x66, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x30, 0xCC,&lt;br /&gt;
  0xC3, 0xE6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,&lt;br /&gt;
  0xFF, 0xF8, 0x00, 0x03, 0x00, 0x3F, 0x3B, 0x70, 0xCE, 0xC1, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFF, 0xF8, 0x00, 0x43, 0x06, 0x3F, 0x33,&lt;br /&gt;
  0xB0, 0xE6, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFE,&lt;br /&gt;
  0x00, 0x00, 0xFF, 0xF8, 0x00, 0xE3, 0x9F, 0xBB, 0xB3, 0xBE, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0xF8, 0x00, 0xF7, 0x99,&lt;br /&gt;
  0x99, 0xBB, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F,&lt;br /&gt;
  0xFF, 0xFF, 0x00, 0x01, 0xFF, 0xF8, 0x00, 0xF7, 0x99, 0x99, 0x9F, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0xFC, 0x00,&lt;br /&gt;
  0x7F, 0x99, 0x99, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x1F, 0xFF, 0xFF, 0x00, 0x03, 0xFB, 0xFC, 0x00, 0x7D, 0x9F, 0x98, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x30, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0x00, 0x03, 0xFB,&lt;br /&gt;
  0xFC, 0x00, 0x6C, 0xCF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0xE7, 0x60, 0x00, 0x00,&lt;br /&gt;
  0x0C, 0x00, 0x00, 0x1F, 0xFF, 0xE0, 0x00, 0x07, 0xF3, 0xFC, 0x00, 0x64, 0xC0, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0xC0, 0x02, 0x31, 0x33, 0x60, 0x00, 0x01, 0xFC, 0x00, 0x00, 0x1F, 0xF8, 0x00, 0x00,&lt;br /&gt;
  0x07, 0xF3, 0xFC, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x1F, 0xB8, 0x71, 0xE0,&lt;br /&gt;
  0x00, 0x03, 0xFC, 0x00, 0x00, 0x1F, 0xE0, 0x00, 0x00, 0x07, 0xF3, 0xFE, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0xFC, 0x07, 0x99, 0x99, 0xB1, 0xC0, 0x00, 0x07, 0xFC, 0x00, 0x00, 0x1F, 0xE0,&lt;br /&gt;
  0x00, 0x00, 0x0F, 0xF3, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x66, 0x19, 0x99,&lt;br /&gt;
  0xB8, 0xC0, 0x00, 0x1F, 0xFE, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0x0F, 0xE3, 0xFE, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0x67, 0x19, 0x99, 0xF8, 0xC1, 0x00, 0x7F, 0xFE, 0x00, 0x00,&lt;br /&gt;
  0x0F, 0xF0, 0x00, 0x00, 0x0F, 0xE1, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xC6, 0x67,&lt;br /&gt;
  0xD9, 0x9C, 0xC1, 0xFF, 0x01, 0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0x1F, 0xE1, 0xFE,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xE7, 0x60, 0xDF, 0x80, 0x0F, 0xFF, 0x01, 0xFF, 0xFE,&lt;br /&gt;
  0x00, 0x00, 0x0F, 0xF7, 0xFC, 0x00, 0x1F, 0xC1, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0xE0,&lt;br /&gt;
  0x66, 0x77, 0xDE, 0x01, 0xFF, 0xFF, 0x01, 0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x3F,&lt;br /&gt;
  0xC1, 0xFF, 0x00, 0x00, 0x04, 0x00, 0x3E, 0x66, 0xC0, 0x66, 0x37, 0x8C, 0x7F, 0xFF, 0xFF, 0x01,&lt;br /&gt;
  0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xC0, 0x3F, 0x81, 0xFF, 0xF0, 0x00, 0x3F, 0x0E, 0x7F,&lt;br /&gt;
  0x7E, 0xE0, 0x7C, 0x20, 0x0F, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x0F, 0xFF, 0xFF,&lt;br /&gt;
  0xC0, 0x3F, 0x81, 0xFF, 0xF0, 0x00, 0x3B, 0xBE, 0x73, 0x78, 0x60, 0x78, 0x03, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0x00, 0x81, 0xFF, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xE0, 0x7F, 0x9F, 0xFF, 0xF0, 0x00, 0x31,&lt;br /&gt;
  0x87, 0x73, 0x70, 0x60, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x07,&lt;br /&gt;
  0xFF, 0xFF, 0xF0, 0x7F, 0xFF, 0xFF, 0xF0, 0x0F, 0x3B, 0x8F, 0x33, 0x3E, 0x40, 0x0F, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x07, 0xF8, 0x7F, 0xF0, 0x7F, 0xFF, 0xFF, 0xF8,&lt;br /&gt;
  0x0D, 0x9F, 0x1B, 0x3F, 0x18, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0x00,&lt;br /&gt;
  0x00, 0x07, 0xE0, 0x3F, 0xF0, 0xFF, 0xFF, 0xFF, 0xF8, 0x19, 0x9C, 0x3B, 0x3E, 0x00, 0x7F, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x00, 0xC0, 0x1F, 0xF8, 0x7F, 0xFF,&lt;br /&gt;
  0xFF, 0xF0, 0x1F, 0x98, 0x1F, 0x30, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,&lt;br /&gt;
  0xFF, 0x80, 0x00, 0x00, 0x00, 0x0F, 0xF8, 0x7F, 0xFF, 0xFF, 0x80, 0x1C, 0x18, 0x00, 0x33, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x0F, 0xF8,&lt;br /&gt;
  0x7F, 0xFF, 0xFF, 0x80, 0x0F, 0x98, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0x00, 0x00, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x0F, 0xF8, 0x7F, 0xC0, 0x7F, 0x80, 0x07, 0x00, 0x1F,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x80, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x0F, 0xF8, 0x78, 0x00, 0x7F, 0xC0, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0x7F, 0xC0, 0x00,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x7F, 0xC0, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0x7F, 0xC0, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x00, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0x3F,&lt;br /&gt;
  0xC7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x7F,&lt;br /&gt;
  0xC0, 0x00, 0x01, 0x80, 0x1F, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x03, 0xE0, 0x7F, 0xF0, 0x00,&lt;br /&gt;
  0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,&lt;br /&gt;
  0x00, 0x7F, 0xC0, 0x00, 0x03, 0xFF, 0xFF, 0xE0, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x07, 0xFF, 0xFF,&lt;br /&gt;
  0xE0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0x00, 0x00, 0x3F, 0xE0, 0x00, 0x07, 0xFF, 0xFF, 0xC0, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0xE0, 0x00, 0x07,&lt;br /&gt;
  0xFF, 0xFF, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0xE7, 0xC1, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0xFF,&lt;br /&gt;
  0xC3, 0xC1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0xFF, 0xC3, 0xE0, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x0F,&lt;br /&gt;
  0xFF, 0xFF, 0xC3, 0xE1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0x00, 0x1F, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x7F, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFE, 0x7F, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xEF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xC1, 0xFF, 0xFF, 0xFE, 0x7F, 0xF7, 0x3F, 0xFF, 0xFF,&lt;br /&gt;
  0xF1, 0xE3, 0xE7, 0xF2, 0x39, 0x3F, 0xFF, 0xC7, 0x8F, 0x9F, 0xCC, 0xE7, 0x7F, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xC0, 0xFF, 0xFF, 0xFE, 0x7F, 0xE7, 0xFF, 0xFF, 0xFF, 0xC0, 0xC1, 0xC3, 0xF3, 0x39, 0xBC, 0xF3,&lt;br /&gt;
  0x03, 0x07, 0x0F, 0xCC, 0xE7, 0x3F, 0xFF, 0xFF, 0xFF, 0xCE, 0x61, 0xC3, 0x8E, 0x66, 0x41, 0x38,&lt;br /&gt;
  0x70, 0x73, 0xFC, 0xCC, 0x99, 0xF7, 0x33, 0xBE, 0x67, 0xF3, 0x32, 0x67, 0xDC, 0xE7, 0x3F, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xCC, 0x40, 0x83, 0x06, 0x66, 0x41, 0x30, 0x30, 0x33, 0xFC, 0xCC, 0x99, 0xF7, 0x33,&lt;br /&gt;
  0x9F, 0x0F, 0xF3, 0x32, 0x67, 0xDC, 0x67, 0xBF, 0xFF, 0xFF, 0xFF, 0xC0, 0xCC, 0x8E, 0x62, 0x66,&lt;br /&gt;
  0x67, 0x33, 0x33, 0x33, 0xF8, 0xCC, 0x99, 0xE7, 0x13, 0x9F, 0x9F, 0xE3, 0x32, 0x67, 0x9C, 0x07,&lt;br /&gt;
  0xBF, 0xFF, 0xFF, 0xFF, 0xC1, 0xC0, 0xC2, 0x72, 0x66, 0x67, 0x33, 0x33, 0x3F, 0xF9, 0xCC, 0x99,&lt;br /&gt;
  0xE7, 0x97, 0x9F, 0x0F, 0xE7, 0x32, 0x67, 0x9C, 0x67, 0xBF, 0xFF, 0xFF, 0xFF, 0xCC, 0xCF, 0xF2,&lt;br /&gt;
  0x62, 0x66, 0x67, 0x33, 0x33, 0x3F, 0xF3, 0xCC, 0x99, 0xF7, 0x87, 0x9E, 0x67, 0xCF, 0x32, 0x67,&lt;br /&gt;
  0xDC, 0xE7, 0xBF, 0xFF, 0xFF, 0xFF, 0xCC, 0xC5, 0x93, 0x06, 0x20, 0x63, 0x30, 0x33, 0x33, 0xE0,&lt;br /&gt;
  0xC1, 0x81, 0xF7, 0x87, 0x9C, 0xF3, 0x83, 0x06, 0x07, 0xDC, 0xE7, 0x3F, 0xFF, 0xFF, 0xFF, 0xCE,&lt;br /&gt;
  0x61, 0x87, 0x0F, 0x30, 0x71, 0x38, 0x73, 0x33, 0xC0, 0xE1, 0xC3, 0xF3, 0xC7, 0xBF, 0xFF, 0x03,&lt;br /&gt;
  0x8F, 0x0F, 0xCC, 0xE7, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xF3, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xFF, 0x3F, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xFF, 0x7F,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0xFE, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0x8F, 0xCE, 0x0E, 0x7F, 0xFC,&lt;br /&gt;
  0x18, 0x3E, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFE, 0x7F, 0xFF, 0xFF, 0x07, 0x86, 0x07, 0xFF, 0xFC, 0x18, 0x1C, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xE1, 0xD1, 0x91, 0xC3, 0xC4, 0x18, 0x74, 0xDF, 0xE7, 0x86, 0x62,&lt;br /&gt;
  0x60, 0xFC, 0xF9, 0x98, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xC0, 0xC0,&lt;br /&gt;
  0x81, 0xC1, 0x84, 0x10, 0x60, 0x8F, 0xE7, 0x26, 0x62, 0x60, 0x7C, 0xF9, 0x99, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xCC, 0xCC, 0x88, 0x99, 0x1E, 0x73, 0x23, 0xDF, 0xE6,&lt;br /&gt;
  0x66, 0x06, 0x66, 0x7C, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF,&lt;br /&gt;
  0xCC, 0xCC, 0x8C, 0x81, 0x3E, 0x63, 0x23, 0xFF, 0xCE, 0x06, 0x0E, 0x66, 0x7C, 0x38, 0x39, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xCC, 0xCC, 0x8C, 0x9F, 0x3E, 0x73, 0x23,&lt;br /&gt;
  0xFF, 0x8E, 0x06, 0x7E, 0x66, 0x7C, 0xF9, 0xF9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xC0, 0xC0, 0xCC, 0x8C, 0x8B, 0x86, 0x30, 0x23, 0x8F, 0x03, 0xE6, 0x7E, 0x66, 0x7C, 0xF9,&lt;br /&gt;
  0xFC, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xE1, 0xCC, 0x8C, 0xC3, 0x87,&lt;br /&gt;
  0x18, 0x63, 0x9F, 0x03, 0xE6, 0x7E, 0x66, 0x7C, 0xF9, 0xFE, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xCF, 0xFF, 0xFE, 0x7C, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xFF, 0xFC, 0x7C,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF,&lt;br /&gt;
  0xE9, 0x0E, 0x66, 0x1C, 0x61, 0xCE, 0x1D, 0xF8, 0x7C, 0xE1, 0x99, 0xC7, 0x30, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xE1, 0x06, 0x64, 0x18, 0x60, 0xCC, 0x18,&lt;br /&gt;
  0xF8, 0x7C, 0xC0, 0x99, 0x83, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xCC, 0x67, 0xE6, 0x64, 0x71, 0xFC, 0xCC, 0xCD, 0xF2, 0x7C, 0xCC, 0x99, 0x33, 0x23, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCC, 0x67, 0x07, 0x0E, 0x13, 0xE0,&lt;br /&gt;
  0xCC, 0x0F, 0xF0, 0x3C, 0xC0, 0xCB, 0x03, 0x30, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xCE, 0x67, 0x27, 0x0F, 0x93, 0xE4, 0xCC, 0xFF, 0xF0, 0x3C, 0xCF, 0xC3, 0x3F,&lt;br /&gt;
  0x3C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x67, 0x07, 0x9C,&lt;br /&gt;
  0x98, 0x60, 0xC4, 0x58, 0xFE, 0x7C, 0x45, 0xC3, 0x17, 0x24, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xE7, 0x07, 0x9C, 0x38, 0x60, 0xE6, 0x19, 0xFE, 0x7E, 0x61,&lt;br /&gt;
  0xE7, 0x83, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFE, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xFE, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0x87, 0x07, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xCF, 0xFC, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0x07, 0x03, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCC, 0x98, 0x30, 0xC8, 0x18, 0x78,&lt;br /&gt;
  0xE3, 0x9F, 0x3F, 0x33, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xCC, 0x08, 0x20, 0xC0, 0x18, 0x30, 0xC1, 0x9F, 0x1F, 0x33, 0x3F, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCC, 0xCC, 0xE6, 0x47,&lt;br /&gt;
  0x3E, 0x23, 0x89, 0x9F, 0x07, 0x03, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCC, 0xCC, 0xE0, 0x4F, 0x38, 0x27, 0x81, 0xFF, 0xE3, 0x07, 0x3F,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCC, 0xCC,&lt;br /&gt;
  0xE7, 0xCF, 0x33, 0x23, 0x8F, 0xFF, 0xF3, 0x3F, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCC, 0xCC, 0x62, 0xCF, 0x30, 0x30, 0xC1, 0x9F, 0x03,&lt;br /&gt;
  0x3F, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xCC, 0xCE, 0x30, 0xCF, 0x38, 0x30, 0xE1, 0x9F, 0x07, 0x3F, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [Code 2 Display a clock] ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 An example digital clock using a TFT LCD screen to show the time.&lt;br /&gt;
 Demonstrates use of the font printing routines. (Time updates but date does not.)&lt;br /&gt;
 &lt;br /&gt;
 For a more accurate clock, it would be better to use the RTClib library.&lt;br /&gt;
 But this is just a demo. &lt;br /&gt;
 &lt;br /&gt;
 This examples uses the hardware SPI only. Non-hardware SPI&lt;br /&gt;
 is just too slow (~8 times slower!)&lt;br /&gt;
 &lt;br /&gt;
 Based on clock sketch by Gilchrist 6/2/2014 1.0&lt;br /&gt;
 Updated by Bodmer&lt;br /&gt;
A few colour codes:&lt;br /&gt;
 &lt;br /&gt;
code	color&lt;br /&gt;
0x0000	Black&lt;br /&gt;
0xFFFF	White&lt;br /&gt;
0xBDF7	Light Gray&lt;br /&gt;
0x7BEF	Dark Gray&lt;br /&gt;
0xF800	Red&lt;br /&gt;
0xFFE0	Yellow&lt;br /&gt;
0xFBE0	Orange&lt;br /&gt;
0x79E0	Brown&lt;br /&gt;
0x7E0	Green&lt;br /&gt;
0x7FF	Cyan&lt;br /&gt;
0x1F	Blue&lt;br /&gt;
0xF81F	Pink&lt;br /&gt;
&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;TFT_eSPI.h&amp;gt; // Graphics and font library for ST7735 driver chip&lt;br /&gt;
#include &amp;lt;SPI.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#ifdef EPAPER_ENABLE // Only compile this code if the EPAPER_ENABLE is defined in User_Setup.h&lt;br /&gt;
&lt;br /&gt;
EPaper epaper = EPaper();  // Invoke library, pins defined in User_Setup.h&lt;br /&gt;
&lt;br /&gt;
uint32_t targetTime = 0;       // for next 1 second timeout&lt;br /&gt;
&lt;br /&gt;
byte omm = 99;&lt;br /&gt;
bool initial = 1;&lt;br /&gt;
byte xcolon = 0;&lt;br /&gt;
unsigned int colour = 0;&lt;br /&gt;
&lt;br /&gt;
static uint8_t conv2d(const char* p) {&lt;br /&gt;
  uint8_t v = 0;&lt;br /&gt;
  if (&amp;#039;0&amp;#039; &amp;lt;= *p &amp;amp;&amp;amp; *p &amp;lt;= &amp;#039;9&amp;#039;)&lt;br /&gt;
    v = *p - &amp;#039;0&amp;#039;;&lt;br /&gt;
  return 10 * v + *++p - &amp;#039;0&amp;#039;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
uint8_t hh=conv2d(__TIME__), mm=conv2d(__TIME__+3), ss=conv2d(__TIME__+6);  // Get H, M, S from compile time&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
void setup(void) {&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
  epaper.begin();&lt;br /&gt;
  epaper.setRotation(1);&lt;br /&gt;
  epaper.fillScreen(TFT_BLACK);&lt;br /&gt;
&lt;br /&gt;
  epaper.setTextColor(TFT_YELLOW, TFT_BLACK); // Note: the new fonts do not draw the background colour&lt;br /&gt;
  epaper.update(); // update the display&lt;br /&gt;
  targetTime = millis() + 1000; &lt;br /&gt;
#endif&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
  if (targetTime &amp;lt; millis()) {&lt;br /&gt;
    targetTime = millis()+1000;&lt;br /&gt;
    ss++;              // Advance second&lt;br /&gt;
    if (ss==60) {&lt;br /&gt;
      ss=0;&lt;br /&gt;
      omm = mm;&lt;br /&gt;
      mm++;            // Advance minute&lt;br /&gt;
      if(mm&amp;gt;59) {&lt;br /&gt;
        mm=0;&lt;br /&gt;
        hh++;          // Advance hour&lt;br /&gt;
        if (hh&amp;gt;23) {&lt;br /&gt;
          hh=0;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (ss==0 || initial) {&lt;br /&gt;
      initial = 0;&lt;br /&gt;
      epaper.setTextColor(TFT_GREEN, TFT_BLACK);&lt;br /&gt;
      epaper.setCursor (8, 52);&lt;br /&gt;
      epaper.print(__DATE__); // This uses the standard ADAFruit small font&lt;br /&gt;
&lt;br /&gt;
      epaper.setTextColor(TFT_BLUE, TFT_BLACK);&lt;br /&gt;
      epaper.drawCentreString(&amp;quot;It is windy&amp;quot;,120,48,2); // Next size up font 2&lt;br /&gt;
&lt;br /&gt;
      //epaper.setTextColor(0xF81F, TFT_BLACK); // Pink&lt;br /&gt;
      //epaper.drawCentreString(&amp;quot;12.34&amp;quot;,80,100,6); // Large font 6 only contains characters [space] 0 1 2 3 4 5 6 7 8 9 . : a p m&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Update digital time&lt;br /&gt;
    byte xpos = 6;&lt;br /&gt;
    byte ypos = 0;&lt;br /&gt;
    if (omm != mm) { // Only redraw every minute to minimise flicker&lt;br /&gt;
      // Uncomment ONE of the next 2 lines, using the ghost image demonstrates text overlay as time is drawn over it&lt;br /&gt;
      epaper.setTextColor(TFT_BLACK, TFT_BLACK);  // Leave a 7 segment ghost image, comment out next line!&lt;br /&gt;
      //epaper.setTextColor(TFT_BLACK, TFT_BLACK); // Set font colour to black to wipe image&lt;br /&gt;
      // Font 7 is to show a pseudo 7 segment display.&lt;br /&gt;
      // Font 7 only contains characters [space] 0 1 2 3 4 5 6 7 8 9 0 : .&lt;br /&gt;
      epaper.drawString(&amp;quot;88:88&amp;quot;,xpos,ypos,7); // Overwrite the text to clear it&lt;br /&gt;
      epaper.setTextColor(0xFBE0); // Orange&lt;br /&gt;
      omm = mm;&lt;br /&gt;
&lt;br /&gt;
      if (hh&amp;lt;10) xpos+= epaper.drawChar(&amp;#039;0&amp;#039;,xpos,ypos,7);&lt;br /&gt;
      xpos+= epaper.drawNumber(hh,xpos,ypos,7);&lt;br /&gt;
      xcolon=xpos;&lt;br /&gt;
      xpos+= epaper.drawChar(&amp;#039;:&amp;#039;,xpos,ypos,7);&lt;br /&gt;
      if (mm&amp;lt;10) xpos+= epaper.drawChar(&amp;#039;0&amp;#039;,xpos,ypos,7);&lt;br /&gt;
      epaper.drawNumber(mm,xpos,ypos,7);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (ss%2) { // Flash the colon&lt;br /&gt;
      epaper.setTextColor(TFT_BLACK, TFT_BLACK);&lt;br /&gt;
      xpos+= epaper.drawChar(&amp;#039;:&amp;#039;,xcolon,ypos,7);&lt;br /&gt;
      epaper.setTextColor(0xFBE0, TFT_BLACK);&lt;br /&gt;
    }&lt;br /&gt;
    else {&lt;br /&gt;
      epaper.drawChar(&amp;#039;:&amp;#039;,xcolon,ypos,7);&lt;br /&gt;
      colour = random(0xFFFF);&lt;br /&gt;
      // Erase the old text with a rectangle, the disadvantage of this method is increased display flicker&lt;br /&gt;
      epaper.fillRect (0, 64, 160, 20, TFT_BLACK);&lt;br /&gt;
      epaper.setTextColor(TFT_WHITE);&lt;br /&gt;
    }&lt;br /&gt;
    epaper.update(); // update the display&lt;br /&gt;
  }&lt;br /&gt;
#endif&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;onglet driver.h&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// driver.h file &lt;br /&gt;
#define BOARD_SCREEN_COMBO 505 // 1.54 inch monochrome ePaper Screen （SSD1681）&lt;br /&gt;
#define USE_XIAO_EPAPER_BREAKOUT_BOARD&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [Code 2 Display a clock - WIFI] ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;TFT_eSPI.h&amp;gt;   // Librairie pour ton écran E-paper&lt;br /&gt;
#include &amp;lt;SPI.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
EPaper epaper = EPaper();  // Pins définis dans User_Setup.h&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// ⚙️ Paramètres WiFi&lt;br /&gt;
const char* ssid     = &amp;quot;TON_SSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TON_MOTDEPASSE&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ⚙️ Paramètres NTP&lt;br /&gt;
const char* ntpServer = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const long  gmtOffset_sec = 3600;       // Décalage GMT (ex: +1h pour Suisse en hiver)&lt;br /&gt;
const int   daylightOffset_sec = 3600;  // Décalage été (DST)&lt;br /&gt;
&lt;br /&gt;
// Variables pour éviter scintillement&lt;br /&gt;
int lastMinute = -1;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
  epaper.begin();&lt;br /&gt;
  epaper.setRotation(1);&lt;br /&gt;
  epaper.fillScreen(TFT_BLACK);&lt;br /&gt;
  epaper.setTextColor(TFT_WHITE, TFT_BLACK);&lt;br /&gt;
  epaper.update();&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Initialisation NTP&lt;br /&gt;
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  // Récupérer l’heure système&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    return; // Si pas d’heure dispo&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Rafraîchir uniquement si la minute change&lt;br /&gt;
  if (timeinfo.tm_min != lastMinute) {&lt;br /&gt;
    lastMinute = timeinfo.tm_min;&lt;br /&gt;
&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
    epaper.fillScreen(TFT_BLACK);&lt;br /&gt;
&lt;br /&gt;
    // Afficher la date&lt;br /&gt;
    epaper.setTextColor(TFT_GREEN, TFT_BLACK);&lt;br /&gt;
    epaper.setCursor(10, 20);&lt;br /&gt;
    epaper.printf(&amp;quot;%02d/%02d/%04d&amp;quot;, timeinfo.tm_mday, timeinfo.tm_mon+1, timeinfo.tm_year+1900);&lt;br /&gt;
&lt;br /&gt;
    // Afficher l’heure&lt;br /&gt;
    epaper.setTextColor(TFT_ORANGE, TFT_BLACK);&lt;br /&gt;
    epaper.setCursor(10, 60);&lt;br /&gt;
    epaper.printf(&amp;quot;%02d:%02d&amp;quot;, timeinfo.tm_hour, timeinfo.tm_min);&lt;br /&gt;
&lt;br /&gt;
    epaper.update(); // Mise à jour écran&lt;br /&gt;
#endif&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  delay(1000); // Boucle chaque seconde mais rafraîchit seulement à chaque minute&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [Code 2 Display a clock - WIFI v2] ===&lt;br /&gt;
&lt;br /&gt;
version modifié&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;TFT_eSPI.h&amp;gt;   // Librairie pour ton écran E-paper&lt;br /&gt;
#include &amp;lt;SPI.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
EPaper epaper = EPaper();  // Pins définis dans User_Setup.h&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// ⚙️ Paramètres WiFi&lt;br /&gt;
const char* ssid     = &amp;quot;TON_SSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TON_MOTDEPASSE&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ⚙️ Paramètres NTP&lt;br /&gt;
const char* ntpServer = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const long  gmtOffset_sec = 3600;       // Décalage GMT (ex: +1h pour Suisse en hiver)&lt;br /&gt;
const int   daylightOffset_sec = 3600;  // Décalage été (DST)&lt;br /&gt;
&lt;br /&gt;
// Variables pour éviter scintillement&lt;br /&gt;
int lastMinute = -1;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
  epaper.begin();&lt;br /&gt;
  epaper.setRotation(1);&lt;br /&gt;
  epaper.fillScreen(TFT_WHITE);              // Fond blanc&lt;br /&gt;
  epaper.setTextColor(TFT_BLACK, TFT_WHITE); // Texte noir sur fond blanc&lt;br /&gt;
  epaper.update();&lt;br /&gt;
  epaper.sleep(); // Mise en veille après init&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  Serial.print(&amp;quot;Connexion au WiFi &amp;quot;);&lt;br /&gt;
  Serial.println(ssid);&lt;br /&gt;
&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot;\nWiFi connecté !&amp;quot;);&lt;br /&gt;
  Serial.print(&amp;quot;Adresse IP : &amp;quot;);&lt;br /&gt;
  Serial.println(WiFi.localIP());&lt;br /&gt;
  Serial.print(&amp;quot;Adresse MAC : &amp;quot;);&lt;br /&gt;
  Serial.println(WiFi.macAddress());&lt;br /&gt;
&lt;br /&gt;
  // Initialisation NTP&lt;br /&gt;
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  // Récupérer l’heure système&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Erreur récupération heure NTP&amp;quot;);&lt;br /&gt;
    return; // Si pas d’heure dispo&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Rafraîchir uniquement si la minute change&lt;br /&gt;
  if (timeinfo.tm_min != lastMinute) {&lt;br /&gt;
    lastMinute = timeinfo.tm_min;&lt;br /&gt;
&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
    //epaper.wakeup(); // Réveille l’écran avant mise à jour&lt;br /&gt;
    epaper.fillScreen(TFT_WHITE);&lt;br /&gt;
&lt;br /&gt;
    // --- Affichage DATE (plus petite, centrée en haut) ---&lt;br /&gt;
    epaper.setTextColor(TFT_BLACK, TFT_WHITE);&lt;br /&gt;
    epaper.setTextDatum(TC_DATUM); // Centrage horizontal (Top Center)&lt;br /&gt;
    epaper.drawString(&lt;br /&gt;
      String(timeinfo.tm_mday) + &amp;quot;/&amp;quot; + &lt;br /&gt;
      String(timeinfo.tm_mon+1) + &amp;quot;/&amp;quot; + &lt;br /&gt;
      String(timeinfo.tm_year+1900),&lt;br /&gt;
      epaper.width()/2, 30, 4   // police taille 2 -&amp;gt; 4&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    // --- Affichage HEURE (plus grande, centrée au milieu) ---&lt;br /&gt;
    char buffer[6];&lt;br /&gt;
    sprintf(buffer, &amp;quot;%02d:%02d&amp;quot;, timeinfo.tm_hour, timeinfo.tm_min);&lt;br /&gt;
    epaper.setTextDatum(MC_DATUM); // Centrage horizontal + vertical (Middle Center)&lt;br /&gt;
    epaper.drawString(buffer, epaper.width()/2, epaper.height()/2, 7); // police taille 6 -&amp;gt; 7&lt;br /&gt;
&lt;br /&gt;
    epaper.update(); // Mise à jour écran&lt;br /&gt;
    //epaper.sleep();  // Mise en veille après mise à jour&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
    // --- Sortie série ---&lt;br /&gt;
    Serial.printf(&amp;quot;Heure actuelle : %02d:%02d:%02d\n&amp;quot;, &lt;br /&gt;
                  timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  delay(1000); // Boucle chaque seconde mais rafraîchit seulement à chaque minute&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>144.2.107.134</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.myows.top/index.php?title=1.54-inch_E-paper_Display&amp;diff=2038</id>
		<title>1.54-inch E-paper Display</title>
		<link rel="alternate" type="text/html" href="https://wiki.myows.top/index.php?title=1.54-inch_E-paper_Display&amp;diff=2038"/>
		<updated>2025-12-12T22:55:34Z</updated>

		<summary type="html">&lt;p&gt;144.2.107.134: /* [Code 2 Display a clock - WIFI] */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
=== Support ===&lt;br /&gt;
&lt;br /&gt;
1.54-inch E-paper Display&lt;br /&gt;
&lt;br /&gt;
[[File:EPaper-Display-1.54.PNG|250px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Setup&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 Install Seeed &amp;lt;b&amp;gt;GFX Library&amp;lt;/b&amp;gt;&lt;br /&gt;
 https://github.com/Seeed-Studio/Seeed_GFX&lt;br /&gt;
&lt;br /&gt;
This library has same function as TFT library and no compatible with it. If you have installed TFT library or other similary display libraries, please uninstall it first.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Create a driver.h file&amp;lt;/b&amp;gt; and paste the following code into it.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Seeed GFX Library - &amp;lt;b&amp;gt;Online Configuration Generator&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
https://seeed-studio.github.io/Seeed_GFX/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// driver.h file &lt;br /&gt;
#define BOARD_SCREEN_COMBO 505 // 1.54 inch monochrome ePaper Screen （SSD1681）&lt;br /&gt;
#define USE_XIAO_EPAPER_BREAKOUT_BOARD&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sketch -&amp;gt; &amp;lt;b&amp;gt;Include Library&amp;lt;/b&amp;gt; -&amp;gt; Add .ZIP&amp;lt;br&amp;gt;&lt;br /&gt;
Seeed_GFX-master.zip&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Upload the Code&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
driver.h&amp;lt;br&amp;gt;&lt;br /&gt;
HelloWorld.ino&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Liens externes ====&lt;br /&gt;
&lt;br /&gt;
https://www.seeedstudio.com/1-54-Monochrome-ePaper-Display-with-200x200-Pixels-p-5776.html &amp;lt;font color=red&amp;gt;Shop&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://wiki.seeedstudio.com/XIAO-eInk-Expansion-Board/ &amp;lt;font color=red&amp;gt;Wiki&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exemples ===&lt;br /&gt;
&lt;br /&gt;
/examples/ePaper/Basic&lt;br /&gt;
&lt;br /&gt;
1 Bitmap: Display a bitmap image.&amp;lt;br&amp;gt;&lt;br /&gt;
2 Clock: Display a clock.&amp;lt;br&amp;gt;&lt;br /&gt;
3 Clock_digital: Display a digital clock.&amp;lt;br&amp;gt;&lt;br /&gt;
4 HelloWorld: &amp;lt;br&amp;gt;&lt;br /&gt;
5 Shape: Display different sizes of words and shape randomly.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [Code 1] Display a bitmap image ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;quot;TFT_eSPI.h&amp;quot;&lt;br /&gt;
#include &amp;quot;image.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
EPaper epaper;&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
  delay(2000);&lt;br /&gt;
  Serial.println(&amp;quot;1.54\&amp;quot; E-Paper Bitmap Display Example&amp;quot;);&lt;br /&gt;
  &lt;br /&gt;
  epaper.begin();&lt;br /&gt;
  &lt;br /&gt;
  // Clear screen to white&lt;br /&gt;
  epaper.fillScreen(TFT_WHITE);&lt;br /&gt;
  epaper.update();&lt;br /&gt;
  delay(1000);&lt;br /&gt;
  &lt;br /&gt;
  // Display bitmap image using drawBitmap API&lt;br /&gt;
  // drawBitmap(x, y, bitmap_data, width, height, color)&lt;br /&gt;
  epaper.drawBitmap(0, 0, gImage_1inch54, 200, 200, TFT_BLACK);&lt;br /&gt;
  epaper.update();&lt;br /&gt;
  &lt;br /&gt;
  Serial.println(&amp;quot;Bitmap displayed successfully&amp;quot;);&lt;br /&gt;
  &lt;br /&gt;
  // Put display to sleep to save power&lt;br /&gt;
  epaper.sleep();&lt;br /&gt;
#else&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
  Serial.println(&amp;quot;EPAPER_ENABLE not defined. Please select the correct setup file.&amp;quot;);&lt;br /&gt;
#endif&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop()&lt;br /&gt;
{&lt;br /&gt;
  // Nothing to do here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;onglet driver.h&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// driver.h file &lt;br /&gt;
#define BOARD_SCREEN_COMBO 505 // 1.54 inch monochrome ePaper Screen （SSD1681）&lt;br /&gt;
#define USE_XIAO_EPAPER_BREAKOUT_BOARD&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;onglet image.h&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * Image header file for 1.54&amp;quot; E-Paper Display&lt;br /&gt;
 * &lt;br /&gt;
 * Image specifications:&lt;br /&gt;
 * - Size: 200x200 pixels&lt;br /&gt;
 * - Format: 1-bit monochrome bitmap&lt;br /&gt;
 * - Color depth: Black and White&lt;br /&gt;
 * &lt;br /&gt;
 * To generate your own image:&lt;br /&gt;
 * 1. Prepare a 200x200 pixel image&lt;br /&gt;
 * 2. Convert to 1-bit monochrome bitmap&lt;br /&gt;
 * 3. Use image2cpp or similar tool to generate C array&lt;br /&gt;
 * 4. Replace the array below with your generated data&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
#ifndef _IMAGE_H_&lt;br /&gt;
#define _IMAGE_H_&lt;br /&gt;
&lt;br /&gt;
// Placeholder for 200x200 bitmap image&lt;br /&gt;
// Replace this with your actual image data&lt;br /&gt;
const unsigned char gImage_1inch54[] PROGMEM = {&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0xC0, 0x00, 0x00,&lt;br /&gt;
  0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x07, 0xC0,&lt;br /&gt;
  0x7C, 0x07, 0xC0, 0xFD, 0x81, 0xFC, 0xC6, 0x18, 0x7E, 0xC0, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x0F, 0xF0, 0xFE, 0x1F, 0xE1, 0xFF, 0x83, 0xFC, 0xEE,&lt;br /&gt;
  0x18, 0xFF, 0xCC, 0x7F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,&lt;br /&gt;
  0x1C, 0x71, 0xC7, 0x1C, 0x73, 0xC7, 0x83, 0x00, 0xEE, 0x19, 0xE3, 0xCC, 0xE3, 0xC0, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x18, 0x3B, 0x83, 0x38, 0x33, 0x83, 0x83,&lt;br /&gt;
  0x80, 0xCE, 0x19, 0xC1, 0xCD, 0xC1, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x7C, 0x3F, 0xFB, 0xFF, 0xBF, 0xF3, 0x03, 0x83, 0xF0, 0xCE, 0x19, 0x81, 0xCD, 0xC0, 0xC0,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0xFB, 0xFF, 0xBF, 0xF3,&lt;br /&gt;
  0x03, 0x81, 0xFC, 0xCE, 0x19, 0x81, 0xCD, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x07, 0xB8, 0x03, 0x80, 0x38, 0x03, 0x03, 0x80, 0x1C, 0xCE, 0x19, 0x81, 0xCD,&lt;br /&gt;
  0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x9C, 0x01, 0x80,&lt;br /&gt;
  0x38, 0x03, 0x87, 0x80, 0x0C, 0xC6, 0x19, 0xC3, 0xCC, 0xE1, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x9F, 0xF1, 0xFF, 0x1F, 0xE1, 0xFF, 0x83, 0x1C, 0xE7, 0xF8,&lt;br /&gt;
  0xFF, 0xCC, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x0F,&lt;br /&gt;
  0xE0, 0xFE, 0x0F, 0xE0, 0xFF, 0x83, 0xF8, 0xE3, 0xF0, 0x7F, 0xCC, 0x7F, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x03, 0x80, 0x38, 0x03, 0x80, 0x39, 0x80, 0xE0,&lt;br /&gt;
  0x20, 0xC0, 0x1C, 0xCC, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0xC0, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79,&lt;br /&gt;
  0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x38, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0xC0, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0xDC, 0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x18, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFE, 0xFC, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x01, 0x80, 0x13, 0xC6, 0xE6, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xC0, 0xB7, 0xE6, 0x66, 0xE4,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0xF8, 0xE6, 0x66, 0x66, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xFC, 0xC6, 0x76,&lt;br /&gt;
  0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xF0,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x04, 0x3C, 0xCC, 0xC6, 0x66, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x30, 0xCC,&lt;br /&gt;
  0xC3, 0xE6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,&lt;br /&gt;
  0xFF, 0xF8, 0x00, 0x03, 0x00, 0x3F, 0x3B, 0x70, 0xCE, 0xC1, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFF, 0xF8, 0x00, 0x43, 0x06, 0x3F, 0x33,&lt;br /&gt;
  0xB0, 0xE6, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFE,&lt;br /&gt;
  0x00, 0x00, 0xFF, 0xF8, 0x00, 0xE3, 0x9F, 0xBB, 0xB3, 0xBE, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0xF8, 0x00, 0xF7, 0x99,&lt;br /&gt;
  0x99, 0xBB, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F,&lt;br /&gt;
  0xFF, 0xFF, 0x00, 0x01, 0xFF, 0xF8, 0x00, 0xF7, 0x99, 0x99, 0x9F, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0xFC, 0x00,&lt;br /&gt;
  0x7F, 0x99, 0x99, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x1F, 0xFF, 0xFF, 0x00, 0x03, 0xFB, 0xFC, 0x00, 0x7D, 0x9F, 0x98, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x30, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0x00, 0x03, 0xFB,&lt;br /&gt;
  0xFC, 0x00, 0x6C, 0xCF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0xE7, 0x60, 0x00, 0x00,&lt;br /&gt;
  0x0C, 0x00, 0x00, 0x1F, 0xFF, 0xE0, 0x00, 0x07, 0xF3, 0xFC, 0x00, 0x64, 0xC0, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0xC0, 0x02, 0x31, 0x33, 0x60, 0x00, 0x01, 0xFC, 0x00, 0x00, 0x1F, 0xF8, 0x00, 0x00,&lt;br /&gt;
  0x07, 0xF3, 0xFC, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x1F, 0xB8, 0x71, 0xE0,&lt;br /&gt;
  0x00, 0x03, 0xFC, 0x00, 0x00, 0x1F, 0xE0, 0x00, 0x00, 0x07, 0xF3, 0xFE, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0xFC, 0x07, 0x99, 0x99, 0xB1, 0xC0, 0x00, 0x07, 0xFC, 0x00, 0x00, 0x1F, 0xE0,&lt;br /&gt;
  0x00, 0x00, 0x0F, 0xF3, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x66, 0x19, 0x99,&lt;br /&gt;
  0xB8, 0xC0, 0x00, 0x1F, 0xFE, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0x0F, 0xE3, 0xFE, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0x67, 0x19, 0x99, 0xF8, 0xC1, 0x00, 0x7F, 0xFE, 0x00, 0x00,&lt;br /&gt;
  0x0F, 0xF0, 0x00, 0x00, 0x0F, 0xE1, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xC6, 0x67,&lt;br /&gt;
  0xD9, 0x9C, 0xC1, 0xFF, 0x01, 0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0x1F, 0xE1, 0xFE,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xE7, 0x60, 0xDF, 0x80, 0x0F, 0xFF, 0x01, 0xFF, 0xFE,&lt;br /&gt;
  0x00, 0x00, 0x0F, 0xF7, 0xFC, 0x00, 0x1F, 0xC1, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0xE0,&lt;br /&gt;
  0x66, 0x77, 0xDE, 0x01, 0xFF, 0xFF, 0x01, 0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x3F,&lt;br /&gt;
  0xC1, 0xFF, 0x00, 0x00, 0x04, 0x00, 0x3E, 0x66, 0xC0, 0x66, 0x37, 0x8C, 0x7F, 0xFF, 0xFF, 0x01,&lt;br /&gt;
  0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xC0, 0x3F, 0x81, 0xFF, 0xF0, 0x00, 0x3F, 0x0E, 0x7F,&lt;br /&gt;
  0x7E, 0xE0, 0x7C, 0x20, 0x0F, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x0F, 0xFF, 0xFF,&lt;br /&gt;
  0xC0, 0x3F, 0x81, 0xFF, 0xF0, 0x00, 0x3B, 0xBE, 0x73, 0x78, 0x60, 0x78, 0x03, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0x00, 0x81, 0xFF, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xE0, 0x7F, 0x9F, 0xFF, 0xF0, 0x00, 0x31,&lt;br /&gt;
  0x87, 0x73, 0x70, 0x60, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x07,&lt;br /&gt;
  0xFF, 0xFF, 0xF0, 0x7F, 0xFF, 0xFF, 0xF0, 0x0F, 0x3B, 0x8F, 0x33, 0x3E, 0x40, 0x0F, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x07, 0xF8, 0x7F, 0xF0, 0x7F, 0xFF, 0xFF, 0xF8,&lt;br /&gt;
  0x0D, 0x9F, 0x1B, 0x3F, 0x18, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0x00,&lt;br /&gt;
  0x00, 0x07, 0xE0, 0x3F, 0xF0, 0xFF, 0xFF, 0xFF, 0xF8, 0x19, 0x9C, 0x3B, 0x3E, 0x00, 0x7F, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x00, 0xC0, 0x1F, 0xF8, 0x7F, 0xFF,&lt;br /&gt;
  0xFF, 0xF0, 0x1F, 0x98, 0x1F, 0x30, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,&lt;br /&gt;
  0xFF, 0x80, 0x00, 0x00, 0x00, 0x0F, 0xF8, 0x7F, 0xFF, 0xFF, 0x80, 0x1C, 0x18, 0x00, 0x33, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x0F, 0xF8,&lt;br /&gt;
  0x7F, 0xFF, 0xFF, 0x80, 0x0F, 0x98, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0x00, 0x00, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x0F, 0xF8, 0x7F, 0xC0, 0x7F, 0x80, 0x07, 0x00, 0x1F,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x80, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x0F, 0xF8, 0x78, 0x00, 0x7F, 0xC0, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0x7F, 0xC0, 0x00,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x7F, 0xC0, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0x7F, 0xC0, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x00, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0x3F,&lt;br /&gt;
  0xC7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x7F,&lt;br /&gt;
  0xC0, 0x00, 0x01, 0x80, 0x1F, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x03, 0xE0, 0x7F, 0xF0, 0x00,&lt;br /&gt;
  0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,&lt;br /&gt;
  0x00, 0x7F, 0xC0, 0x00, 0x03, 0xFF, 0xFF, 0xE0, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x07, 0xFF, 0xFF,&lt;br /&gt;
  0xE0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0x00, 0x00, 0x3F, 0xE0, 0x00, 0x07, 0xFF, 0xFF, 0xC0, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0xE0, 0x00, 0x07,&lt;br /&gt;
  0xFF, 0xFF, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0xE7, 0xC1, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0xFF,&lt;br /&gt;
  0xC3, 0xC1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0xFF, 0xC3, 0xE0, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x0F,&lt;br /&gt;
  0xFF, 0xFF, 0xC3, 0xE1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0x00, 0x1F, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x7F, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFE, 0x7F, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xEF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xC1, 0xFF, 0xFF, 0xFE, 0x7F, 0xF7, 0x3F, 0xFF, 0xFF,&lt;br /&gt;
  0xF1, 0xE3, 0xE7, 0xF2, 0x39, 0x3F, 0xFF, 0xC7, 0x8F, 0x9F, 0xCC, 0xE7, 0x7F, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xC0, 0xFF, 0xFF, 0xFE, 0x7F, 0xE7, 0xFF, 0xFF, 0xFF, 0xC0, 0xC1, 0xC3, 0xF3, 0x39, 0xBC, 0xF3,&lt;br /&gt;
  0x03, 0x07, 0x0F, 0xCC, 0xE7, 0x3F, 0xFF, 0xFF, 0xFF, 0xCE, 0x61, 0xC3, 0x8E, 0x66, 0x41, 0x38,&lt;br /&gt;
  0x70, 0x73, 0xFC, 0xCC, 0x99, 0xF7, 0x33, 0xBE, 0x67, 0xF3, 0x32, 0x67, 0xDC, 0xE7, 0x3F, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xCC, 0x40, 0x83, 0x06, 0x66, 0x41, 0x30, 0x30, 0x33, 0xFC, 0xCC, 0x99, 0xF7, 0x33,&lt;br /&gt;
  0x9F, 0x0F, 0xF3, 0x32, 0x67, 0xDC, 0x67, 0xBF, 0xFF, 0xFF, 0xFF, 0xC0, 0xCC, 0x8E, 0x62, 0x66,&lt;br /&gt;
  0x67, 0x33, 0x33, 0x33, 0xF8, 0xCC, 0x99, 0xE7, 0x13, 0x9F, 0x9F, 0xE3, 0x32, 0x67, 0x9C, 0x07,&lt;br /&gt;
  0xBF, 0xFF, 0xFF, 0xFF, 0xC1, 0xC0, 0xC2, 0x72, 0x66, 0x67, 0x33, 0x33, 0x3F, 0xF9, 0xCC, 0x99,&lt;br /&gt;
  0xE7, 0x97, 0x9F, 0x0F, 0xE7, 0x32, 0x67, 0x9C, 0x67, 0xBF, 0xFF, 0xFF, 0xFF, 0xCC, 0xCF, 0xF2,&lt;br /&gt;
  0x62, 0x66, 0x67, 0x33, 0x33, 0x3F, 0xF3, 0xCC, 0x99, 0xF7, 0x87, 0x9E, 0x67, 0xCF, 0x32, 0x67,&lt;br /&gt;
  0xDC, 0xE7, 0xBF, 0xFF, 0xFF, 0xFF, 0xCC, 0xC5, 0x93, 0x06, 0x20, 0x63, 0x30, 0x33, 0x33, 0xE0,&lt;br /&gt;
  0xC1, 0x81, 0xF7, 0x87, 0x9C, 0xF3, 0x83, 0x06, 0x07, 0xDC, 0xE7, 0x3F, 0xFF, 0xFF, 0xFF, 0xCE,&lt;br /&gt;
  0x61, 0x87, 0x0F, 0x30, 0x71, 0x38, 0x73, 0x33, 0xC0, 0xE1, 0xC3, 0xF3, 0xC7, 0xBF, 0xFF, 0x03,&lt;br /&gt;
  0x8F, 0x0F, 0xCC, 0xE7, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xF3, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xFF, 0x3F, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xFF, 0x7F,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0xFE, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0x8F, 0xCE, 0x0E, 0x7F, 0xFC,&lt;br /&gt;
  0x18, 0x3E, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFE, 0x7F, 0xFF, 0xFF, 0x07, 0x86, 0x07, 0xFF, 0xFC, 0x18, 0x1C, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xE1, 0xD1, 0x91, 0xC3, 0xC4, 0x18, 0x74, 0xDF, 0xE7, 0x86, 0x62,&lt;br /&gt;
  0x60, 0xFC, 0xF9, 0x98, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xC0, 0xC0,&lt;br /&gt;
  0x81, 0xC1, 0x84, 0x10, 0x60, 0x8F, 0xE7, 0x26, 0x62, 0x60, 0x7C, 0xF9, 0x99, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xCC, 0xCC, 0x88, 0x99, 0x1E, 0x73, 0x23, 0xDF, 0xE6,&lt;br /&gt;
  0x66, 0x06, 0x66, 0x7C, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF,&lt;br /&gt;
  0xCC, 0xCC, 0x8C, 0x81, 0x3E, 0x63, 0x23, 0xFF, 0xCE, 0x06, 0x0E, 0x66, 0x7C, 0x38, 0x39, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xCC, 0xCC, 0x8C, 0x9F, 0x3E, 0x73, 0x23,&lt;br /&gt;
  0xFF, 0x8E, 0x06, 0x7E, 0x66, 0x7C, 0xF9, 0xF9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xC0, 0xC0, 0xCC, 0x8C, 0x8B, 0x86, 0x30, 0x23, 0x8F, 0x03, 0xE6, 0x7E, 0x66, 0x7C, 0xF9,&lt;br /&gt;
  0xFC, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xE1, 0xCC, 0x8C, 0xC3, 0x87,&lt;br /&gt;
  0x18, 0x63, 0x9F, 0x03, 0xE6, 0x7E, 0x66, 0x7C, 0xF9, 0xFE, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xCF, 0xFF, 0xFE, 0x7C, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xFF, 0xFC, 0x7C,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF,&lt;br /&gt;
  0xE9, 0x0E, 0x66, 0x1C, 0x61, 0xCE, 0x1D, 0xF8, 0x7C, 0xE1, 0x99, 0xC7, 0x30, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xE1, 0x06, 0x64, 0x18, 0x60, 0xCC, 0x18,&lt;br /&gt;
  0xF8, 0x7C, 0xC0, 0x99, 0x83, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xCC, 0x67, 0xE6, 0x64, 0x71, 0xFC, 0xCC, 0xCD, 0xF2, 0x7C, 0xCC, 0x99, 0x33, 0x23, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCC, 0x67, 0x07, 0x0E, 0x13, 0xE0,&lt;br /&gt;
  0xCC, 0x0F, 0xF0, 0x3C, 0xC0, 0xCB, 0x03, 0x30, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xCE, 0x67, 0x27, 0x0F, 0x93, 0xE4, 0xCC, 0xFF, 0xF0, 0x3C, 0xCF, 0xC3, 0x3F,&lt;br /&gt;
  0x3C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x67, 0x07, 0x9C,&lt;br /&gt;
  0x98, 0x60, 0xC4, 0x58, 0xFE, 0x7C, 0x45, 0xC3, 0x17, 0x24, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xE7, 0x07, 0x9C, 0x38, 0x60, 0xE6, 0x19, 0xFE, 0x7E, 0x61,&lt;br /&gt;
  0xE7, 0x83, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFE, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xFE, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0x87, 0x07, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xCF, 0xFC, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0x07, 0x03, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCC, 0x98, 0x30, 0xC8, 0x18, 0x78,&lt;br /&gt;
  0xE3, 0x9F, 0x3F, 0x33, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xCC, 0x08, 0x20, 0xC0, 0x18, 0x30, 0xC1, 0x9F, 0x1F, 0x33, 0x3F, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCC, 0xCC, 0xE6, 0x47,&lt;br /&gt;
  0x3E, 0x23, 0x89, 0x9F, 0x07, 0x03, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCC, 0xCC, 0xE0, 0x4F, 0x38, 0x27, 0x81, 0xFF, 0xE3, 0x07, 0x3F,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCC, 0xCC,&lt;br /&gt;
  0xE7, 0xCF, 0x33, 0x23, 0x8F, 0xFF, 0xF3, 0x3F, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCC, 0xCC, 0x62, 0xCF, 0x30, 0x30, 0xC1, 0x9F, 0x03,&lt;br /&gt;
  0x3F, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xCC, 0xCE, 0x30, 0xCF, 0x38, 0x30, 0xE1, 0x9F, 0x07, 0x3F, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [Code 2 Display a clock] ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 An example digital clock using a TFT LCD screen to show the time.&lt;br /&gt;
 Demonstrates use of the font printing routines. (Time updates but date does not.)&lt;br /&gt;
 &lt;br /&gt;
 For a more accurate clock, it would be better to use the RTClib library.&lt;br /&gt;
 But this is just a demo. &lt;br /&gt;
 &lt;br /&gt;
 This examples uses the hardware SPI only. Non-hardware SPI&lt;br /&gt;
 is just too slow (~8 times slower!)&lt;br /&gt;
 &lt;br /&gt;
 Based on clock sketch by Gilchrist 6/2/2014 1.0&lt;br /&gt;
 Updated by Bodmer&lt;br /&gt;
A few colour codes:&lt;br /&gt;
 &lt;br /&gt;
code	color&lt;br /&gt;
0x0000	Black&lt;br /&gt;
0xFFFF	White&lt;br /&gt;
0xBDF7	Light Gray&lt;br /&gt;
0x7BEF	Dark Gray&lt;br /&gt;
0xF800	Red&lt;br /&gt;
0xFFE0	Yellow&lt;br /&gt;
0xFBE0	Orange&lt;br /&gt;
0x79E0	Brown&lt;br /&gt;
0x7E0	Green&lt;br /&gt;
0x7FF	Cyan&lt;br /&gt;
0x1F	Blue&lt;br /&gt;
0xF81F	Pink&lt;br /&gt;
&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;TFT_eSPI.h&amp;gt; // Graphics and font library for ST7735 driver chip&lt;br /&gt;
#include &amp;lt;SPI.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#ifdef EPAPER_ENABLE // Only compile this code if the EPAPER_ENABLE is defined in User_Setup.h&lt;br /&gt;
&lt;br /&gt;
EPaper epaper = EPaper();  // Invoke library, pins defined in User_Setup.h&lt;br /&gt;
&lt;br /&gt;
uint32_t targetTime = 0;       // for next 1 second timeout&lt;br /&gt;
&lt;br /&gt;
byte omm = 99;&lt;br /&gt;
bool initial = 1;&lt;br /&gt;
byte xcolon = 0;&lt;br /&gt;
unsigned int colour = 0;&lt;br /&gt;
&lt;br /&gt;
static uint8_t conv2d(const char* p) {&lt;br /&gt;
  uint8_t v = 0;&lt;br /&gt;
  if (&amp;#039;0&amp;#039; &amp;lt;= *p &amp;amp;&amp;amp; *p &amp;lt;= &amp;#039;9&amp;#039;)&lt;br /&gt;
    v = *p - &amp;#039;0&amp;#039;;&lt;br /&gt;
  return 10 * v + *++p - &amp;#039;0&amp;#039;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
uint8_t hh=conv2d(__TIME__), mm=conv2d(__TIME__+3), ss=conv2d(__TIME__+6);  // Get H, M, S from compile time&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
void setup(void) {&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
  epaper.begin();&lt;br /&gt;
  epaper.setRotation(1);&lt;br /&gt;
  epaper.fillScreen(TFT_BLACK);&lt;br /&gt;
&lt;br /&gt;
  epaper.setTextColor(TFT_YELLOW, TFT_BLACK); // Note: the new fonts do not draw the background colour&lt;br /&gt;
  epaper.update(); // update the display&lt;br /&gt;
  targetTime = millis() + 1000; &lt;br /&gt;
#endif&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
  if (targetTime &amp;lt; millis()) {&lt;br /&gt;
    targetTime = millis()+1000;&lt;br /&gt;
    ss++;              // Advance second&lt;br /&gt;
    if (ss==60) {&lt;br /&gt;
      ss=0;&lt;br /&gt;
      omm = mm;&lt;br /&gt;
      mm++;            // Advance minute&lt;br /&gt;
      if(mm&amp;gt;59) {&lt;br /&gt;
        mm=0;&lt;br /&gt;
        hh++;          // Advance hour&lt;br /&gt;
        if (hh&amp;gt;23) {&lt;br /&gt;
          hh=0;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (ss==0 || initial) {&lt;br /&gt;
      initial = 0;&lt;br /&gt;
      epaper.setTextColor(TFT_GREEN, TFT_BLACK);&lt;br /&gt;
      epaper.setCursor (8, 52);&lt;br /&gt;
      epaper.print(__DATE__); // This uses the standard ADAFruit small font&lt;br /&gt;
&lt;br /&gt;
      epaper.setTextColor(TFT_BLUE, TFT_BLACK);&lt;br /&gt;
      epaper.drawCentreString(&amp;quot;It is windy&amp;quot;,120,48,2); // Next size up font 2&lt;br /&gt;
&lt;br /&gt;
      //epaper.setTextColor(0xF81F, TFT_BLACK); // Pink&lt;br /&gt;
      //epaper.drawCentreString(&amp;quot;12.34&amp;quot;,80,100,6); // Large font 6 only contains characters [space] 0 1 2 3 4 5 6 7 8 9 . : a p m&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Update digital time&lt;br /&gt;
    byte xpos = 6;&lt;br /&gt;
    byte ypos = 0;&lt;br /&gt;
    if (omm != mm) { // Only redraw every minute to minimise flicker&lt;br /&gt;
      // Uncomment ONE of the next 2 lines, using the ghost image demonstrates text overlay as time is drawn over it&lt;br /&gt;
      epaper.setTextColor(TFT_BLACK, TFT_BLACK);  // Leave a 7 segment ghost image, comment out next line!&lt;br /&gt;
      //epaper.setTextColor(TFT_BLACK, TFT_BLACK); // Set font colour to black to wipe image&lt;br /&gt;
      // Font 7 is to show a pseudo 7 segment display.&lt;br /&gt;
      // Font 7 only contains characters [space] 0 1 2 3 4 5 6 7 8 9 0 : .&lt;br /&gt;
      epaper.drawString(&amp;quot;88:88&amp;quot;,xpos,ypos,7); // Overwrite the text to clear it&lt;br /&gt;
      epaper.setTextColor(0xFBE0); // Orange&lt;br /&gt;
      omm = mm;&lt;br /&gt;
&lt;br /&gt;
      if (hh&amp;lt;10) xpos+= epaper.drawChar(&amp;#039;0&amp;#039;,xpos,ypos,7);&lt;br /&gt;
      xpos+= epaper.drawNumber(hh,xpos,ypos,7);&lt;br /&gt;
      xcolon=xpos;&lt;br /&gt;
      xpos+= epaper.drawChar(&amp;#039;:&amp;#039;,xpos,ypos,7);&lt;br /&gt;
      if (mm&amp;lt;10) xpos+= epaper.drawChar(&amp;#039;0&amp;#039;,xpos,ypos,7);&lt;br /&gt;
      epaper.drawNumber(mm,xpos,ypos,7);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (ss%2) { // Flash the colon&lt;br /&gt;
      epaper.setTextColor(TFT_BLACK, TFT_BLACK);&lt;br /&gt;
      xpos+= epaper.drawChar(&amp;#039;:&amp;#039;,xcolon,ypos,7);&lt;br /&gt;
      epaper.setTextColor(0xFBE0, TFT_BLACK);&lt;br /&gt;
    }&lt;br /&gt;
    else {&lt;br /&gt;
      epaper.drawChar(&amp;#039;:&amp;#039;,xcolon,ypos,7);&lt;br /&gt;
      colour = random(0xFFFF);&lt;br /&gt;
      // Erase the old text with a rectangle, the disadvantage of this method is increased display flicker&lt;br /&gt;
      epaper.fillRect (0, 64, 160, 20, TFT_BLACK);&lt;br /&gt;
      epaper.setTextColor(TFT_WHITE);&lt;br /&gt;
    }&lt;br /&gt;
    epaper.update(); // update the display&lt;br /&gt;
  }&lt;br /&gt;
#endif&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;onglet driver.h&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// driver.h file &lt;br /&gt;
#define BOARD_SCREEN_COMBO 505 // 1.54 inch monochrome ePaper Screen （SSD1681）&lt;br /&gt;
#define USE_XIAO_EPAPER_BREAKOUT_BOARD&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [Code 2 Display a clock - WIFI] ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;TFT_eSPI.h&amp;gt;   // Librairie pour ton écran E-paper&lt;br /&gt;
#include &amp;lt;SPI.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
EPaper epaper = EPaper();  // Pins définis dans User_Setup.h&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// ⚙️ Paramètres WiFi&lt;br /&gt;
const char* ssid     = &amp;quot;TON_SSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TON_MOTDEPASSE&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ⚙️ Paramètres NTP&lt;br /&gt;
const char* ntpServer = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const long  gmtOffset_sec = 3600;       // Décalage GMT (ex: +1h pour Suisse en hiver)&lt;br /&gt;
const int   daylightOffset_sec = 3600;  // Décalage été (DST)&lt;br /&gt;
&lt;br /&gt;
// Variables pour éviter scintillement&lt;br /&gt;
int lastMinute = -1;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
  epaper.begin();&lt;br /&gt;
  epaper.setRotation(1);&lt;br /&gt;
  epaper.fillScreen(TFT_BLACK);&lt;br /&gt;
  epaper.setTextColor(TFT_WHITE, TFT_BLACK);&lt;br /&gt;
  epaper.update();&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Initialisation NTP&lt;br /&gt;
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  // Récupérer l’heure système&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    return; // Si pas d’heure dispo&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Rafraîchir uniquement si la minute change&lt;br /&gt;
  if (timeinfo.tm_min != lastMinute) {&lt;br /&gt;
    lastMinute = timeinfo.tm_min;&lt;br /&gt;
&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
    epaper.fillScreen(TFT_BLACK);&lt;br /&gt;
&lt;br /&gt;
    // Afficher la date&lt;br /&gt;
    epaper.setTextColor(TFT_GREEN, TFT_BLACK);&lt;br /&gt;
    epaper.setCursor(10, 20);&lt;br /&gt;
    epaper.printf(&amp;quot;%02d/%02d/%04d&amp;quot;, timeinfo.tm_mday, timeinfo.tm_mon+1, timeinfo.tm_year+1900);&lt;br /&gt;
&lt;br /&gt;
    // Afficher l’heure&lt;br /&gt;
    epaper.setTextColor(TFT_ORANGE, TFT_BLACK);&lt;br /&gt;
    epaper.setCursor(10, 60);&lt;br /&gt;
    epaper.printf(&amp;quot;%02d:%02d&amp;quot;, timeinfo.tm_hour, timeinfo.tm_min);&lt;br /&gt;
&lt;br /&gt;
    epaper.update(); // Mise à jour écran&lt;br /&gt;
#endif&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  delay(1000); // Boucle chaque seconde mais rafraîchit seulement à chaque minute&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [Code 2 Display a clock - WIFI v2] ===&lt;br /&gt;
&lt;br /&gt;
version modifié&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;TFT_eSPI.h&amp;gt;   // Librairie pour ton écran E-paper&lt;br /&gt;
#include &amp;lt;SPI.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
EPaper epaper = EPaper();  // Pins définis dans User_Setup.h&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// ⚙️ Paramètres WiFi&lt;br /&gt;
const char* ssid     = &amp;quot;TON_SSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TON_MOTDEPASSE&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ⚙️ Paramètres NTP&lt;br /&gt;
const char* ntpServer = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const long  gmtOffset_sec = 3600;       // Décalage GMT (ex: +1h pour Suisse en hiver)&lt;br /&gt;
const int   daylightOffset_sec = 3600;  // Décalage été (DST)&lt;br /&gt;
&lt;br /&gt;
// Variables pour éviter scintillement&lt;br /&gt;
int lastMinute = -1;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
  epaper.begin();&lt;br /&gt;
  epaper.setRotation(1);&lt;br /&gt;
  epaper.fillScreen(TFT_WHITE);              // Fond blanc&lt;br /&gt;
  epaper.setTextColor(TFT_BLACK, TFT_WHITE); // Texte noir sur fond blanc&lt;br /&gt;
  epaper.update();&lt;br /&gt;
  epaper.sleep(); // Mise en veille après init&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  Serial.print(&amp;quot;Connexion au WiFi &amp;quot;);&lt;br /&gt;
  Serial.println(ssid);&lt;br /&gt;
&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot;\nWiFi connecté !&amp;quot;);&lt;br /&gt;
  Serial.print(&amp;quot;Adresse IP : &amp;quot;);&lt;br /&gt;
  Serial.println(WiFi.localIP());&lt;br /&gt;
  Serial.print(&amp;quot;Adresse MAC : &amp;quot;);&lt;br /&gt;
  Serial.println(WiFi.macAddress());&lt;br /&gt;
&lt;br /&gt;
  // Initialisation NTP&lt;br /&gt;
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  // Récupérer l’heure système&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Erreur récupération heure NTP&amp;quot;);&lt;br /&gt;
    return; // Si pas d’heure dispo&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Rafraîchir uniquement si la minute change&lt;br /&gt;
  if (timeinfo.tm_min != lastMinute) {&lt;br /&gt;
    lastMinute = timeinfo.tm_min;&lt;br /&gt;
&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
    //epaper.wakeup(); // Réveille l’écran avant mise à jour&lt;br /&gt;
    epaper.fillScreen(TFT_WHITE);&lt;br /&gt;
&lt;br /&gt;
    // --- Affichage DATE (plus petite, centrée en haut) ---&lt;br /&gt;
    epaper.setTextColor(TFT_BLACK, TFT_WHITE);&lt;br /&gt;
    epaper.setTextDatum(TC_DATUM); // Centrage horizontal (Top Center)&lt;br /&gt;
    epaper.drawString(&lt;br /&gt;
      String(timeinfo.tm_mday) + &amp;quot;/&amp;quot; + &lt;br /&gt;
      String(timeinfo.tm_mon+1) + &amp;quot;/&amp;quot; + &lt;br /&gt;
      String(timeinfo.tm_year+1900),&lt;br /&gt;
      epaper.width()/2, 30, 4   // police taille 2&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    // --- Affichage HEURE (plus grande, centrée au milieu) ---&lt;br /&gt;
    char buffer[6];&lt;br /&gt;
    sprintf(buffer, &amp;quot;%02d:%02d&amp;quot;, timeinfo.tm_hour, timeinfo.tm_min);&lt;br /&gt;
    epaper.setTextDatum(MC_DATUM); // Centrage horizontal + vertical (Middle Center)&lt;br /&gt;
    epaper.drawString(buffer, epaper.width()/2, epaper.height()/2, 7); // police taille 6&lt;br /&gt;
&lt;br /&gt;
    epaper.update(); // Mise à jour écran&lt;br /&gt;
    //epaper.sleep();  // Mise en veille après mise à jour&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
    // --- Sortie série ---&lt;br /&gt;
    Serial.printf(&amp;quot;Heure actuelle : %02d:%02d:%02d\n&amp;quot;, &lt;br /&gt;
                  timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  delay(1000); // Boucle chaque seconde mais rafraîchit seulement à chaque minute&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>144.2.107.134</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.myows.top/index.php?title=1.54-inch_E-paper_Display&amp;diff=2037</id>
		<title>1.54-inch E-paper Display</title>
		<link rel="alternate" type="text/html" href="https://wiki.myows.top/index.php?title=1.54-inch_E-paper_Display&amp;diff=2037"/>
		<updated>2025-12-12T21:43:17Z</updated>

		<summary type="html">&lt;p&gt;144.2.107.134: /* Support */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
=== Support ===&lt;br /&gt;
&lt;br /&gt;
1.54-inch E-paper Display&lt;br /&gt;
&lt;br /&gt;
[[File:EPaper-Display-1.54.PNG|250px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Setup&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 Install Seeed &amp;lt;b&amp;gt;GFX Library&amp;lt;/b&amp;gt;&lt;br /&gt;
 https://github.com/Seeed-Studio/Seeed_GFX&lt;br /&gt;
&lt;br /&gt;
This library has same function as TFT library and no compatible with it. If you have installed TFT library or other similary display libraries, please uninstall it first.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Create a driver.h file&amp;lt;/b&amp;gt; and paste the following code into it.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Seeed GFX Library - &amp;lt;b&amp;gt;Online Configuration Generator&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
https://seeed-studio.github.io/Seeed_GFX/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// driver.h file &lt;br /&gt;
#define BOARD_SCREEN_COMBO 505 // 1.54 inch monochrome ePaper Screen （SSD1681）&lt;br /&gt;
#define USE_XIAO_EPAPER_BREAKOUT_BOARD&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sketch -&amp;gt; &amp;lt;b&amp;gt;Include Library&amp;lt;/b&amp;gt; -&amp;gt; Add .ZIP&amp;lt;br&amp;gt;&lt;br /&gt;
Seeed_GFX-master.zip&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Upload the Code&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
driver.h&amp;lt;br&amp;gt;&lt;br /&gt;
HelloWorld.ino&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Liens externes ====&lt;br /&gt;
&lt;br /&gt;
https://www.seeedstudio.com/1-54-Monochrome-ePaper-Display-with-200x200-Pixels-p-5776.html &amp;lt;font color=red&amp;gt;Shop&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://wiki.seeedstudio.com/XIAO-eInk-Expansion-Board/ &amp;lt;font color=red&amp;gt;Wiki&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exemples ===&lt;br /&gt;
&lt;br /&gt;
/examples/ePaper/Basic&lt;br /&gt;
&lt;br /&gt;
1 Bitmap: Display a bitmap image.&amp;lt;br&amp;gt;&lt;br /&gt;
2 Clock: Display a clock.&amp;lt;br&amp;gt;&lt;br /&gt;
3 Clock_digital: Display a digital clock.&amp;lt;br&amp;gt;&lt;br /&gt;
4 HelloWorld: &amp;lt;br&amp;gt;&lt;br /&gt;
5 Shape: Display different sizes of words and shape randomly.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [Code 1] Display a bitmap image ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;quot;TFT_eSPI.h&amp;quot;&lt;br /&gt;
#include &amp;quot;image.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
EPaper epaper;&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
  delay(2000);&lt;br /&gt;
  Serial.println(&amp;quot;1.54\&amp;quot; E-Paper Bitmap Display Example&amp;quot;);&lt;br /&gt;
  &lt;br /&gt;
  epaper.begin();&lt;br /&gt;
  &lt;br /&gt;
  // Clear screen to white&lt;br /&gt;
  epaper.fillScreen(TFT_WHITE);&lt;br /&gt;
  epaper.update();&lt;br /&gt;
  delay(1000);&lt;br /&gt;
  &lt;br /&gt;
  // Display bitmap image using drawBitmap API&lt;br /&gt;
  // drawBitmap(x, y, bitmap_data, width, height, color)&lt;br /&gt;
  epaper.drawBitmap(0, 0, gImage_1inch54, 200, 200, TFT_BLACK);&lt;br /&gt;
  epaper.update();&lt;br /&gt;
  &lt;br /&gt;
  Serial.println(&amp;quot;Bitmap displayed successfully&amp;quot;);&lt;br /&gt;
  &lt;br /&gt;
  // Put display to sleep to save power&lt;br /&gt;
  epaper.sleep();&lt;br /&gt;
#else&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
  Serial.println(&amp;quot;EPAPER_ENABLE not defined. Please select the correct setup file.&amp;quot;);&lt;br /&gt;
#endif&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop()&lt;br /&gt;
{&lt;br /&gt;
  // Nothing to do here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;onglet driver.h&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// driver.h file &lt;br /&gt;
#define BOARD_SCREEN_COMBO 505 // 1.54 inch monochrome ePaper Screen （SSD1681）&lt;br /&gt;
#define USE_XIAO_EPAPER_BREAKOUT_BOARD&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;onglet image.h&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * Image header file for 1.54&amp;quot; E-Paper Display&lt;br /&gt;
 * &lt;br /&gt;
 * Image specifications:&lt;br /&gt;
 * - Size: 200x200 pixels&lt;br /&gt;
 * - Format: 1-bit monochrome bitmap&lt;br /&gt;
 * - Color depth: Black and White&lt;br /&gt;
 * &lt;br /&gt;
 * To generate your own image:&lt;br /&gt;
 * 1. Prepare a 200x200 pixel image&lt;br /&gt;
 * 2. Convert to 1-bit monochrome bitmap&lt;br /&gt;
 * 3. Use image2cpp or similar tool to generate C array&lt;br /&gt;
 * 4. Replace the array below with your generated data&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
#ifndef _IMAGE_H_&lt;br /&gt;
#define _IMAGE_H_&lt;br /&gt;
&lt;br /&gt;
// Placeholder for 200x200 bitmap image&lt;br /&gt;
// Replace this with your actual image data&lt;br /&gt;
const unsigned char gImage_1inch54[] PROGMEM = {&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0xC0, 0x00, 0x00,&lt;br /&gt;
  0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x07, 0xC0,&lt;br /&gt;
  0x7C, 0x07, 0xC0, 0xFD, 0x81, 0xFC, 0xC6, 0x18, 0x7E, 0xC0, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x0F, 0xF0, 0xFE, 0x1F, 0xE1, 0xFF, 0x83, 0xFC, 0xEE,&lt;br /&gt;
  0x18, 0xFF, 0xCC, 0x7F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,&lt;br /&gt;
  0x1C, 0x71, 0xC7, 0x1C, 0x73, 0xC7, 0x83, 0x00, 0xEE, 0x19, 0xE3, 0xCC, 0xE3, 0xC0, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x18, 0x3B, 0x83, 0x38, 0x33, 0x83, 0x83,&lt;br /&gt;
  0x80, 0xCE, 0x19, 0xC1, 0xCD, 0xC1, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x7C, 0x3F, 0xFB, 0xFF, 0xBF, 0xF3, 0x03, 0x83, 0xF0, 0xCE, 0x19, 0x81, 0xCD, 0xC0, 0xC0,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0xFB, 0xFF, 0xBF, 0xF3,&lt;br /&gt;
  0x03, 0x81, 0xFC, 0xCE, 0x19, 0x81, 0xCD, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x07, 0xB8, 0x03, 0x80, 0x38, 0x03, 0x03, 0x80, 0x1C, 0xCE, 0x19, 0x81, 0xCD,&lt;br /&gt;
  0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x9C, 0x01, 0x80,&lt;br /&gt;
  0x38, 0x03, 0x87, 0x80, 0x0C, 0xC6, 0x19, 0xC3, 0xCC, 0xE1, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x9F, 0xF1, 0xFF, 0x1F, 0xE1, 0xFF, 0x83, 0x1C, 0xE7, 0xF8,&lt;br /&gt;
  0xFF, 0xCC, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x0F,&lt;br /&gt;
  0xE0, 0xFE, 0x0F, 0xE0, 0xFF, 0x83, 0xF8, 0xE3, 0xF0, 0x7F, 0xCC, 0x7F, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x03, 0x80, 0x38, 0x03, 0x80, 0x39, 0x80, 0xE0,&lt;br /&gt;
  0x20, 0xC0, 0x1C, 0xCC, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0xC0, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79,&lt;br /&gt;
  0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x38, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0xC0, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0xDC, 0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x18, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFE, 0xFC, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x01, 0x80, 0x13, 0xC6, 0xE6, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xC0, 0xB7, 0xE6, 0x66, 0xE4,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0xF8, 0xE6, 0x66, 0x66, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xFC, 0xC6, 0x76,&lt;br /&gt;
  0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xF0,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x04, 0x3C, 0xCC, 0xC6, 0x66, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x30, 0xCC,&lt;br /&gt;
  0xC3, 0xE6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,&lt;br /&gt;
  0xFF, 0xF8, 0x00, 0x03, 0x00, 0x3F, 0x3B, 0x70, 0xCE, 0xC1, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFF, 0xF8, 0x00, 0x43, 0x06, 0x3F, 0x33,&lt;br /&gt;
  0xB0, 0xE6, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFE,&lt;br /&gt;
  0x00, 0x00, 0xFF, 0xF8, 0x00, 0xE3, 0x9F, 0xBB, 0xB3, 0xBE, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0xF8, 0x00, 0xF7, 0x99,&lt;br /&gt;
  0x99, 0xBB, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F,&lt;br /&gt;
  0xFF, 0xFF, 0x00, 0x01, 0xFF, 0xF8, 0x00, 0xF7, 0x99, 0x99, 0x9F, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0xFC, 0x00,&lt;br /&gt;
  0x7F, 0x99, 0x99, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x1F, 0xFF, 0xFF, 0x00, 0x03, 0xFB, 0xFC, 0x00, 0x7D, 0x9F, 0x98, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x30, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0x00, 0x03, 0xFB,&lt;br /&gt;
  0xFC, 0x00, 0x6C, 0xCF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0xE7, 0x60, 0x00, 0x00,&lt;br /&gt;
  0x0C, 0x00, 0x00, 0x1F, 0xFF, 0xE0, 0x00, 0x07, 0xF3, 0xFC, 0x00, 0x64, 0xC0, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0xC0, 0x02, 0x31, 0x33, 0x60, 0x00, 0x01, 0xFC, 0x00, 0x00, 0x1F, 0xF8, 0x00, 0x00,&lt;br /&gt;
  0x07, 0xF3, 0xFC, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x1F, 0xB8, 0x71, 0xE0,&lt;br /&gt;
  0x00, 0x03, 0xFC, 0x00, 0x00, 0x1F, 0xE0, 0x00, 0x00, 0x07, 0xF3, 0xFE, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0xFC, 0x07, 0x99, 0x99, 0xB1, 0xC0, 0x00, 0x07, 0xFC, 0x00, 0x00, 0x1F, 0xE0,&lt;br /&gt;
  0x00, 0x00, 0x0F, 0xF3, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x66, 0x19, 0x99,&lt;br /&gt;
  0xB8, 0xC0, 0x00, 0x1F, 0xFE, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0x0F, 0xE3, 0xFE, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0x67, 0x19, 0x99, 0xF8, 0xC1, 0x00, 0x7F, 0xFE, 0x00, 0x00,&lt;br /&gt;
  0x0F, 0xF0, 0x00, 0x00, 0x0F, 0xE1, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xC6, 0x67,&lt;br /&gt;
  0xD9, 0x9C, 0xC1, 0xFF, 0x01, 0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0x1F, 0xE1, 0xFE,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xE7, 0x60, 0xDF, 0x80, 0x0F, 0xFF, 0x01, 0xFF, 0xFE,&lt;br /&gt;
  0x00, 0x00, 0x0F, 0xF7, 0xFC, 0x00, 0x1F, 0xC1, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0xE0,&lt;br /&gt;
  0x66, 0x77, 0xDE, 0x01, 0xFF, 0xFF, 0x01, 0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x3F,&lt;br /&gt;
  0xC1, 0xFF, 0x00, 0x00, 0x04, 0x00, 0x3E, 0x66, 0xC0, 0x66, 0x37, 0x8C, 0x7F, 0xFF, 0xFF, 0x01,&lt;br /&gt;
  0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xC0, 0x3F, 0x81, 0xFF, 0xF0, 0x00, 0x3F, 0x0E, 0x7F,&lt;br /&gt;
  0x7E, 0xE0, 0x7C, 0x20, 0x0F, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x0F, 0xFF, 0xFF,&lt;br /&gt;
  0xC0, 0x3F, 0x81, 0xFF, 0xF0, 0x00, 0x3B, 0xBE, 0x73, 0x78, 0x60, 0x78, 0x03, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0x00, 0x81, 0xFF, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xE0, 0x7F, 0x9F, 0xFF, 0xF0, 0x00, 0x31,&lt;br /&gt;
  0x87, 0x73, 0x70, 0x60, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x07,&lt;br /&gt;
  0xFF, 0xFF, 0xF0, 0x7F, 0xFF, 0xFF, 0xF0, 0x0F, 0x3B, 0x8F, 0x33, 0x3E, 0x40, 0x0F, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x07, 0xF8, 0x7F, 0xF0, 0x7F, 0xFF, 0xFF, 0xF8,&lt;br /&gt;
  0x0D, 0x9F, 0x1B, 0x3F, 0x18, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0x00,&lt;br /&gt;
  0x00, 0x07, 0xE0, 0x3F, 0xF0, 0xFF, 0xFF, 0xFF, 0xF8, 0x19, 0x9C, 0x3B, 0x3E, 0x00, 0x7F, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x00, 0xC0, 0x1F, 0xF8, 0x7F, 0xFF,&lt;br /&gt;
  0xFF, 0xF0, 0x1F, 0x98, 0x1F, 0x30, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,&lt;br /&gt;
  0xFF, 0x80, 0x00, 0x00, 0x00, 0x0F, 0xF8, 0x7F, 0xFF, 0xFF, 0x80, 0x1C, 0x18, 0x00, 0x33, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x0F, 0xF8,&lt;br /&gt;
  0x7F, 0xFF, 0xFF, 0x80, 0x0F, 0x98, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0x00, 0x00, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x0F, 0xF8, 0x7F, 0xC0, 0x7F, 0x80, 0x07, 0x00, 0x1F,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x80, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x0F, 0xF8, 0x78, 0x00, 0x7F, 0xC0, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0x7F, 0xC0, 0x00,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x7F, 0xC0, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0x7F, 0xC0, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x00, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0x3F,&lt;br /&gt;
  0xC7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x7F,&lt;br /&gt;
  0xC0, 0x00, 0x01, 0x80, 0x1F, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x03, 0xE0, 0x7F, 0xF0, 0x00,&lt;br /&gt;
  0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,&lt;br /&gt;
  0x00, 0x7F, 0xC0, 0x00, 0x03, 0xFF, 0xFF, 0xE0, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x07, 0xFF, 0xFF,&lt;br /&gt;
  0xE0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0x00, 0x00, 0x3F, 0xE0, 0x00, 0x07, 0xFF, 0xFF, 0xC0, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0xE0, 0x00, 0x07,&lt;br /&gt;
  0xFF, 0xFF, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0xE7, 0xC1, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0xFF,&lt;br /&gt;
  0xC3, 0xC1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0xFF, 0xC3, 0xE0, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x0F,&lt;br /&gt;
  0xFF, 0xFF, 0xC3, 0xE1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0x00, 0x1F, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x7F, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFE, 0x7F, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xEF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xC1, 0xFF, 0xFF, 0xFE, 0x7F, 0xF7, 0x3F, 0xFF, 0xFF,&lt;br /&gt;
  0xF1, 0xE3, 0xE7, 0xF2, 0x39, 0x3F, 0xFF, 0xC7, 0x8F, 0x9F, 0xCC, 0xE7, 0x7F, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xC0, 0xFF, 0xFF, 0xFE, 0x7F, 0xE7, 0xFF, 0xFF, 0xFF, 0xC0, 0xC1, 0xC3, 0xF3, 0x39, 0xBC, 0xF3,&lt;br /&gt;
  0x03, 0x07, 0x0F, 0xCC, 0xE7, 0x3F, 0xFF, 0xFF, 0xFF, 0xCE, 0x61, 0xC3, 0x8E, 0x66, 0x41, 0x38,&lt;br /&gt;
  0x70, 0x73, 0xFC, 0xCC, 0x99, 0xF7, 0x33, 0xBE, 0x67, 0xF3, 0x32, 0x67, 0xDC, 0xE7, 0x3F, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xCC, 0x40, 0x83, 0x06, 0x66, 0x41, 0x30, 0x30, 0x33, 0xFC, 0xCC, 0x99, 0xF7, 0x33,&lt;br /&gt;
  0x9F, 0x0F, 0xF3, 0x32, 0x67, 0xDC, 0x67, 0xBF, 0xFF, 0xFF, 0xFF, 0xC0, 0xCC, 0x8E, 0x62, 0x66,&lt;br /&gt;
  0x67, 0x33, 0x33, 0x33, 0xF8, 0xCC, 0x99, 0xE7, 0x13, 0x9F, 0x9F, 0xE3, 0x32, 0x67, 0x9C, 0x07,&lt;br /&gt;
  0xBF, 0xFF, 0xFF, 0xFF, 0xC1, 0xC0, 0xC2, 0x72, 0x66, 0x67, 0x33, 0x33, 0x3F, 0xF9, 0xCC, 0x99,&lt;br /&gt;
  0xE7, 0x97, 0x9F, 0x0F, 0xE7, 0x32, 0x67, 0x9C, 0x67, 0xBF, 0xFF, 0xFF, 0xFF, 0xCC, 0xCF, 0xF2,&lt;br /&gt;
  0x62, 0x66, 0x67, 0x33, 0x33, 0x3F, 0xF3, 0xCC, 0x99, 0xF7, 0x87, 0x9E, 0x67, 0xCF, 0x32, 0x67,&lt;br /&gt;
  0xDC, 0xE7, 0xBF, 0xFF, 0xFF, 0xFF, 0xCC, 0xC5, 0x93, 0x06, 0x20, 0x63, 0x30, 0x33, 0x33, 0xE0,&lt;br /&gt;
  0xC1, 0x81, 0xF7, 0x87, 0x9C, 0xF3, 0x83, 0x06, 0x07, 0xDC, 0xE7, 0x3F, 0xFF, 0xFF, 0xFF, 0xCE,&lt;br /&gt;
  0x61, 0x87, 0x0F, 0x30, 0x71, 0x38, 0x73, 0x33, 0xC0, 0xE1, 0xC3, 0xF3, 0xC7, 0xBF, 0xFF, 0x03,&lt;br /&gt;
  0x8F, 0x0F, 0xCC, 0xE7, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xF3, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xFF, 0x3F, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xFF, 0x7F,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0xFE, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0x8F, 0xCE, 0x0E, 0x7F, 0xFC,&lt;br /&gt;
  0x18, 0x3E, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFE, 0x7F, 0xFF, 0xFF, 0x07, 0x86, 0x07, 0xFF, 0xFC, 0x18, 0x1C, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xE1, 0xD1, 0x91, 0xC3, 0xC4, 0x18, 0x74, 0xDF, 0xE7, 0x86, 0x62,&lt;br /&gt;
  0x60, 0xFC, 0xF9, 0x98, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xC0, 0xC0,&lt;br /&gt;
  0x81, 0xC1, 0x84, 0x10, 0x60, 0x8F, 0xE7, 0x26, 0x62, 0x60, 0x7C, 0xF9, 0x99, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xCC, 0xCC, 0x88, 0x99, 0x1E, 0x73, 0x23, 0xDF, 0xE6,&lt;br /&gt;
  0x66, 0x06, 0x66, 0x7C, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF,&lt;br /&gt;
  0xCC, 0xCC, 0x8C, 0x81, 0x3E, 0x63, 0x23, 0xFF, 0xCE, 0x06, 0x0E, 0x66, 0x7C, 0x38, 0x39, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xCC, 0xCC, 0x8C, 0x9F, 0x3E, 0x73, 0x23,&lt;br /&gt;
  0xFF, 0x8E, 0x06, 0x7E, 0x66, 0x7C, 0xF9, 0xF9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xC0, 0xC0, 0xCC, 0x8C, 0x8B, 0x86, 0x30, 0x23, 0x8F, 0x03, 0xE6, 0x7E, 0x66, 0x7C, 0xF9,&lt;br /&gt;
  0xFC, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xE1, 0xCC, 0x8C, 0xC3, 0x87,&lt;br /&gt;
  0x18, 0x63, 0x9F, 0x03, 0xE6, 0x7E, 0x66, 0x7C, 0xF9, 0xFE, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xCF, 0xFF, 0xFE, 0x7C, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xFF, 0xFC, 0x7C,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF,&lt;br /&gt;
  0xE9, 0x0E, 0x66, 0x1C, 0x61, 0xCE, 0x1D, 0xF8, 0x7C, 0xE1, 0x99, 0xC7, 0x30, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xE1, 0x06, 0x64, 0x18, 0x60, 0xCC, 0x18,&lt;br /&gt;
  0xF8, 0x7C, 0xC0, 0x99, 0x83, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xCC, 0x67, 0xE6, 0x64, 0x71, 0xFC, 0xCC, 0xCD, 0xF2, 0x7C, 0xCC, 0x99, 0x33, 0x23, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCC, 0x67, 0x07, 0x0E, 0x13, 0xE0,&lt;br /&gt;
  0xCC, 0x0F, 0xF0, 0x3C, 0xC0, 0xCB, 0x03, 0x30, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xCE, 0x67, 0x27, 0x0F, 0x93, 0xE4, 0xCC, 0xFF, 0xF0, 0x3C, 0xCF, 0xC3, 0x3F,&lt;br /&gt;
  0x3C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x67, 0x07, 0x9C,&lt;br /&gt;
  0x98, 0x60, 0xC4, 0x58, 0xFE, 0x7C, 0x45, 0xC3, 0x17, 0x24, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xE7, 0x07, 0x9C, 0x38, 0x60, 0xE6, 0x19, 0xFE, 0x7E, 0x61,&lt;br /&gt;
  0xE7, 0x83, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFE, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xFE, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0x87, 0x07, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xCF, 0xFC, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0x07, 0x03, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCC, 0x98, 0x30, 0xC8, 0x18, 0x78,&lt;br /&gt;
  0xE3, 0x9F, 0x3F, 0x33, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xCC, 0x08, 0x20, 0xC0, 0x18, 0x30, 0xC1, 0x9F, 0x1F, 0x33, 0x3F, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCC, 0xCC, 0xE6, 0x47,&lt;br /&gt;
  0x3E, 0x23, 0x89, 0x9F, 0x07, 0x03, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCC, 0xCC, 0xE0, 0x4F, 0x38, 0x27, 0x81, 0xFF, 0xE3, 0x07, 0x3F,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCC, 0xCC,&lt;br /&gt;
  0xE7, 0xCF, 0x33, 0x23, 0x8F, 0xFF, 0xF3, 0x3F, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCC, 0xCC, 0x62, 0xCF, 0x30, 0x30, 0xC1, 0x9F, 0x03,&lt;br /&gt;
  0x3F, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xCC, 0xCE, 0x30, 0xCF, 0x38, 0x30, 0xE1, 0x9F, 0x07, 0x3F, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [Code 2 Display a clock] ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 An example digital clock using a TFT LCD screen to show the time.&lt;br /&gt;
 Demonstrates use of the font printing routines. (Time updates but date does not.)&lt;br /&gt;
 &lt;br /&gt;
 For a more accurate clock, it would be better to use the RTClib library.&lt;br /&gt;
 But this is just a demo. &lt;br /&gt;
 &lt;br /&gt;
 This examples uses the hardware SPI only. Non-hardware SPI&lt;br /&gt;
 is just too slow (~8 times slower!)&lt;br /&gt;
 &lt;br /&gt;
 Based on clock sketch by Gilchrist 6/2/2014 1.0&lt;br /&gt;
 Updated by Bodmer&lt;br /&gt;
A few colour codes:&lt;br /&gt;
 &lt;br /&gt;
code	color&lt;br /&gt;
0x0000	Black&lt;br /&gt;
0xFFFF	White&lt;br /&gt;
0xBDF7	Light Gray&lt;br /&gt;
0x7BEF	Dark Gray&lt;br /&gt;
0xF800	Red&lt;br /&gt;
0xFFE0	Yellow&lt;br /&gt;
0xFBE0	Orange&lt;br /&gt;
0x79E0	Brown&lt;br /&gt;
0x7E0	Green&lt;br /&gt;
0x7FF	Cyan&lt;br /&gt;
0x1F	Blue&lt;br /&gt;
0xF81F	Pink&lt;br /&gt;
&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;TFT_eSPI.h&amp;gt; // Graphics and font library for ST7735 driver chip&lt;br /&gt;
#include &amp;lt;SPI.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#ifdef EPAPER_ENABLE // Only compile this code if the EPAPER_ENABLE is defined in User_Setup.h&lt;br /&gt;
&lt;br /&gt;
EPaper epaper = EPaper();  // Invoke library, pins defined in User_Setup.h&lt;br /&gt;
&lt;br /&gt;
uint32_t targetTime = 0;       // for next 1 second timeout&lt;br /&gt;
&lt;br /&gt;
byte omm = 99;&lt;br /&gt;
bool initial = 1;&lt;br /&gt;
byte xcolon = 0;&lt;br /&gt;
unsigned int colour = 0;&lt;br /&gt;
&lt;br /&gt;
static uint8_t conv2d(const char* p) {&lt;br /&gt;
  uint8_t v = 0;&lt;br /&gt;
  if (&amp;#039;0&amp;#039; &amp;lt;= *p &amp;amp;&amp;amp; *p &amp;lt;= &amp;#039;9&amp;#039;)&lt;br /&gt;
    v = *p - &amp;#039;0&amp;#039;;&lt;br /&gt;
  return 10 * v + *++p - &amp;#039;0&amp;#039;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
uint8_t hh=conv2d(__TIME__), mm=conv2d(__TIME__+3), ss=conv2d(__TIME__+6);  // Get H, M, S from compile time&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
void setup(void) {&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
  epaper.begin();&lt;br /&gt;
  epaper.setRotation(1);&lt;br /&gt;
  epaper.fillScreen(TFT_BLACK);&lt;br /&gt;
&lt;br /&gt;
  epaper.setTextColor(TFT_YELLOW, TFT_BLACK); // Note: the new fonts do not draw the background colour&lt;br /&gt;
  epaper.update(); // update the display&lt;br /&gt;
  targetTime = millis() + 1000; &lt;br /&gt;
#endif&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
  if (targetTime &amp;lt; millis()) {&lt;br /&gt;
    targetTime = millis()+1000;&lt;br /&gt;
    ss++;              // Advance second&lt;br /&gt;
    if (ss==60) {&lt;br /&gt;
      ss=0;&lt;br /&gt;
      omm = mm;&lt;br /&gt;
      mm++;            // Advance minute&lt;br /&gt;
      if(mm&amp;gt;59) {&lt;br /&gt;
        mm=0;&lt;br /&gt;
        hh++;          // Advance hour&lt;br /&gt;
        if (hh&amp;gt;23) {&lt;br /&gt;
          hh=0;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (ss==0 || initial) {&lt;br /&gt;
      initial = 0;&lt;br /&gt;
      epaper.setTextColor(TFT_GREEN, TFT_BLACK);&lt;br /&gt;
      epaper.setCursor (8, 52);&lt;br /&gt;
      epaper.print(__DATE__); // This uses the standard ADAFruit small font&lt;br /&gt;
&lt;br /&gt;
      epaper.setTextColor(TFT_BLUE, TFT_BLACK);&lt;br /&gt;
      epaper.drawCentreString(&amp;quot;It is windy&amp;quot;,120,48,2); // Next size up font 2&lt;br /&gt;
&lt;br /&gt;
      //epaper.setTextColor(0xF81F, TFT_BLACK); // Pink&lt;br /&gt;
      //epaper.drawCentreString(&amp;quot;12.34&amp;quot;,80,100,6); // Large font 6 only contains characters [space] 0 1 2 3 4 5 6 7 8 9 . : a p m&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Update digital time&lt;br /&gt;
    byte xpos = 6;&lt;br /&gt;
    byte ypos = 0;&lt;br /&gt;
    if (omm != mm) { // Only redraw every minute to minimise flicker&lt;br /&gt;
      // Uncomment ONE of the next 2 lines, using the ghost image demonstrates text overlay as time is drawn over it&lt;br /&gt;
      epaper.setTextColor(TFT_BLACK, TFT_BLACK);  // Leave a 7 segment ghost image, comment out next line!&lt;br /&gt;
      //epaper.setTextColor(TFT_BLACK, TFT_BLACK); // Set font colour to black to wipe image&lt;br /&gt;
      // Font 7 is to show a pseudo 7 segment display.&lt;br /&gt;
      // Font 7 only contains characters [space] 0 1 2 3 4 5 6 7 8 9 0 : .&lt;br /&gt;
      epaper.drawString(&amp;quot;88:88&amp;quot;,xpos,ypos,7); // Overwrite the text to clear it&lt;br /&gt;
      epaper.setTextColor(0xFBE0); // Orange&lt;br /&gt;
      omm = mm;&lt;br /&gt;
&lt;br /&gt;
      if (hh&amp;lt;10) xpos+= epaper.drawChar(&amp;#039;0&amp;#039;,xpos,ypos,7);&lt;br /&gt;
      xpos+= epaper.drawNumber(hh,xpos,ypos,7);&lt;br /&gt;
      xcolon=xpos;&lt;br /&gt;
      xpos+= epaper.drawChar(&amp;#039;:&amp;#039;,xpos,ypos,7);&lt;br /&gt;
      if (mm&amp;lt;10) xpos+= epaper.drawChar(&amp;#039;0&amp;#039;,xpos,ypos,7);&lt;br /&gt;
      epaper.drawNumber(mm,xpos,ypos,7);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (ss%2) { // Flash the colon&lt;br /&gt;
      epaper.setTextColor(TFT_BLACK, TFT_BLACK);&lt;br /&gt;
      xpos+= epaper.drawChar(&amp;#039;:&amp;#039;,xcolon,ypos,7);&lt;br /&gt;
      epaper.setTextColor(0xFBE0, TFT_BLACK);&lt;br /&gt;
    }&lt;br /&gt;
    else {&lt;br /&gt;
      epaper.drawChar(&amp;#039;:&amp;#039;,xcolon,ypos,7);&lt;br /&gt;
      colour = random(0xFFFF);&lt;br /&gt;
      // Erase the old text with a rectangle, the disadvantage of this method is increased display flicker&lt;br /&gt;
      epaper.fillRect (0, 64, 160, 20, TFT_BLACK);&lt;br /&gt;
      epaper.setTextColor(TFT_WHITE);&lt;br /&gt;
    }&lt;br /&gt;
    epaper.update(); // update the display&lt;br /&gt;
  }&lt;br /&gt;
#endif&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;onglet driver.h&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// driver.h file &lt;br /&gt;
#define BOARD_SCREEN_COMBO 505 // 1.54 inch monochrome ePaper Screen （SSD1681）&lt;br /&gt;
#define USE_XIAO_EPAPER_BREAKOUT_BOARD&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [Code 2 Display a clock - WIFI] ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;TFT_eSPI.h&amp;gt;   // Librairie pour ton écran E-paper&lt;br /&gt;
#include &amp;lt;SPI.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
EPaper epaper = EPaper();  // Pins définis dans User_Setup.h&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// ⚙️ Paramètres WiFi&lt;br /&gt;
const char* ssid     = &amp;quot;TON_SSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TON_MOTDEPASSE&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ⚙️ Paramètres NTP&lt;br /&gt;
const char* ntpServer = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const long  gmtOffset_sec = 3600;       // Décalage GMT (ex: +1h pour Suisse en hiver)&lt;br /&gt;
const int   daylightOffset_sec = 3600;  // Décalage été (DST)&lt;br /&gt;
&lt;br /&gt;
// Variables pour éviter scintillement&lt;br /&gt;
int lastMinute = -1;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
  epaper.begin();&lt;br /&gt;
  epaper.setRotation(1);&lt;br /&gt;
  epaper.fillScreen(TFT_BLACK);&lt;br /&gt;
  epaper.setTextColor(TFT_WHITE, TFT_BLACK);&lt;br /&gt;
  epaper.update();&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Initialisation NTP&lt;br /&gt;
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  // Récupérer l’heure système&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    return; // Si pas d’heure dispo&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Rafraîchir uniquement si la minute change&lt;br /&gt;
  if (timeinfo.tm_min != lastMinute) {&lt;br /&gt;
    lastMinute = timeinfo.tm_min;&lt;br /&gt;
&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
    epaper.fillScreen(TFT_BLACK);&lt;br /&gt;
&lt;br /&gt;
    // Afficher la date&lt;br /&gt;
    epaper.setTextColor(TFT_GREEN, TFT_BLACK);&lt;br /&gt;
    epaper.setCursor(10, 20);&lt;br /&gt;
    epaper.printf(&amp;quot;%02d/%02d/%04d&amp;quot;, timeinfo.tm_mday, timeinfo.tm_mon+1, timeinfo.tm_year+1900);&lt;br /&gt;
&lt;br /&gt;
    // Afficher l’heure&lt;br /&gt;
    epaper.setTextColor(TFT_ORANGE, TFT_BLACK);&lt;br /&gt;
    epaper.setCursor(10, 60);&lt;br /&gt;
    epaper.printf(&amp;quot;%02d:%02d&amp;quot;, timeinfo.tm_hour, timeinfo.tm_min);&lt;br /&gt;
&lt;br /&gt;
    epaper.update(); // Mise à jour écran&lt;br /&gt;
#endif&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  delay(1000); // Boucle chaque seconde mais rafraîchit seulement à chaque minute&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>144.2.107.134</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.myows.top/index.php?title=1.54-inch_E-paper_Display&amp;diff=2036</id>
		<title>1.54-inch E-paper Display</title>
		<link rel="alternate" type="text/html" href="https://wiki.myows.top/index.php?title=1.54-inch_E-paper_Display&amp;diff=2036"/>
		<updated>2025-12-12T21:43:01Z</updated>

		<summary type="html">&lt;p&gt;144.2.107.134: /* Support */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
=== Support ===&lt;br /&gt;
&lt;br /&gt;
1.54-inch E-paper Display&lt;br /&gt;
&lt;br /&gt;
[[File:EPaper-Display-1.54.PNG|250px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Setup&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 Install Seeed &amp;lt;b&amp;gt;GFX Library&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 https://github.com/Seeed-Studio/Seeed_GFX&lt;br /&gt;
&lt;br /&gt;
This library has same function as TFT library and no compatible with it. If you have installed TFT library or other similary display libraries, please uninstall it first.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Create a driver.h file&amp;lt;/b&amp;gt; and paste the following code into it.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Seeed GFX Library - &amp;lt;b&amp;gt;Online Configuration Generator&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
https://seeed-studio.github.io/Seeed_GFX/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// driver.h file &lt;br /&gt;
#define BOARD_SCREEN_COMBO 505 // 1.54 inch monochrome ePaper Screen （SSD1681）&lt;br /&gt;
#define USE_XIAO_EPAPER_BREAKOUT_BOARD&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sketch -&amp;gt; &amp;lt;b&amp;gt;Include Library&amp;lt;/b&amp;gt; -&amp;gt; Add .ZIP&amp;lt;br&amp;gt;&lt;br /&gt;
Seeed_GFX-master.zip&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Upload the Code&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
driver.h&amp;lt;br&amp;gt;&lt;br /&gt;
HelloWorld.ino&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Liens externes ====&lt;br /&gt;
&lt;br /&gt;
https://www.seeedstudio.com/1-54-Monochrome-ePaper-Display-with-200x200-Pixels-p-5776.html &amp;lt;font color=red&amp;gt;Shop&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://wiki.seeedstudio.com/XIAO-eInk-Expansion-Board/ &amp;lt;font color=red&amp;gt;Wiki&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exemples ===&lt;br /&gt;
&lt;br /&gt;
/examples/ePaper/Basic&lt;br /&gt;
&lt;br /&gt;
1 Bitmap: Display a bitmap image.&amp;lt;br&amp;gt;&lt;br /&gt;
2 Clock: Display a clock.&amp;lt;br&amp;gt;&lt;br /&gt;
3 Clock_digital: Display a digital clock.&amp;lt;br&amp;gt;&lt;br /&gt;
4 HelloWorld: &amp;lt;br&amp;gt;&lt;br /&gt;
5 Shape: Display different sizes of words and shape randomly.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [Code 1] Display a bitmap image ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;quot;TFT_eSPI.h&amp;quot;&lt;br /&gt;
#include &amp;quot;image.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
EPaper epaper;&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
  delay(2000);&lt;br /&gt;
  Serial.println(&amp;quot;1.54\&amp;quot; E-Paper Bitmap Display Example&amp;quot;);&lt;br /&gt;
  &lt;br /&gt;
  epaper.begin();&lt;br /&gt;
  &lt;br /&gt;
  // Clear screen to white&lt;br /&gt;
  epaper.fillScreen(TFT_WHITE);&lt;br /&gt;
  epaper.update();&lt;br /&gt;
  delay(1000);&lt;br /&gt;
  &lt;br /&gt;
  // Display bitmap image using drawBitmap API&lt;br /&gt;
  // drawBitmap(x, y, bitmap_data, width, height, color)&lt;br /&gt;
  epaper.drawBitmap(0, 0, gImage_1inch54, 200, 200, TFT_BLACK);&lt;br /&gt;
  epaper.update();&lt;br /&gt;
  &lt;br /&gt;
  Serial.println(&amp;quot;Bitmap displayed successfully&amp;quot;);&lt;br /&gt;
  &lt;br /&gt;
  // Put display to sleep to save power&lt;br /&gt;
  epaper.sleep();&lt;br /&gt;
#else&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
  Serial.println(&amp;quot;EPAPER_ENABLE not defined. Please select the correct setup file.&amp;quot;);&lt;br /&gt;
#endif&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop()&lt;br /&gt;
{&lt;br /&gt;
  // Nothing to do here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;onglet driver.h&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// driver.h file &lt;br /&gt;
#define BOARD_SCREEN_COMBO 505 // 1.54 inch monochrome ePaper Screen （SSD1681）&lt;br /&gt;
#define USE_XIAO_EPAPER_BREAKOUT_BOARD&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;onglet image.h&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * Image header file for 1.54&amp;quot; E-Paper Display&lt;br /&gt;
 * &lt;br /&gt;
 * Image specifications:&lt;br /&gt;
 * - Size: 200x200 pixels&lt;br /&gt;
 * - Format: 1-bit monochrome bitmap&lt;br /&gt;
 * - Color depth: Black and White&lt;br /&gt;
 * &lt;br /&gt;
 * To generate your own image:&lt;br /&gt;
 * 1. Prepare a 200x200 pixel image&lt;br /&gt;
 * 2. Convert to 1-bit monochrome bitmap&lt;br /&gt;
 * 3. Use image2cpp or similar tool to generate C array&lt;br /&gt;
 * 4. Replace the array below with your generated data&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
#ifndef _IMAGE_H_&lt;br /&gt;
#define _IMAGE_H_&lt;br /&gt;
&lt;br /&gt;
// Placeholder for 200x200 bitmap image&lt;br /&gt;
// Replace this with your actual image data&lt;br /&gt;
const unsigned char gImage_1inch54[] PROGMEM = {&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0xC0, 0x00, 0x00,&lt;br /&gt;
  0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x07, 0xC0,&lt;br /&gt;
  0x7C, 0x07, 0xC0, 0xFD, 0x81, 0xFC, 0xC6, 0x18, 0x7E, 0xC0, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x0F, 0xF0, 0xFE, 0x1F, 0xE1, 0xFF, 0x83, 0xFC, 0xEE,&lt;br /&gt;
  0x18, 0xFF, 0xCC, 0x7F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,&lt;br /&gt;
  0x1C, 0x71, 0xC7, 0x1C, 0x73, 0xC7, 0x83, 0x00, 0xEE, 0x19, 0xE3, 0xCC, 0xE3, 0xC0, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x18, 0x3B, 0x83, 0x38, 0x33, 0x83, 0x83,&lt;br /&gt;
  0x80, 0xCE, 0x19, 0xC1, 0xCD, 0xC1, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x7C, 0x3F, 0xFB, 0xFF, 0xBF, 0xF3, 0x03, 0x83, 0xF0, 0xCE, 0x19, 0x81, 0xCD, 0xC0, 0xC0,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0xFB, 0xFF, 0xBF, 0xF3,&lt;br /&gt;
  0x03, 0x81, 0xFC, 0xCE, 0x19, 0x81, 0xCD, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x07, 0xB8, 0x03, 0x80, 0x38, 0x03, 0x03, 0x80, 0x1C, 0xCE, 0x19, 0x81, 0xCD,&lt;br /&gt;
  0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x9C, 0x01, 0x80,&lt;br /&gt;
  0x38, 0x03, 0x87, 0x80, 0x0C, 0xC6, 0x19, 0xC3, 0xCC, 0xE1, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x9F, 0xF1, 0xFF, 0x1F, 0xE1, 0xFF, 0x83, 0x1C, 0xE7, 0xF8,&lt;br /&gt;
  0xFF, 0xCC, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x0F,&lt;br /&gt;
  0xE0, 0xFE, 0x0F, 0xE0, 0xFF, 0x83, 0xF8, 0xE3, 0xF0, 0x7F, 0xCC, 0x7F, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x03, 0x80, 0x38, 0x03, 0x80, 0x39, 0x80, 0xE0,&lt;br /&gt;
  0x20, 0xC0, 0x1C, 0xCC, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0xC0, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79,&lt;br /&gt;
  0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x38, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0xC0, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0xDC, 0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x18, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFE, 0xFC, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x01, 0x80, 0x13, 0xC6, 0xE6, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xC0, 0xB7, 0xE6, 0x66, 0xE4,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0xF8, 0xE6, 0x66, 0x66, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xFC, 0xC6, 0x76,&lt;br /&gt;
  0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xF0,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x04, 0x3C, 0xCC, 0xC6, 0x66, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x30, 0xCC,&lt;br /&gt;
  0xC3, 0xE6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,&lt;br /&gt;
  0xFF, 0xF8, 0x00, 0x03, 0x00, 0x3F, 0x3B, 0x70, 0xCE, 0xC1, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFF, 0xF8, 0x00, 0x43, 0x06, 0x3F, 0x33,&lt;br /&gt;
  0xB0, 0xE6, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFE,&lt;br /&gt;
  0x00, 0x00, 0xFF, 0xF8, 0x00, 0xE3, 0x9F, 0xBB, 0xB3, 0xBE, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0xF8, 0x00, 0xF7, 0x99,&lt;br /&gt;
  0x99, 0xBB, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F,&lt;br /&gt;
  0xFF, 0xFF, 0x00, 0x01, 0xFF, 0xF8, 0x00, 0xF7, 0x99, 0x99, 0x9F, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0xFC, 0x00,&lt;br /&gt;
  0x7F, 0x99, 0x99, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x1F, 0xFF, 0xFF, 0x00, 0x03, 0xFB, 0xFC, 0x00, 0x7D, 0x9F, 0x98, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x30, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0x00, 0x03, 0xFB,&lt;br /&gt;
  0xFC, 0x00, 0x6C, 0xCF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0xE7, 0x60, 0x00, 0x00,&lt;br /&gt;
  0x0C, 0x00, 0x00, 0x1F, 0xFF, 0xE0, 0x00, 0x07, 0xF3, 0xFC, 0x00, 0x64, 0xC0, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0xC0, 0x02, 0x31, 0x33, 0x60, 0x00, 0x01, 0xFC, 0x00, 0x00, 0x1F, 0xF8, 0x00, 0x00,&lt;br /&gt;
  0x07, 0xF3, 0xFC, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x1F, 0xB8, 0x71, 0xE0,&lt;br /&gt;
  0x00, 0x03, 0xFC, 0x00, 0x00, 0x1F, 0xE0, 0x00, 0x00, 0x07, 0xF3, 0xFE, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0xFC, 0x07, 0x99, 0x99, 0xB1, 0xC0, 0x00, 0x07, 0xFC, 0x00, 0x00, 0x1F, 0xE0,&lt;br /&gt;
  0x00, 0x00, 0x0F, 0xF3, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x66, 0x19, 0x99,&lt;br /&gt;
  0xB8, 0xC0, 0x00, 0x1F, 0xFE, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0x0F, 0xE3, 0xFE, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0x67, 0x19, 0x99, 0xF8, 0xC1, 0x00, 0x7F, 0xFE, 0x00, 0x00,&lt;br /&gt;
  0x0F, 0xF0, 0x00, 0x00, 0x0F, 0xE1, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xC6, 0x67,&lt;br /&gt;
  0xD9, 0x9C, 0xC1, 0xFF, 0x01, 0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0x1F, 0xE1, 0xFE,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xE7, 0x60, 0xDF, 0x80, 0x0F, 0xFF, 0x01, 0xFF, 0xFE,&lt;br /&gt;
  0x00, 0x00, 0x0F, 0xF7, 0xFC, 0x00, 0x1F, 0xC1, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0xE0,&lt;br /&gt;
  0x66, 0x77, 0xDE, 0x01, 0xFF, 0xFF, 0x01, 0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x3F,&lt;br /&gt;
  0xC1, 0xFF, 0x00, 0x00, 0x04, 0x00, 0x3E, 0x66, 0xC0, 0x66, 0x37, 0x8C, 0x7F, 0xFF, 0xFF, 0x01,&lt;br /&gt;
  0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xC0, 0x3F, 0x81, 0xFF, 0xF0, 0x00, 0x3F, 0x0E, 0x7F,&lt;br /&gt;
  0x7E, 0xE0, 0x7C, 0x20, 0x0F, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x0F, 0xFF, 0xFF,&lt;br /&gt;
  0xC0, 0x3F, 0x81, 0xFF, 0xF0, 0x00, 0x3B, 0xBE, 0x73, 0x78, 0x60, 0x78, 0x03, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0x00, 0x81, 0xFF, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xE0, 0x7F, 0x9F, 0xFF, 0xF0, 0x00, 0x31,&lt;br /&gt;
  0x87, 0x73, 0x70, 0x60, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x07,&lt;br /&gt;
  0xFF, 0xFF, 0xF0, 0x7F, 0xFF, 0xFF, 0xF0, 0x0F, 0x3B, 0x8F, 0x33, 0x3E, 0x40, 0x0F, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x07, 0xF8, 0x7F, 0xF0, 0x7F, 0xFF, 0xFF, 0xF8,&lt;br /&gt;
  0x0D, 0x9F, 0x1B, 0x3F, 0x18, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0x00,&lt;br /&gt;
  0x00, 0x07, 0xE0, 0x3F, 0xF0, 0xFF, 0xFF, 0xFF, 0xF8, 0x19, 0x9C, 0x3B, 0x3E, 0x00, 0x7F, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x00, 0xC0, 0x1F, 0xF8, 0x7F, 0xFF,&lt;br /&gt;
  0xFF, 0xF0, 0x1F, 0x98, 0x1F, 0x30, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,&lt;br /&gt;
  0xFF, 0x80, 0x00, 0x00, 0x00, 0x0F, 0xF8, 0x7F, 0xFF, 0xFF, 0x80, 0x1C, 0x18, 0x00, 0x33, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x0F, 0xF8,&lt;br /&gt;
  0x7F, 0xFF, 0xFF, 0x80, 0x0F, 0x98, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0x00, 0x00, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x0F, 0xF8, 0x7F, 0xC0, 0x7F, 0x80, 0x07, 0x00, 0x1F,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x80, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x0F, 0xF8, 0x78, 0x00, 0x7F, 0xC0, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0x7F, 0xC0, 0x00,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x7F, 0xC0, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0x7F, 0xC0, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x00, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0x3F,&lt;br /&gt;
  0xC7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x7F,&lt;br /&gt;
  0xC0, 0x00, 0x01, 0x80, 0x1F, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x03, 0xE0, 0x7F, 0xF0, 0x00,&lt;br /&gt;
  0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,&lt;br /&gt;
  0x00, 0x7F, 0xC0, 0x00, 0x03, 0xFF, 0xFF, 0xE0, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x07, 0xFF, 0xFF,&lt;br /&gt;
  0xE0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0x00, 0x00, 0x3F, 0xE0, 0x00, 0x07, 0xFF, 0xFF, 0xC0, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0xE0, 0x00, 0x07,&lt;br /&gt;
  0xFF, 0xFF, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0xE7, 0xC1, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0xFF,&lt;br /&gt;
  0xC3, 0xC1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0xFF, 0xC3, 0xE0, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x0F,&lt;br /&gt;
  0xFF, 0xFF, 0xC3, 0xE1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0x00, 0x1F, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x7F, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFE, 0x7F, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xEF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xC1, 0xFF, 0xFF, 0xFE, 0x7F, 0xF7, 0x3F, 0xFF, 0xFF,&lt;br /&gt;
  0xF1, 0xE3, 0xE7, 0xF2, 0x39, 0x3F, 0xFF, 0xC7, 0x8F, 0x9F, 0xCC, 0xE7, 0x7F, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xC0, 0xFF, 0xFF, 0xFE, 0x7F, 0xE7, 0xFF, 0xFF, 0xFF, 0xC0, 0xC1, 0xC3, 0xF3, 0x39, 0xBC, 0xF3,&lt;br /&gt;
  0x03, 0x07, 0x0F, 0xCC, 0xE7, 0x3F, 0xFF, 0xFF, 0xFF, 0xCE, 0x61, 0xC3, 0x8E, 0x66, 0x41, 0x38,&lt;br /&gt;
  0x70, 0x73, 0xFC, 0xCC, 0x99, 0xF7, 0x33, 0xBE, 0x67, 0xF3, 0x32, 0x67, 0xDC, 0xE7, 0x3F, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xCC, 0x40, 0x83, 0x06, 0x66, 0x41, 0x30, 0x30, 0x33, 0xFC, 0xCC, 0x99, 0xF7, 0x33,&lt;br /&gt;
  0x9F, 0x0F, 0xF3, 0x32, 0x67, 0xDC, 0x67, 0xBF, 0xFF, 0xFF, 0xFF, 0xC0, 0xCC, 0x8E, 0x62, 0x66,&lt;br /&gt;
  0x67, 0x33, 0x33, 0x33, 0xF8, 0xCC, 0x99, 0xE7, 0x13, 0x9F, 0x9F, 0xE3, 0x32, 0x67, 0x9C, 0x07,&lt;br /&gt;
  0xBF, 0xFF, 0xFF, 0xFF, 0xC1, 0xC0, 0xC2, 0x72, 0x66, 0x67, 0x33, 0x33, 0x3F, 0xF9, 0xCC, 0x99,&lt;br /&gt;
  0xE7, 0x97, 0x9F, 0x0F, 0xE7, 0x32, 0x67, 0x9C, 0x67, 0xBF, 0xFF, 0xFF, 0xFF, 0xCC, 0xCF, 0xF2,&lt;br /&gt;
  0x62, 0x66, 0x67, 0x33, 0x33, 0x3F, 0xF3, 0xCC, 0x99, 0xF7, 0x87, 0x9E, 0x67, 0xCF, 0x32, 0x67,&lt;br /&gt;
  0xDC, 0xE7, 0xBF, 0xFF, 0xFF, 0xFF, 0xCC, 0xC5, 0x93, 0x06, 0x20, 0x63, 0x30, 0x33, 0x33, 0xE0,&lt;br /&gt;
  0xC1, 0x81, 0xF7, 0x87, 0x9C, 0xF3, 0x83, 0x06, 0x07, 0xDC, 0xE7, 0x3F, 0xFF, 0xFF, 0xFF, 0xCE,&lt;br /&gt;
  0x61, 0x87, 0x0F, 0x30, 0x71, 0x38, 0x73, 0x33, 0xC0, 0xE1, 0xC3, 0xF3, 0xC7, 0xBF, 0xFF, 0x03,&lt;br /&gt;
  0x8F, 0x0F, 0xCC, 0xE7, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xF3, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xFF, 0x3F, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xFF, 0x7F,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0xFE, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0x8F, 0xCE, 0x0E, 0x7F, 0xFC,&lt;br /&gt;
  0x18, 0x3E, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFE, 0x7F, 0xFF, 0xFF, 0x07, 0x86, 0x07, 0xFF, 0xFC, 0x18, 0x1C, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xE1, 0xD1, 0x91, 0xC3, 0xC4, 0x18, 0x74, 0xDF, 0xE7, 0x86, 0x62,&lt;br /&gt;
  0x60, 0xFC, 0xF9, 0x98, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xC0, 0xC0,&lt;br /&gt;
  0x81, 0xC1, 0x84, 0x10, 0x60, 0x8F, 0xE7, 0x26, 0x62, 0x60, 0x7C, 0xF9, 0x99, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xCC, 0xCC, 0x88, 0x99, 0x1E, 0x73, 0x23, 0xDF, 0xE6,&lt;br /&gt;
  0x66, 0x06, 0x66, 0x7C, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF,&lt;br /&gt;
  0xCC, 0xCC, 0x8C, 0x81, 0x3E, 0x63, 0x23, 0xFF, 0xCE, 0x06, 0x0E, 0x66, 0x7C, 0x38, 0x39, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xCC, 0xCC, 0x8C, 0x9F, 0x3E, 0x73, 0x23,&lt;br /&gt;
  0xFF, 0x8E, 0x06, 0x7E, 0x66, 0x7C, 0xF9, 0xF9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xC0, 0xC0, 0xCC, 0x8C, 0x8B, 0x86, 0x30, 0x23, 0x8F, 0x03, 0xE6, 0x7E, 0x66, 0x7C, 0xF9,&lt;br /&gt;
  0xFC, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xE1, 0xCC, 0x8C, 0xC3, 0x87,&lt;br /&gt;
  0x18, 0x63, 0x9F, 0x03, 0xE6, 0x7E, 0x66, 0x7C, 0xF9, 0xFE, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xCF, 0xFF, 0xFE, 0x7C, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xFF, 0xFC, 0x7C,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF,&lt;br /&gt;
  0xE9, 0x0E, 0x66, 0x1C, 0x61, 0xCE, 0x1D, 0xF8, 0x7C, 0xE1, 0x99, 0xC7, 0x30, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xE1, 0x06, 0x64, 0x18, 0x60, 0xCC, 0x18,&lt;br /&gt;
  0xF8, 0x7C, 0xC0, 0x99, 0x83, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xCC, 0x67, 0xE6, 0x64, 0x71, 0xFC, 0xCC, 0xCD, 0xF2, 0x7C, 0xCC, 0x99, 0x33, 0x23, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCC, 0x67, 0x07, 0x0E, 0x13, 0xE0,&lt;br /&gt;
  0xCC, 0x0F, 0xF0, 0x3C, 0xC0, 0xCB, 0x03, 0x30, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xCE, 0x67, 0x27, 0x0F, 0x93, 0xE4, 0xCC, 0xFF, 0xF0, 0x3C, 0xCF, 0xC3, 0x3F,&lt;br /&gt;
  0x3C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x67, 0x07, 0x9C,&lt;br /&gt;
  0x98, 0x60, 0xC4, 0x58, 0xFE, 0x7C, 0x45, 0xC3, 0x17, 0x24, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xE7, 0x07, 0x9C, 0x38, 0x60, 0xE6, 0x19, 0xFE, 0x7E, 0x61,&lt;br /&gt;
  0xE7, 0x83, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFE, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xFE, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0x87, 0x07, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xCF, 0xFC, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0x07, 0x03, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCC, 0x98, 0x30, 0xC8, 0x18, 0x78,&lt;br /&gt;
  0xE3, 0x9F, 0x3F, 0x33, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xCC, 0x08, 0x20, 0xC0, 0x18, 0x30, 0xC1, 0x9F, 0x1F, 0x33, 0x3F, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCC, 0xCC, 0xE6, 0x47,&lt;br /&gt;
  0x3E, 0x23, 0x89, 0x9F, 0x07, 0x03, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCC, 0xCC, 0xE0, 0x4F, 0x38, 0x27, 0x81, 0xFF, 0xE3, 0x07, 0x3F,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCC, 0xCC,&lt;br /&gt;
  0xE7, 0xCF, 0x33, 0x23, 0x8F, 0xFF, 0xF3, 0x3F, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCC, 0xCC, 0x62, 0xCF, 0x30, 0x30, 0xC1, 0x9F, 0x03,&lt;br /&gt;
  0x3F, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xCC, 0xCE, 0x30, 0xCF, 0x38, 0x30, 0xE1, 0x9F, 0x07, 0x3F, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [Code 2 Display a clock] ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 An example digital clock using a TFT LCD screen to show the time.&lt;br /&gt;
 Demonstrates use of the font printing routines. (Time updates but date does not.)&lt;br /&gt;
 &lt;br /&gt;
 For a more accurate clock, it would be better to use the RTClib library.&lt;br /&gt;
 But this is just a demo. &lt;br /&gt;
 &lt;br /&gt;
 This examples uses the hardware SPI only. Non-hardware SPI&lt;br /&gt;
 is just too slow (~8 times slower!)&lt;br /&gt;
 &lt;br /&gt;
 Based on clock sketch by Gilchrist 6/2/2014 1.0&lt;br /&gt;
 Updated by Bodmer&lt;br /&gt;
A few colour codes:&lt;br /&gt;
 &lt;br /&gt;
code	color&lt;br /&gt;
0x0000	Black&lt;br /&gt;
0xFFFF	White&lt;br /&gt;
0xBDF7	Light Gray&lt;br /&gt;
0x7BEF	Dark Gray&lt;br /&gt;
0xF800	Red&lt;br /&gt;
0xFFE0	Yellow&lt;br /&gt;
0xFBE0	Orange&lt;br /&gt;
0x79E0	Brown&lt;br /&gt;
0x7E0	Green&lt;br /&gt;
0x7FF	Cyan&lt;br /&gt;
0x1F	Blue&lt;br /&gt;
0xF81F	Pink&lt;br /&gt;
&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;TFT_eSPI.h&amp;gt; // Graphics and font library for ST7735 driver chip&lt;br /&gt;
#include &amp;lt;SPI.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#ifdef EPAPER_ENABLE // Only compile this code if the EPAPER_ENABLE is defined in User_Setup.h&lt;br /&gt;
&lt;br /&gt;
EPaper epaper = EPaper();  // Invoke library, pins defined in User_Setup.h&lt;br /&gt;
&lt;br /&gt;
uint32_t targetTime = 0;       // for next 1 second timeout&lt;br /&gt;
&lt;br /&gt;
byte omm = 99;&lt;br /&gt;
bool initial = 1;&lt;br /&gt;
byte xcolon = 0;&lt;br /&gt;
unsigned int colour = 0;&lt;br /&gt;
&lt;br /&gt;
static uint8_t conv2d(const char* p) {&lt;br /&gt;
  uint8_t v = 0;&lt;br /&gt;
  if (&amp;#039;0&amp;#039; &amp;lt;= *p &amp;amp;&amp;amp; *p &amp;lt;= &amp;#039;9&amp;#039;)&lt;br /&gt;
    v = *p - &amp;#039;0&amp;#039;;&lt;br /&gt;
  return 10 * v + *++p - &amp;#039;0&amp;#039;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
uint8_t hh=conv2d(__TIME__), mm=conv2d(__TIME__+3), ss=conv2d(__TIME__+6);  // Get H, M, S from compile time&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
void setup(void) {&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
  epaper.begin();&lt;br /&gt;
  epaper.setRotation(1);&lt;br /&gt;
  epaper.fillScreen(TFT_BLACK);&lt;br /&gt;
&lt;br /&gt;
  epaper.setTextColor(TFT_YELLOW, TFT_BLACK); // Note: the new fonts do not draw the background colour&lt;br /&gt;
  epaper.update(); // update the display&lt;br /&gt;
  targetTime = millis() + 1000; &lt;br /&gt;
#endif&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
  if (targetTime &amp;lt; millis()) {&lt;br /&gt;
    targetTime = millis()+1000;&lt;br /&gt;
    ss++;              // Advance second&lt;br /&gt;
    if (ss==60) {&lt;br /&gt;
      ss=0;&lt;br /&gt;
      omm = mm;&lt;br /&gt;
      mm++;            // Advance minute&lt;br /&gt;
      if(mm&amp;gt;59) {&lt;br /&gt;
        mm=0;&lt;br /&gt;
        hh++;          // Advance hour&lt;br /&gt;
        if (hh&amp;gt;23) {&lt;br /&gt;
          hh=0;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (ss==0 || initial) {&lt;br /&gt;
      initial = 0;&lt;br /&gt;
      epaper.setTextColor(TFT_GREEN, TFT_BLACK);&lt;br /&gt;
      epaper.setCursor (8, 52);&lt;br /&gt;
      epaper.print(__DATE__); // This uses the standard ADAFruit small font&lt;br /&gt;
&lt;br /&gt;
      epaper.setTextColor(TFT_BLUE, TFT_BLACK);&lt;br /&gt;
      epaper.drawCentreString(&amp;quot;It is windy&amp;quot;,120,48,2); // Next size up font 2&lt;br /&gt;
&lt;br /&gt;
      //epaper.setTextColor(0xF81F, TFT_BLACK); // Pink&lt;br /&gt;
      //epaper.drawCentreString(&amp;quot;12.34&amp;quot;,80,100,6); // Large font 6 only contains characters [space] 0 1 2 3 4 5 6 7 8 9 . : a p m&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Update digital time&lt;br /&gt;
    byte xpos = 6;&lt;br /&gt;
    byte ypos = 0;&lt;br /&gt;
    if (omm != mm) { // Only redraw every minute to minimise flicker&lt;br /&gt;
      // Uncomment ONE of the next 2 lines, using the ghost image demonstrates text overlay as time is drawn over it&lt;br /&gt;
      epaper.setTextColor(TFT_BLACK, TFT_BLACK);  // Leave a 7 segment ghost image, comment out next line!&lt;br /&gt;
      //epaper.setTextColor(TFT_BLACK, TFT_BLACK); // Set font colour to black to wipe image&lt;br /&gt;
      // Font 7 is to show a pseudo 7 segment display.&lt;br /&gt;
      // Font 7 only contains characters [space] 0 1 2 3 4 5 6 7 8 9 0 : .&lt;br /&gt;
      epaper.drawString(&amp;quot;88:88&amp;quot;,xpos,ypos,7); // Overwrite the text to clear it&lt;br /&gt;
      epaper.setTextColor(0xFBE0); // Orange&lt;br /&gt;
      omm = mm;&lt;br /&gt;
&lt;br /&gt;
      if (hh&amp;lt;10) xpos+= epaper.drawChar(&amp;#039;0&amp;#039;,xpos,ypos,7);&lt;br /&gt;
      xpos+= epaper.drawNumber(hh,xpos,ypos,7);&lt;br /&gt;
      xcolon=xpos;&lt;br /&gt;
      xpos+= epaper.drawChar(&amp;#039;:&amp;#039;,xpos,ypos,7);&lt;br /&gt;
      if (mm&amp;lt;10) xpos+= epaper.drawChar(&amp;#039;0&amp;#039;,xpos,ypos,7);&lt;br /&gt;
      epaper.drawNumber(mm,xpos,ypos,7);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (ss%2) { // Flash the colon&lt;br /&gt;
      epaper.setTextColor(TFT_BLACK, TFT_BLACK);&lt;br /&gt;
      xpos+= epaper.drawChar(&amp;#039;:&amp;#039;,xcolon,ypos,7);&lt;br /&gt;
      epaper.setTextColor(0xFBE0, TFT_BLACK);&lt;br /&gt;
    }&lt;br /&gt;
    else {&lt;br /&gt;
      epaper.drawChar(&amp;#039;:&amp;#039;,xcolon,ypos,7);&lt;br /&gt;
      colour = random(0xFFFF);&lt;br /&gt;
      // Erase the old text with a rectangle, the disadvantage of this method is increased display flicker&lt;br /&gt;
      epaper.fillRect (0, 64, 160, 20, TFT_BLACK);&lt;br /&gt;
      epaper.setTextColor(TFT_WHITE);&lt;br /&gt;
    }&lt;br /&gt;
    epaper.update(); // update the display&lt;br /&gt;
  }&lt;br /&gt;
#endif&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;onglet driver.h&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// driver.h file &lt;br /&gt;
#define BOARD_SCREEN_COMBO 505 // 1.54 inch monochrome ePaper Screen （SSD1681）&lt;br /&gt;
#define USE_XIAO_EPAPER_BREAKOUT_BOARD&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [Code 2 Display a clock - WIFI] ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;TFT_eSPI.h&amp;gt;   // Librairie pour ton écran E-paper&lt;br /&gt;
#include &amp;lt;SPI.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
EPaper epaper = EPaper();  // Pins définis dans User_Setup.h&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// ⚙️ Paramètres WiFi&lt;br /&gt;
const char* ssid     = &amp;quot;TON_SSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TON_MOTDEPASSE&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ⚙️ Paramètres NTP&lt;br /&gt;
const char* ntpServer = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const long  gmtOffset_sec = 3600;       // Décalage GMT (ex: +1h pour Suisse en hiver)&lt;br /&gt;
const int   daylightOffset_sec = 3600;  // Décalage été (DST)&lt;br /&gt;
&lt;br /&gt;
// Variables pour éviter scintillement&lt;br /&gt;
int lastMinute = -1;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
  epaper.begin();&lt;br /&gt;
  epaper.setRotation(1);&lt;br /&gt;
  epaper.fillScreen(TFT_BLACK);&lt;br /&gt;
  epaper.setTextColor(TFT_WHITE, TFT_BLACK);&lt;br /&gt;
  epaper.update();&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Initialisation NTP&lt;br /&gt;
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  // Récupérer l’heure système&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    return; // Si pas d’heure dispo&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Rafraîchir uniquement si la minute change&lt;br /&gt;
  if (timeinfo.tm_min != lastMinute) {&lt;br /&gt;
    lastMinute = timeinfo.tm_min;&lt;br /&gt;
&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
    epaper.fillScreen(TFT_BLACK);&lt;br /&gt;
&lt;br /&gt;
    // Afficher la date&lt;br /&gt;
    epaper.setTextColor(TFT_GREEN, TFT_BLACK);&lt;br /&gt;
    epaper.setCursor(10, 20);&lt;br /&gt;
    epaper.printf(&amp;quot;%02d/%02d/%04d&amp;quot;, timeinfo.tm_mday, timeinfo.tm_mon+1, timeinfo.tm_year+1900);&lt;br /&gt;
&lt;br /&gt;
    // Afficher l’heure&lt;br /&gt;
    epaper.setTextColor(TFT_ORANGE, TFT_BLACK);&lt;br /&gt;
    epaper.setCursor(10, 60);&lt;br /&gt;
    epaper.printf(&amp;quot;%02d:%02d&amp;quot;, timeinfo.tm_hour, timeinfo.tm_min);&lt;br /&gt;
&lt;br /&gt;
    epaper.update(); // Mise à jour écran&lt;br /&gt;
#endif&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  delay(1000); // Boucle chaque seconde mais rafraîchit seulement à chaque minute&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>144.2.107.134</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.myows.top/index.php?title=1.54-inch_E-paper_Display&amp;diff=2035</id>
		<title>1.54-inch E-paper Display</title>
		<link rel="alternate" type="text/html" href="https://wiki.myows.top/index.php?title=1.54-inch_E-paper_Display&amp;diff=2035"/>
		<updated>2025-12-12T21:42:33Z</updated>

		<summary type="html">&lt;p&gt;144.2.107.134: /* Support */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
=== Support ===&lt;br /&gt;
&lt;br /&gt;
1.54-inch E-paper Display&lt;br /&gt;
&lt;br /&gt;
[[File:EPaper-Display-1.54.PNG|250px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Setup&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Install Seeed &amp;lt;b&amp;gt;GFX Library&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
https://github.com/Seeed-Studio/Seeed_GFX&lt;br /&gt;
&lt;br /&gt;
This library has same function as TFT library and no compatible with it. If you have installed TFT library or other similary display libraries, please uninstall it first.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Create a driver.h file&amp;lt;/b&amp;gt; and paste the following code into it.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Seeed GFX Library - &amp;lt;b&amp;gt;Online Configuration Generator&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
https://seeed-studio.github.io/Seeed_GFX/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// driver.h file &lt;br /&gt;
#define BOARD_SCREEN_COMBO 505 // 1.54 inch monochrome ePaper Screen （SSD1681）&lt;br /&gt;
#define USE_XIAO_EPAPER_BREAKOUT_BOARD&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sketch -&amp;gt; &amp;lt;b&amp;gt;Include Library&amp;lt;/b&amp;gt; -&amp;gt; Add .ZIP&amp;lt;br&amp;gt;&lt;br /&gt;
Seeed_GFX-master.zip&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Upload the Code&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
driver.h&amp;lt;br&amp;gt;&lt;br /&gt;
HelloWorld.ino&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Liens externes ====&lt;br /&gt;
&lt;br /&gt;
https://www.seeedstudio.com/1-54-Monochrome-ePaper-Display-with-200x200-Pixels-p-5776.html &amp;lt;font color=red&amp;gt;Shop&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://wiki.seeedstudio.com/XIAO-eInk-Expansion-Board/ &amp;lt;font color=red&amp;gt;Wiki&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exemples ===&lt;br /&gt;
&lt;br /&gt;
/examples/ePaper/Basic&lt;br /&gt;
&lt;br /&gt;
1 Bitmap: Display a bitmap image.&amp;lt;br&amp;gt;&lt;br /&gt;
2 Clock: Display a clock.&amp;lt;br&amp;gt;&lt;br /&gt;
3 Clock_digital: Display a digital clock.&amp;lt;br&amp;gt;&lt;br /&gt;
4 HelloWorld: &amp;lt;br&amp;gt;&lt;br /&gt;
5 Shape: Display different sizes of words and shape randomly.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [Code 1] Display a bitmap image ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;quot;TFT_eSPI.h&amp;quot;&lt;br /&gt;
#include &amp;quot;image.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
EPaper epaper;&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
  delay(2000);&lt;br /&gt;
  Serial.println(&amp;quot;1.54\&amp;quot; E-Paper Bitmap Display Example&amp;quot;);&lt;br /&gt;
  &lt;br /&gt;
  epaper.begin();&lt;br /&gt;
  &lt;br /&gt;
  // Clear screen to white&lt;br /&gt;
  epaper.fillScreen(TFT_WHITE);&lt;br /&gt;
  epaper.update();&lt;br /&gt;
  delay(1000);&lt;br /&gt;
  &lt;br /&gt;
  // Display bitmap image using drawBitmap API&lt;br /&gt;
  // drawBitmap(x, y, bitmap_data, width, height, color)&lt;br /&gt;
  epaper.drawBitmap(0, 0, gImage_1inch54, 200, 200, TFT_BLACK);&lt;br /&gt;
  epaper.update();&lt;br /&gt;
  &lt;br /&gt;
  Serial.println(&amp;quot;Bitmap displayed successfully&amp;quot;);&lt;br /&gt;
  &lt;br /&gt;
  // Put display to sleep to save power&lt;br /&gt;
  epaper.sleep();&lt;br /&gt;
#else&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
  Serial.println(&amp;quot;EPAPER_ENABLE not defined. Please select the correct setup file.&amp;quot;);&lt;br /&gt;
#endif&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop()&lt;br /&gt;
{&lt;br /&gt;
  // Nothing to do here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;onglet driver.h&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// driver.h file &lt;br /&gt;
#define BOARD_SCREEN_COMBO 505 // 1.54 inch monochrome ePaper Screen （SSD1681）&lt;br /&gt;
#define USE_XIAO_EPAPER_BREAKOUT_BOARD&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;onglet image.h&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * Image header file for 1.54&amp;quot; E-Paper Display&lt;br /&gt;
 * &lt;br /&gt;
 * Image specifications:&lt;br /&gt;
 * - Size: 200x200 pixels&lt;br /&gt;
 * - Format: 1-bit monochrome bitmap&lt;br /&gt;
 * - Color depth: Black and White&lt;br /&gt;
 * &lt;br /&gt;
 * To generate your own image:&lt;br /&gt;
 * 1. Prepare a 200x200 pixel image&lt;br /&gt;
 * 2. Convert to 1-bit monochrome bitmap&lt;br /&gt;
 * 3. Use image2cpp or similar tool to generate C array&lt;br /&gt;
 * 4. Replace the array below with your generated data&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
#ifndef _IMAGE_H_&lt;br /&gt;
#define _IMAGE_H_&lt;br /&gt;
&lt;br /&gt;
// Placeholder for 200x200 bitmap image&lt;br /&gt;
// Replace this with your actual image data&lt;br /&gt;
const unsigned char gImage_1inch54[] PROGMEM = {&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0xC0, 0x00, 0x00,&lt;br /&gt;
  0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x07, 0xC0,&lt;br /&gt;
  0x7C, 0x07, 0xC0, 0xFD, 0x81, 0xFC, 0xC6, 0x18, 0x7E, 0xC0, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x0F, 0xF0, 0xFE, 0x1F, 0xE1, 0xFF, 0x83, 0xFC, 0xEE,&lt;br /&gt;
  0x18, 0xFF, 0xCC, 0x7F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,&lt;br /&gt;
  0x1C, 0x71, 0xC7, 0x1C, 0x73, 0xC7, 0x83, 0x00, 0xEE, 0x19, 0xE3, 0xCC, 0xE3, 0xC0, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x18, 0x3B, 0x83, 0x38, 0x33, 0x83, 0x83,&lt;br /&gt;
  0x80, 0xCE, 0x19, 0xC1, 0xCD, 0xC1, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x7C, 0x3F, 0xFB, 0xFF, 0xBF, 0xF3, 0x03, 0x83, 0xF0, 0xCE, 0x19, 0x81, 0xCD, 0xC0, 0xC0,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0xFB, 0xFF, 0xBF, 0xF3,&lt;br /&gt;
  0x03, 0x81, 0xFC, 0xCE, 0x19, 0x81, 0xCD, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x07, 0xB8, 0x03, 0x80, 0x38, 0x03, 0x03, 0x80, 0x1C, 0xCE, 0x19, 0x81, 0xCD,&lt;br /&gt;
  0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x9C, 0x01, 0x80,&lt;br /&gt;
  0x38, 0x03, 0x87, 0x80, 0x0C, 0xC6, 0x19, 0xC3, 0xCC, 0xE1, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x9F, 0xF1, 0xFF, 0x1F, 0xE1, 0xFF, 0x83, 0x1C, 0xE7, 0xF8,&lt;br /&gt;
  0xFF, 0xCC, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x0F,&lt;br /&gt;
  0xE0, 0xFE, 0x0F, 0xE0, 0xFF, 0x83, 0xF8, 0xE3, 0xF0, 0x7F, 0xCC, 0x7F, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x03, 0x80, 0x38, 0x03, 0x80, 0x39, 0x80, 0xE0,&lt;br /&gt;
  0x20, 0xC0, 0x1C, 0xCC, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0xC0, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79,&lt;br /&gt;
  0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x38, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0xC0, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0xDC, 0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x18, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFE, 0xFC, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x01, 0x80, 0x13, 0xC6, 0xE6, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xC0, 0xB7, 0xE6, 0x66, 0xE4,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0xF8, 0xE6, 0x66, 0x66, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xFC, 0xC6, 0x76,&lt;br /&gt;
  0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xF0,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x04, 0x3C, 0xCC, 0xC6, 0x66, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x30, 0xCC,&lt;br /&gt;
  0xC3, 0xE6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,&lt;br /&gt;
  0xFF, 0xF8, 0x00, 0x03, 0x00, 0x3F, 0x3B, 0x70, 0xCE, 0xC1, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFF, 0xF8, 0x00, 0x43, 0x06, 0x3F, 0x33,&lt;br /&gt;
  0xB0, 0xE6, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFE,&lt;br /&gt;
  0x00, 0x00, 0xFF, 0xF8, 0x00, 0xE3, 0x9F, 0xBB, 0xB3, 0xBE, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0xF8, 0x00, 0xF7, 0x99,&lt;br /&gt;
  0x99, 0xBB, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F,&lt;br /&gt;
  0xFF, 0xFF, 0x00, 0x01, 0xFF, 0xF8, 0x00, 0xF7, 0x99, 0x99, 0x9F, 0x00, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0xFC, 0x00,&lt;br /&gt;
  0x7F, 0x99, 0x99, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x1F, 0xFF, 0xFF, 0x00, 0x03, 0xFB, 0xFC, 0x00, 0x7D, 0x9F, 0x98, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x30, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0x00, 0x03, 0xFB,&lt;br /&gt;
  0xFC, 0x00, 0x6C, 0xCF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0xE7, 0x60, 0x00, 0x00,&lt;br /&gt;
  0x0C, 0x00, 0x00, 0x1F, 0xFF, 0xE0, 0x00, 0x07, 0xF3, 0xFC, 0x00, 0x64, 0xC0, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0xC0, 0x02, 0x31, 0x33, 0x60, 0x00, 0x01, 0xFC, 0x00, 0x00, 0x1F, 0xF8, 0x00, 0x00,&lt;br /&gt;
  0x07, 0xF3, 0xFC, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x1F, 0xB8, 0x71, 0xE0,&lt;br /&gt;
  0x00, 0x03, 0xFC, 0x00, 0x00, 0x1F, 0xE0, 0x00, 0x00, 0x07, 0xF3, 0xFE, 0x00, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0xFC, 0x07, 0x99, 0x99, 0xB1, 0xC0, 0x00, 0x07, 0xFC, 0x00, 0x00, 0x1F, 0xE0,&lt;br /&gt;
  0x00, 0x00, 0x0F, 0xF3, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x66, 0x19, 0x99,&lt;br /&gt;
  0xB8, 0xC0, 0x00, 0x1F, 0xFE, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0x0F, 0xE3, 0xFE, 0x00, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0x67, 0x19, 0x99, 0xF8, 0xC1, 0x00, 0x7F, 0xFE, 0x00, 0x00,&lt;br /&gt;
  0x0F, 0xF0, 0x00, 0x00, 0x0F, 0xE1, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xC6, 0x67,&lt;br /&gt;
  0xD9, 0x9C, 0xC1, 0xFF, 0x01, 0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0x1F, 0xE1, 0xFE,&lt;br /&gt;
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xE7, 0x60, 0xDF, 0x80, 0x0F, 0xFF, 0x01, 0xFF, 0xFE,&lt;br /&gt;
  0x00, 0x00, 0x0F, 0xF7, 0xFC, 0x00, 0x1F, 0xC1, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0xE0,&lt;br /&gt;
  0x66, 0x77, 0xDE, 0x01, 0xFF, 0xFF, 0x01, 0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x3F,&lt;br /&gt;
  0xC1, 0xFF, 0x00, 0x00, 0x04, 0x00, 0x3E, 0x66, 0xC0, 0x66, 0x37, 0x8C, 0x7F, 0xFF, 0xFF, 0x01,&lt;br /&gt;
  0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xC0, 0x3F, 0x81, 0xFF, 0xF0, 0x00, 0x3F, 0x0E, 0x7F,&lt;br /&gt;
  0x7E, 0xE0, 0x7C, 0x20, 0x0F, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x0F, 0xFF, 0xFF,&lt;br /&gt;
  0xC0, 0x3F, 0x81, 0xFF, 0xF0, 0x00, 0x3B, 0xBE, 0x73, 0x78, 0x60, 0x78, 0x03, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0x00, 0x81, 0xFF, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xE0, 0x7F, 0x9F, 0xFF, 0xF0, 0x00, 0x31,&lt;br /&gt;
  0x87, 0x73, 0x70, 0x60, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x07,&lt;br /&gt;
  0xFF, 0xFF, 0xF0, 0x7F, 0xFF, 0xFF, 0xF0, 0x0F, 0x3B, 0x8F, 0x33, 0x3E, 0x40, 0x0F, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x07, 0xF8, 0x7F, 0xF0, 0x7F, 0xFF, 0xFF, 0xF8,&lt;br /&gt;
  0x0D, 0x9F, 0x1B, 0x3F, 0x18, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0x00,&lt;br /&gt;
  0x00, 0x07, 0xE0, 0x3F, 0xF0, 0xFF, 0xFF, 0xFF, 0xF8, 0x19, 0x9C, 0x3B, 0x3E, 0x00, 0x7F, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x00, 0xC0, 0x1F, 0xF8, 0x7F, 0xFF,&lt;br /&gt;
  0xFF, 0xF0, 0x1F, 0x98, 0x1F, 0x30, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,&lt;br /&gt;
  0xFF, 0x80, 0x00, 0x00, 0x00, 0x0F, 0xF8, 0x7F, 0xFF, 0xFF, 0x80, 0x1C, 0x18, 0x00, 0x33, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x0F, 0xF8,&lt;br /&gt;
  0x7F, 0xFF, 0xFF, 0x80, 0x0F, 0x98, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0x00, 0x00, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x0F, 0xF8, 0x7F, 0xC0, 0x7F, 0x80, 0x07, 0x00, 0x1F,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x80, 0x00, 0x00, 0x00,&lt;br /&gt;
  0x0F, 0xF8, 0x78, 0x00, 0x7F, 0xC0, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0x7F, 0xC0, 0x00,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x7F, 0xC0, 0x00,&lt;br /&gt;
  0x00, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0x7F, 0xC0, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x00, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0x3F,&lt;br /&gt;
  0xC7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x7F,&lt;br /&gt;
  0xC0, 0x00, 0x01, 0x80, 0x1F, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x03, 0xE0, 0x7F, 0xF0, 0x00,&lt;br /&gt;
  0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,&lt;br /&gt;
  0x00, 0x7F, 0xC0, 0x00, 0x03, 0xFF, 0xFF, 0xE0, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x07, 0xFF, 0xFF,&lt;br /&gt;
  0xE0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0x00, 0x00, 0x3F, 0xE0, 0x00, 0x07, 0xFF, 0xFF, 0xC0, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0xE0, 0x00, 0x07,&lt;br /&gt;
  0xFF, 0xFF, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0xE7, 0xC1, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0xFF,&lt;br /&gt;
  0xC3, 0xC1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0xFF, 0xC3, 0xE0, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x0F,&lt;br /&gt;
  0xFF, 0xFF, 0xC3, 0xE1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0x00, 0x1F, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x7F, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFE, 0x7F, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xEF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xC1, 0xFF, 0xFF, 0xFE, 0x7F, 0xF7, 0x3F, 0xFF, 0xFF,&lt;br /&gt;
  0xF1, 0xE3, 0xE7, 0xF2, 0x39, 0x3F, 0xFF, 0xC7, 0x8F, 0x9F, 0xCC, 0xE7, 0x7F, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xC0, 0xFF, 0xFF, 0xFE, 0x7F, 0xE7, 0xFF, 0xFF, 0xFF, 0xC0, 0xC1, 0xC3, 0xF3, 0x39, 0xBC, 0xF3,&lt;br /&gt;
  0x03, 0x07, 0x0F, 0xCC, 0xE7, 0x3F, 0xFF, 0xFF, 0xFF, 0xCE, 0x61, 0xC3, 0x8E, 0x66, 0x41, 0x38,&lt;br /&gt;
  0x70, 0x73, 0xFC, 0xCC, 0x99, 0xF7, 0x33, 0xBE, 0x67, 0xF3, 0x32, 0x67, 0xDC, 0xE7, 0x3F, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xCC, 0x40, 0x83, 0x06, 0x66, 0x41, 0x30, 0x30, 0x33, 0xFC, 0xCC, 0x99, 0xF7, 0x33,&lt;br /&gt;
  0x9F, 0x0F, 0xF3, 0x32, 0x67, 0xDC, 0x67, 0xBF, 0xFF, 0xFF, 0xFF, 0xC0, 0xCC, 0x8E, 0x62, 0x66,&lt;br /&gt;
  0x67, 0x33, 0x33, 0x33, 0xF8, 0xCC, 0x99, 0xE7, 0x13, 0x9F, 0x9F, 0xE3, 0x32, 0x67, 0x9C, 0x07,&lt;br /&gt;
  0xBF, 0xFF, 0xFF, 0xFF, 0xC1, 0xC0, 0xC2, 0x72, 0x66, 0x67, 0x33, 0x33, 0x3F, 0xF9, 0xCC, 0x99,&lt;br /&gt;
  0xE7, 0x97, 0x9F, 0x0F, 0xE7, 0x32, 0x67, 0x9C, 0x67, 0xBF, 0xFF, 0xFF, 0xFF, 0xCC, 0xCF, 0xF2,&lt;br /&gt;
  0x62, 0x66, 0x67, 0x33, 0x33, 0x3F, 0xF3, 0xCC, 0x99, 0xF7, 0x87, 0x9E, 0x67, 0xCF, 0x32, 0x67,&lt;br /&gt;
  0xDC, 0xE7, 0xBF, 0xFF, 0xFF, 0xFF, 0xCC, 0xC5, 0x93, 0x06, 0x20, 0x63, 0x30, 0x33, 0x33, 0xE0,&lt;br /&gt;
  0xC1, 0x81, 0xF7, 0x87, 0x9C, 0xF3, 0x83, 0x06, 0x07, 0xDC, 0xE7, 0x3F, 0xFF, 0xFF, 0xFF, 0xCE,&lt;br /&gt;
  0x61, 0x87, 0x0F, 0x30, 0x71, 0x38, 0x73, 0x33, 0xC0, 0xE1, 0xC3, 0xF3, 0xC7, 0xBF, 0xFF, 0x03,&lt;br /&gt;
  0x8F, 0x0F, 0xCC, 0xE7, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xF3, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xFF, 0x3F, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xFF, 0x7F,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0xFE, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0x8F, 0xCE, 0x0E, 0x7F, 0xFC,&lt;br /&gt;
  0x18, 0x3E, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFE, 0x7F, 0xFF, 0xFF, 0x07, 0x86, 0x07, 0xFF, 0xFC, 0x18, 0x1C, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xE1, 0xD1, 0x91, 0xC3, 0xC4, 0x18, 0x74, 0xDF, 0xE7, 0x86, 0x62,&lt;br /&gt;
  0x60, 0xFC, 0xF9, 0x98, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xC0, 0xC0,&lt;br /&gt;
  0x81, 0xC1, 0x84, 0x10, 0x60, 0x8F, 0xE7, 0x26, 0x62, 0x60, 0x7C, 0xF9, 0x99, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xCC, 0xCC, 0x88, 0x99, 0x1E, 0x73, 0x23, 0xDF, 0xE6,&lt;br /&gt;
  0x66, 0x06, 0x66, 0x7C, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF,&lt;br /&gt;
  0xCC, 0xCC, 0x8C, 0x81, 0x3E, 0x63, 0x23, 0xFF, 0xCE, 0x06, 0x0E, 0x66, 0x7C, 0x38, 0x39, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xCC, 0xCC, 0x8C, 0x9F, 0x3E, 0x73, 0x23,&lt;br /&gt;
  0xFF, 0x8E, 0x06, 0x7E, 0x66, 0x7C, 0xF9, 0xF9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xC0, 0xC0, 0xCC, 0x8C, 0x8B, 0x86, 0x30, 0x23, 0x8F, 0x03, 0xE6, 0x7E, 0x66, 0x7C, 0xF9,&lt;br /&gt;
  0xFC, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xE1, 0xCC, 0x8C, 0xC3, 0x87,&lt;br /&gt;
  0x18, 0x63, 0x9F, 0x03, 0xE6, 0x7E, 0x66, 0x7C, 0xF9, 0xFE, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xCF, 0xFF, 0xFE, 0x7C, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xFF, 0xFC, 0x7C,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF,&lt;br /&gt;
  0xE9, 0x0E, 0x66, 0x1C, 0x61, 0xCE, 0x1D, 0xF8, 0x7C, 0xE1, 0x99, 0xC7, 0x30, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xE1, 0x06, 0x64, 0x18, 0x60, 0xCC, 0x18,&lt;br /&gt;
  0xF8, 0x7C, 0xC0, 0x99, 0x83, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xCC, 0x67, 0xE6, 0x64, 0x71, 0xFC, 0xCC, 0xCD, 0xF2, 0x7C, 0xCC, 0x99, 0x33, 0x23, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCC, 0x67, 0x07, 0x0E, 0x13, 0xE0,&lt;br /&gt;
  0xCC, 0x0F, 0xF0, 0x3C, 0xC0, 0xCB, 0x03, 0x30, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xCE, 0x67, 0x27, 0x0F, 0x93, 0xE4, 0xCC, 0xFF, 0xF0, 0x3C, 0xCF, 0xC3, 0x3F,&lt;br /&gt;
  0x3C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x67, 0x07, 0x9C,&lt;br /&gt;
  0x98, 0x60, 0xC4, 0x58, 0xFE, 0x7C, 0x45, 0xC3, 0x17, 0x24, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xE7, 0x07, 0x9C, 0x38, 0x60, 0xE6, 0x19, 0xFE, 0x7E, 0x61,&lt;br /&gt;
  0xE7, 0x83, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFE, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xFE, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0x87, 0x07, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xCF, 0xFC, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0x07, 0x03, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCC, 0x98, 0x30, 0xC8, 0x18, 0x78,&lt;br /&gt;
  0xE3, 0x9F, 0x3F, 0x33, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xCC, 0x08, 0x20, 0xC0, 0x18, 0x30, 0xC1, 0x9F, 0x1F, 0x33, 0x3F, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCC, 0xCC, 0xE6, 0x47,&lt;br /&gt;
  0x3E, 0x23, 0x89, 0x9F, 0x07, 0x03, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCC, 0xCC, 0xE0, 0x4F, 0x38, 0x27, 0x81, 0xFF, 0xE3, 0x07, 0x3F,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCC, 0xCC,&lt;br /&gt;
  0xE7, 0xCF, 0x33, 0x23, 0x8F, 0xFF, 0xF3, 0x3F, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCC, 0xCC, 0x62, 0xCF, 0x30, 0x30, 0xC1, 0x9F, 0x03,&lt;br /&gt;
  0x3F, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xCC, 0xCE, 0x30, 0xCF, 0x38, 0x30, 0xE1, 0x9F, 0x07, 0x3F, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,&lt;br /&gt;
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [Code 2 Display a clock] ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 An example digital clock using a TFT LCD screen to show the time.&lt;br /&gt;
 Demonstrates use of the font printing routines. (Time updates but date does not.)&lt;br /&gt;
 &lt;br /&gt;
 For a more accurate clock, it would be better to use the RTClib library.&lt;br /&gt;
 But this is just a demo. &lt;br /&gt;
 &lt;br /&gt;
 This examples uses the hardware SPI only. Non-hardware SPI&lt;br /&gt;
 is just too slow (~8 times slower!)&lt;br /&gt;
 &lt;br /&gt;
 Based on clock sketch by Gilchrist 6/2/2014 1.0&lt;br /&gt;
 Updated by Bodmer&lt;br /&gt;
A few colour codes:&lt;br /&gt;
 &lt;br /&gt;
code	color&lt;br /&gt;
0x0000	Black&lt;br /&gt;
0xFFFF	White&lt;br /&gt;
0xBDF7	Light Gray&lt;br /&gt;
0x7BEF	Dark Gray&lt;br /&gt;
0xF800	Red&lt;br /&gt;
0xFFE0	Yellow&lt;br /&gt;
0xFBE0	Orange&lt;br /&gt;
0x79E0	Brown&lt;br /&gt;
0x7E0	Green&lt;br /&gt;
0x7FF	Cyan&lt;br /&gt;
0x1F	Blue&lt;br /&gt;
0xF81F	Pink&lt;br /&gt;
&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;lt;TFT_eSPI.h&amp;gt; // Graphics and font library for ST7735 driver chip&lt;br /&gt;
#include &amp;lt;SPI.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#ifdef EPAPER_ENABLE // Only compile this code if the EPAPER_ENABLE is defined in User_Setup.h&lt;br /&gt;
&lt;br /&gt;
EPaper epaper = EPaper();  // Invoke library, pins defined in User_Setup.h&lt;br /&gt;
&lt;br /&gt;
uint32_t targetTime = 0;       // for next 1 second timeout&lt;br /&gt;
&lt;br /&gt;
byte omm = 99;&lt;br /&gt;
bool initial = 1;&lt;br /&gt;
byte xcolon = 0;&lt;br /&gt;
unsigned int colour = 0;&lt;br /&gt;
&lt;br /&gt;
static uint8_t conv2d(const char* p) {&lt;br /&gt;
  uint8_t v = 0;&lt;br /&gt;
  if (&amp;#039;0&amp;#039; &amp;lt;= *p &amp;amp;&amp;amp; *p &amp;lt;= &amp;#039;9&amp;#039;)&lt;br /&gt;
    v = *p - &amp;#039;0&amp;#039;;&lt;br /&gt;
  return 10 * v + *++p - &amp;#039;0&amp;#039;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
uint8_t hh=conv2d(__TIME__), mm=conv2d(__TIME__+3), ss=conv2d(__TIME__+6);  // Get H, M, S from compile time&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
void setup(void) {&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
  epaper.begin();&lt;br /&gt;
  epaper.setRotation(1);&lt;br /&gt;
  epaper.fillScreen(TFT_BLACK);&lt;br /&gt;
&lt;br /&gt;
  epaper.setTextColor(TFT_YELLOW, TFT_BLACK); // Note: the new fonts do not draw the background colour&lt;br /&gt;
  epaper.update(); // update the display&lt;br /&gt;
  targetTime = millis() + 1000; &lt;br /&gt;
#endif&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
  if (targetTime &amp;lt; millis()) {&lt;br /&gt;
    targetTime = millis()+1000;&lt;br /&gt;
    ss++;              // Advance second&lt;br /&gt;
    if (ss==60) {&lt;br /&gt;
      ss=0;&lt;br /&gt;
      omm = mm;&lt;br /&gt;
      mm++;            // Advance minute&lt;br /&gt;
      if(mm&amp;gt;59) {&lt;br /&gt;
        mm=0;&lt;br /&gt;
        hh++;          // Advance hour&lt;br /&gt;
        if (hh&amp;gt;23) {&lt;br /&gt;
          hh=0;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (ss==0 || initial) {&lt;br /&gt;
      initial = 0;&lt;br /&gt;
      epaper.setTextColor(TFT_GREEN, TFT_BLACK);&lt;br /&gt;
      epaper.setCursor (8, 52);&lt;br /&gt;
      epaper.print(__DATE__); // This uses the standard ADAFruit small font&lt;br /&gt;
&lt;br /&gt;
      epaper.setTextColor(TFT_BLUE, TFT_BLACK);&lt;br /&gt;
      epaper.drawCentreString(&amp;quot;It is windy&amp;quot;,120,48,2); // Next size up font 2&lt;br /&gt;
&lt;br /&gt;
      //epaper.setTextColor(0xF81F, TFT_BLACK); // Pink&lt;br /&gt;
      //epaper.drawCentreString(&amp;quot;12.34&amp;quot;,80,100,6); // Large font 6 only contains characters [space] 0 1 2 3 4 5 6 7 8 9 . : a p m&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Update digital time&lt;br /&gt;
    byte xpos = 6;&lt;br /&gt;
    byte ypos = 0;&lt;br /&gt;
    if (omm != mm) { // Only redraw every minute to minimise flicker&lt;br /&gt;
      // Uncomment ONE of the next 2 lines, using the ghost image demonstrates text overlay as time is drawn over it&lt;br /&gt;
      epaper.setTextColor(TFT_BLACK, TFT_BLACK);  // Leave a 7 segment ghost image, comment out next line!&lt;br /&gt;
      //epaper.setTextColor(TFT_BLACK, TFT_BLACK); // Set font colour to black to wipe image&lt;br /&gt;
      // Font 7 is to show a pseudo 7 segment display.&lt;br /&gt;
      // Font 7 only contains characters [space] 0 1 2 3 4 5 6 7 8 9 0 : .&lt;br /&gt;
      epaper.drawString(&amp;quot;88:88&amp;quot;,xpos,ypos,7); // Overwrite the text to clear it&lt;br /&gt;
      epaper.setTextColor(0xFBE0); // Orange&lt;br /&gt;
      omm = mm;&lt;br /&gt;
&lt;br /&gt;
      if (hh&amp;lt;10) xpos+= epaper.drawChar(&amp;#039;0&amp;#039;,xpos,ypos,7);&lt;br /&gt;
      xpos+= epaper.drawNumber(hh,xpos,ypos,7);&lt;br /&gt;
      xcolon=xpos;&lt;br /&gt;
      xpos+= epaper.drawChar(&amp;#039;:&amp;#039;,xpos,ypos,7);&lt;br /&gt;
      if (mm&amp;lt;10) xpos+= epaper.drawChar(&amp;#039;0&amp;#039;,xpos,ypos,7);&lt;br /&gt;
      epaper.drawNumber(mm,xpos,ypos,7);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (ss%2) { // Flash the colon&lt;br /&gt;
      epaper.setTextColor(TFT_BLACK, TFT_BLACK);&lt;br /&gt;
      xpos+= epaper.drawChar(&amp;#039;:&amp;#039;,xcolon,ypos,7);&lt;br /&gt;
      epaper.setTextColor(0xFBE0, TFT_BLACK);&lt;br /&gt;
    }&lt;br /&gt;
    else {&lt;br /&gt;
      epaper.drawChar(&amp;#039;:&amp;#039;,xcolon,ypos,7);&lt;br /&gt;
      colour = random(0xFFFF);&lt;br /&gt;
      // Erase the old text with a rectangle, the disadvantage of this method is increased display flicker&lt;br /&gt;
      epaper.fillRect (0, 64, 160, 20, TFT_BLACK);&lt;br /&gt;
      epaper.setTextColor(TFT_WHITE);&lt;br /&gt;
    }&lt;br /&gt;
    epaper.update(); // update the display&lt;br /&gt;
  }&lt;br /&gt;
#endif&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;onglet driver.h&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// driver.h file &lt;br /&gt;
#define BOARD_SCREEN_COMBO 505 // 1.54 inch monochrome ePaper Screen （SSD1681）&lt;br /&gt;
#define USE_XIAO_EPAPER_BREAKOUT_BOARD&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [Code 2 Display a clock - WIFI] ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;TFT_eSPI.h&amp;gt;   // Librairie pour ton écran E-paper&lt;br /&gt;
#include &amp;lt;SPI.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
EPaper epaper = EPaper();  // Pins définis dans User_Setup.h&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// ⚙️ Paramètres WiFi&lt;br /&gt;
const char* ssid     = &amp;quot;TON_SSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TON_MOTDEPASSE&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ⚙️ Paramètres NTP&lt;br /&gt;
const char* ntpServer = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const long  gmtOffset_sec = 3600;       // Décalage GMT (ex: +1h pour Suisse en hiver)&lt;br /&gt;
const int   daylightOffset_sec = 3600;  // Décalage été (DST)&lt;br /&gt;
&lt;br /&gt;
// Variables pour éviter scintillement&lt;br /&gt;
int lastMinute = -1;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
  epaper.begin();&lt;br /&gt;
  epaper.setRotation(1);&lt;br /&gt;
  epaper.fillScreen(TFT_BLACK);&lt;br /&gt;
  epaper.setTextColor(TFT_WHITE, TFT_BLACK);&lt;br /&gt;
  epaper.update();&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Initialisation NTP&lt;br /&gt;
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  // Récupérer l’heure système&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    return; // Si pas d’heure dispo&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Rafraîchir uniquement si la minute change&lt;br /&gt;
  if (timeinfo.tm_min != lastMinute) {&lt;br /&gt;
    lastMinute = timeinfo.tm_min;&lt;br /&gt;
&lt;br /&gt;
#ifdef EPAPER_ENABLE&lt;br /&gt;
    epaper.fillScreen(TFT_BLACK);&lt;br /&gt;
&lt;br /&gt;
    // Afficher la date&lt;br /&gt;
    epaper.setTextColor(TFT_GREEN, TFT_BLACK);&lt;br /&gt;
    epaper.setCursor(10, 20);&lt;br /&gt;
    epaper.printf(&amp;quot;%02d/%02d/%04d&amp;quot;, timeinfo.tm_mday, timeinfo.tm_mon+1, timeinfo.tm_year+1900);&lt;br /&gt;
&lt;br /&gt;
    // Afficher l’heure&lt;br /&gt;
    epaper.setTextColor(TFT_ORANGE, TFT_BLACK);&lt;br /&gt;
    epaper.setCursor(10, 60);&lt;br /&gt;
    epaper.printf(&amp;quot;%02d:%02d&amp;quot;, timeinfo.tm_hour, timeinfo.tm_min);&lt;br /&gt;
&lt;br /&gt;
    epaper.update(); // Mise à jour écran&lt;br /&gt;
#endif&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  delay(1000); // Boucle chaque seconde mais rafraîchit seulement à chaque minute&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>144.2.107.134</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1954</id>
		<title>CrowPanel-ESP32-E-Paper-HMI-1.54</title>
		<link rel="alternate" type="text/html" href="https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1954"/>
		<updated>2025-12-01T23:21:25Z</updated>

		<summary type="html">&lt;p&gt;144.2.107.134: /* Code Exemples */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== E-Paper-HMI-1.54 (Elecrow) ==&lt;br /&gt;
&lt;br /&gt;
=== Liens externes ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_HMI_1.54-inch_Display.html Wiki&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_1.54-inch_Arduino_Tutorial.html Arduino Setup&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/crowpanel-esp32-1-54-e-paper-hmi-display-with-152-152-resolution-black-white-color-driven-by-spi-interface.html Shop&lt;br /&gt;
&lt;br /&gt;
 BLE debugging assistant&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/1-54-inch-152-152-e-paper-display-black-white-e-ink-display-with-spi-communication.html&lt;br /&gt;
&lt;br /&gt;
=== Caractéristiques ===&lt;br /&gt;
&lt;br /&gt;
Model: DIE09154S&amp;lt;br&amp;gt;&lt;br /&gt;
Driver Chip : &amp;lt;b&amp;gt;SSD1680&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Résolution 152*152&amp;lt;br&amp;gt;&lt;br /&gt;
Couleur noir et blanc&amp;lt;br&amp;gt;&lt;br /&gt;
Pilote ESP32-S3 comme contrôleur principal&amp;lt;br&amp;gt;&lt;br /&gt;
PSRAM : 8MB&amp;lt;br&amp;gt;&lt;br /&gt;
Flash :	8MB&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Images ===&lt;br /&gt;
[[File:E-Paper-HMI-1.54-1.png|300px]]&lt;br /&gt;
&lt;br /&gt;
[[File:E-Paper-HMI-1.54-2.png|300px]]&lt;br /&gt;
[[File:E-Paper-HMI-1.54-3.png|300px]]&lt;br /&gt;
&lt;br /&gt;
=== Ressources ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/download/product/CrowPanel/E-paper/Image2Lcd_v2.9.zip Image2Lcd_v2.9&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152 GitHub&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152/archive/refs/heads/master.zip GitHub ZIP&lt;br /&gt;
&lt;br /&gt;
=== Arduine Mise en route (Setup) ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. Téléchargez les fichiers de bibliothèque utilisés par ce produit dans le dossier « bibliothèques ».&lt;br /&gt;
&lt;br /&gt;
C:\Users\Documents\Arduino\libraries\&lt;br /&gt;
&lt;br /&gt;
[[File:CrowPanel-ESP32-Setup-Arduino-1.png|600px]]&lt;br /&gt;
&lt;br /&gt;
CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152-master/example/arduino/libraries/ &amp;lt;b&amp;gt;Voir sur GitHub&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Ouvrez l&amp;#039;IDE Arduino&amp;lt;br&amp;gt;&lt;br /&gt;
chercher &amp;lt;b&amp;gt;ESP32&amp;lt;/b&amp;gt; dans Boards Manager, installez si cela n&amp;#039;est pas déjà fait &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;by Espressif Systems&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:CrowPanel-ESP32-Setup-Arduino-2.jpg|400px]]&lt;br /&gt;
&lt;br /&gt;
3. Click &amp;quot;Tools&amp;quot;-&amp;gt;&amp;quot;Board&amp;quot;-&amp;gt;&amp;quot;esp32&amp;quot;-&amp;gt;&amp;quot;&amp;lt;b&amp;gt;ESP32S3 Dev Module&amp;lt;/b&amp;gt;&amp;quot;, &lt;br /&gt;
&lt;br /&gt;
and the &amp;quot;Partition Scheme&amp;quot; select &lt;br /&gt;
&amp;quot;Huge APP (3MB No OTA/1MB SPIFFS)&amp;quot;, &lt;br /&gt;
&amp;quot;PSRAM&amp;quot; select &amp;quot;OPI PSRAM&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[File:Setup-Arduino-1.png|300px]]&lt;br /&gt;
&lt;br /&gt;
=== Librairies ===&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;Arduino.h&amp;gt;   // Inclure la bibliothèque principale Arduino&lt;br /&gt;
 #include &amp;quot;EPD_GUI.h&amp;quot;   // Inclure la bibliothèque pour l&amp;#039;écran à encre électronique&lt;br /&gt;
 #include &amp;quot;Pic.h&amp;quot;       // Inclure la bibliothèque de fonctions personnalisées&lt;br /&gt;
 #include &amp;quot;FS.h&amp;quot;        // Bibliothèque du système de fichiers pour les opérations sur les fichiers&lt;br /&gt;
 #include &amp;quot;SPIFFS.h&amp;quot;    // Bibliothèque du système de fichiers SPIFFS pour la lecture et l&amp;#039;écriture de fichiers&lt;br /&gt;
 #include &amp;lt;WiFi.h&amp;gt;      // Bibliothèque WiFi pour la création et la gestion des connexions WiFi&lt;br /&gt;
 #include &amp;lt;Ticker.h&amp;gt;    // Bibliothèque de chronométrage&lt;br /&gt;
 #include &amp;lt;WebServer.h&amp;gt; // Bibliothèque de serveur Web pour la création d&amp;#039;un serveur HTTP&lt;br /&gt;
&lt;br /&gt;
=== Code Exemples ===&lt;br /&gt;
&lt;br /&gt;
Arduino Code for demos&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_WIFI_refresh.ino &amp;lt;b&amp;gt;Update via WiFi&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_ble_refresh.ino  &amp;lt;b&amp;gt;Update via Bluetooth&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_wifi_http_openweather.ino&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arduino Code for examples&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_PWR.ino&amp;lt;br&amp;gt;&lt;br /&gt;
[[1.54_wifi.ino| 1.54_wifi.ino]]&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_BLE.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_key.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_Global_refresh.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_partial_refresh.ino&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[epd1in54bV2-demo.ino| epd1in54bV2-demo.ino]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get Started with Crowpanel E-Paper Screen:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=smDFHRxDYdw&amp;lt;br&amp;gt;&lt;br /&gt;
Lesson 01 - A Comprehensive Introduction&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=-9DeXQIjOc0&amp;lt;br&amp;gt;&lt;br /&gt;
Lesson 02 - Display Images&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=7PN9q9b3nKk&amp;lt;br&amp;gt;&lt;br /&gt;
Lesson 03 - Display Text&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=x70f8aAUQBk&amp;lt;br&amp;gt;&lt;br /&gt;
Lesson 04 - Transmit Images via Bluetooth&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=vzq8-aMmTOQ&amp;lt;br&amp;gt;&lt;br /&gt;
Lesson 05 - Transmit Images via WiFi&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=Nb-hP7yaf7Q&amp;lt;br&amp;gt;&lt;br /&gt;
Lesson 06 - Setting Up the Calendar Desktop&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Code wifi_http_openweather ===&lt;br /&gt;
&lt;br /&gt;
https://openweathermap.org/ Veuillez vous enregistrer afin de vous procurer votre OpenWeatherMap API key&lt;br /&gt;
&lt;br /&gt;
http://bulk.openweathermap.org/sample/ on trouve ici : &amp;lt;b&amp;gt;city.list.json.gz&amp;lt;/b&amp;gt;, le countryCode de votre ville (variable city)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;lt;HTTPClient.h&amp;gt;&lt;br /&gt;
#include &amp;lt;Arduino_JSON.h&amp;gt;&lt;br /&gt;
#include &amp;quot;EPD_GUI.h&amp;quot;&lt;br /&gt;
#include &amp;quot;Pic.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
// Define an array for black and white image data, which serves as the buffer for the e-paper display.&lt;br /&gt;
// The size of the buffer is determined according to the resolution of the e-paper display.&lt;br /&gt;
uint8_t ImageBW[2888];&lt;br /&gt;
&lt;br /&gt;
// WiFi network name // WiFi password&lt;br /&gt;
const char* ssid = &amp;quot;yanfa_software&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;yanfa-123456&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// OpenWeatherMap API key. This key is used to access weather data from the OpenWeatherMap API.&lt;br /&gt;
String openWeatherMapApiKey = &amp;quot;3c03d1f4e2dd3e14474a9a3a2f2299ff&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// City and country code for which weather data will be fetched.&lt;br /&gt;
String city = &amp;quot;London&amp;quot;;&lt;br /&gt;
String countryCode = &amp;quot;2643743&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Variables related to timing and API calls.&lt;br /&gt;
// lastTime keeps track of the last time the API was called.&lt;br /&gt;
unsigned long lastTime = 0;&lt;br /&gt;
// timerDelay determines the time interval between API calls. For testing, it&amp;#039;s set to 10 seconds (10000 milliseconds).&lt;br /&gt;
// In a final application, this should be set according to the API call limits per hour/minute.&lt;br /&gt;
unsigned long timerDelay = 10000;&lt;br /&gt;
&lt;br /&gt;
// Variables related to JSON data.&lt;br /&gt;
// jsonBuffer stores the raw JSON data received from the API.&lt;br /&gt;
String jsonBuffer;&lt;br /&gt;
// httpResponseCode holds the response code from the HTTP request.&lt;br /&gt;
int httpResponseCode;&lt;br /&gt;
// myObject is a JSON variable that will hold the parsed JSON data.&lt;br /&gt;
JSONVar myObject;&lt;br /&gt;
&lt;br /&gt;
// Variables related to weather information.&lt;br /&gt;
// weather stores the main weather description.&lt;br /&gt;
String weather;&lt;br /&gt;
// temperature stores the temperature value.&lt;br /&gt;
String temperature;&lt;br /&gt;
// humidity stores the humidity value.&lt;br /&gt;
String humidity;&lt;br /&gt;
// sea_level stores the sea level value.&lt;br /&gt;
String sea_level;&lt;br /&gt;
// wind_speed stores the wind speed value.&lt;br /&gt;
String wind_speed;&lt;br /&gt;
// city_js stores the name of the city.&lt;br /&gt;
String city_js;&lt;br /&gt;
// weather_flag is a flag that determines which weather icon to display based on the weather description.&lt;br /&gt;
int weather_flag = 0;&lt;br /&gt;
&lt;br /&gt;
// Function to display weather forecast on the e-paper display.&lt;br /&gt;
void UI_weather_forecast()&lt;br /&gt;
{&lt;br /&gt;
  char buffer[40];&lt;br /&gt;
&lt;br /&gt;
  EPD_HW_RESET();&lt;br /&gt;
&lt;br /&gt;
  // Display a background picture on the e-paper.&lt;br /&gt;
  EPD_ShowPicture(0, 0, 152, 152, pic, BLACK);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  //If you need to replace the display options,&lt;br /&gt;
  //open the following options: temp, wind, visit, hum&lt;br /&gt;
  //The following uses the hum option as an example&lt;br /&gt;
&lt;br /&gt;
  //Visit&lt;br /&gt;
  //EPD_ShowPicture(76, 92, 56, 72, gImage_visit, BLACK);&lt;br /&gt;
  //Wind&lt;br /&gt;
  //EPD_ShowPicture(76, 92, 56, 72, gImage_wind, BLACK);&lt;br /&gt;
  //Temp&lt;br /&gt;
  //  EPD_ShowPicture(92, 0, 56, 72, gImage_temp, BLACK);&lt;br /&gt;
  //Hum&lt;br /&gt;
&lt;br /&gt;
  EPD_Display(ImageBW);&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_DeepSleep();&lt;br /&gt;
&lt;br /&gt;
  EPD_GPIOInit();&lt;br /&gt;
  Paint_NewImage(ImageBW, EPD_W, EPD_H, 270, WHITE);&lt;br /&gt;
  // Paint_Clear(WHITE);&lt;br /&gt;
  EPD_FastMode1Init();&lt;br /&gt;
  // EPD_Display_Clear();&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_Clear_R26H();&lt;br /&gt;
&lt;br /&gt;
  // Display the update time (it seems to be mislabeled as city_js here, might need to be corrected depending on the actual intention).&lt;br /&gt;
  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, city_js);&lt;br /&gt;
  EPD_ShowString(20, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //If you need to replace the display options,&lt;br /&gt;
  //open the following options: temp, wind, visit, hum&lt;br /&gt;
  //The following uses the hum option as an example&lt;br /&gt;
&lt;br /&gt;
  //Hum&lt;br /&gt;
  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, humidity);&lt;br /&gt;
  EPD_ShowString(105, 140, buffer,  12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //Temp&lt;br /&gt;
  //       memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  //       snprintf(buffer, sizeof(buffer), &amp;quot;%s C&amp;quot;, temperature);&lt;br /&gt;
  //       EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //Wind&lt;br /&gt;
  // memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  // snprintf(buffer, sizeof(buffer), &amp;quot;%s m/s&amp;quot;, wind_speed);&lt;br /&gt;
  // EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //visit&lt;br /&gt;
  //  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  //  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, sea_level);&lt;br /&gt;
  //  EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  // Update the e-paper display with the new content.&lt;br /&gt;
  EPD_Display(ImageBW);&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_DeepSleep();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200); // Initialize the serial communication.&lt;br /&gt;
&lt;br /&gt;
  // Connect to the WiFi network.&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  Serial.println(&amp;quot;Connecting&amp;quot;);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot;&amp;quot;);&lt;br /&gt;
  Serial.print(&amp;quot;Connected to WiFi network with IP Address: &amp;quot;);&lt;br /&gt;
  Serial.println(WiFi.localIP()); // Print the IP address of the device after successful connection.&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Timer set to 10 seconds (timerDelay variable), it will take 10 seconds before publishing the first reading.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Set pin 7 as an output pin to control the power of the e-paper display.&lt;br /&gt;
  pinMode(7, OUTPUT);&lt;br /&gt;
  digitalWrite(7, HIGH);&lt;br /&gt;
&lt;br /&gt;
  EPD_GPIOInit();&lt;br /&gt;
  Paint_NewImage(ImageBW, EPD_W, EPD_H, 0, WHITE);&lt;br /&gt;
  Paint_Clear(WHITE);&lt;br /&gt;
  EPD_FastMode1Init();&lt;br /&gt;
  EPD_Display_Clear();&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_Clear_R26H();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  js_analysis();&lt;br /&gt;
  UI_weather_forecast();&lt;br /&gt;
  delay(1000 * 60 * 60);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void js_analysis()&lt;br /&gt;
{&lt;br /&gt;
  // Check if the device is connected to the WiFi network.&lt;br /&gt;
  if (WiFi.status() == WL_CONNECTED) {&lt;br /&gt;
    // Construct the URL for the OpenWeatherMap API request.&lt;br /&gt;
    String serverPath = &amp;quot;http://api.openweathermap.org/data/2.5/weather?q=&amp;quot; + city + &amp;quot;,&amp;quot; + countryCode + &amp;quot;&amp;amp;APPID=&amp;quot; + openWeatherMapApiKey + &amp;quot;&amp;amp;units=metric&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    // Keep trying until a successful response (status code 200) is received.&lt;br /&gt;
    while (httpResponseCode != 200) {&lt;br /&gt;
      // Make an HTTP GET request to the API and store the response in jsonBuffer.&lt;br /&gt;
      jsonBuffer = httpGETRequest(serverPath.c_str());&lt;br /&gt;
      Serial.println(jsonBuffer);&lt;br /&gt;
      myObject = JSON.parse(jsonBuffer);&lt;br /&gt;
&lt;br /&gt;
      // Check if the JSON parsing was successful.&lt;br /&gt;
      if (JSON.typeof(myObject) == &amp;quot;undefined&amp;quot;) {&lt;br /&gt;
        Serial.println(&amp;quot;Parsing input failed!&amp;quot;);&lt;br /&gt;
        return;&lt;br /&gt;
      }&lt;br /&gt;
      delay(2000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Extract weather information from the parsed JSON data.&lt;br /&gt;
    weather = JSON.stringify(myObject[&amp;quot;weather&amp;quot;][0][&amp;quot;main&amp;quot;]);&lt;br /&gt;
    temperature = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;temp&amp;quot;]);&lt;br /&gt;
    humidity = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;humidity&amp;quot;]);&lt;br /&gt;
    sea_level = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;sea_level&amp;quot;]);&lt;br /&gt;
    wind_speed = JSON.stringify(myObject[&amp;quot;wind&amp;quot;][&amp;quot;speed&amp;quot;]);&lt;br /&gt;
    city_js = JSON.stringify(myObject[&amp;quot;name&amp;quot;]);&lt;br /&gt;
&lt;br /&gt;
    // Print the extracted weather information for debugging purposes.&lt;br /&gt;
    Serial.print(&amp;quot;String weather: &amp;quot;);&lt;br /&gt;
    Serial.println(weather);&lt;br /&gt;
    Serial.print(&amp;quot;String Temperature: &amp;quot;);&lt;br /&gt;
    Serial.println(temperature);&lt;br /&gt;
    Serial.print(&amp;quot;String humidity: &amp;quot;);&lt;br /&gt;
    Serial.println(humidity);&lt;br /&gt;
    Serial.print(&amp;quot;String sea_level: &amp;quot;);&lt;br /&gt;
    Serial.println(sea_level);&lt;br /&gt;
    Serial.print(&amp;quot;String wind_speed: &amp;quot;);&lt;br /&gt;
    Serial.println(wind_speed);&lt;br /&gt;
    Serial.print(&amp;quot;String city_js: &amp;quot;);&lt;br /&gt;
    Serial.println(city_js);&lt;br /&gt;
&lt;br /&gt;
    // Determine the weather icon based on the weather description.&lt;br /&gt;
    if (weather.indexOf(&amp;quot;clouds&amp;quot;) != -1 || weather.indexOf(&amp;quot;Clouds&amp;quot;) != -1 ) {&lt;br /&gt;
      weather_flag = 1;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;clear sky&amp;quot;) != -1 || weather.indexOf(&amp;quot;Clear sky&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 3;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;rain&amp;quot;) != -1 || weather.indexOf(&amp;quot;Rain&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 5;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;thunderstorm&amp;quot;) != -1 || weather.indexOf(&amp;quot;Thunderstorm&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 2;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;snow&amp;quot;) != -1 || weather.indexOf(&amp;quot;Snow&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 4;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;mist&amp;quot;) != -1 || weather.indexOf(&amp;quot;Mist&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 0;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
    // Print a message if the device is not connected to the WiFi network.&lt;br /&gt;
    Serial.println(&amp;quot;WiFi Disconnected&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Function to make an HTTP GET request and return the response.&lt;br /&gt;
String httpGETRequest(const char* serverName) {&lt;br /&gt;
  WiFiClient client;&lt;br /&gt;
  HTTPClient http;&lt;br /&gt;
&lt;br /&gt;
  // Initialize the HTTP client with the server name.&lt;br /&gt;
  http.begin(client, serverName);&lt;br /&gt;
&lt;br /&gt;
  // Send an HTTP GET request.&lt;br /&gt;
  httpResponseCode = http.GET();&lt;br /&gt;
&lt;br /&gt;
  // Initialize the response payload as an empty JSON object.&lt;br /&gt;
  String payload = &amp;quot;{}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  // Check if the response code is positive (indicating a successful request).&lt;br /&gt;
  if (httpResponseCode &amp;gt; 0) {&lt;br /&gt;
    Serial.print(&amp;quot;HTTP Response code: &amp;quot;);&lt;br /&gt;
    Serial.println(httpResponseCode);&lt;br /&gt;
    payload = http.getString();&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
    Serial.print(&amp;quot;Error code: &amp;quot;);&lt;br /&gt;
    Serial.println(httpResponseCode);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Close the HTTP connection.&lt;br /&gt;
  http.end();&lt;br /&gt;
&lt;br /&gt;
  return payload;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 Explications : Partie à modifier avec vos données, ssid, password, openWeatherMapApiKey, city, countryCode&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// WiFi network name // WiFi password&lt;br /&gt;
&lt;br /&gt;
const char* ssid = &amp;quot;yanfa_software&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;yanfa-123456&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// OpenWeatherMap API key. This key is used to access weather data from the OpenWeatherMap API.&lt;br /&gt;
String openWeatherMapApiKey = &amp;quot;3c03d1f4e2dd3e14474a9a3a2f2299ff&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// City and country code for which weather data will be fetched.&lt;br /&gt;
String city = &amp;quot;London&amp;quot;;&lt;br /&gt;
String countryCode = &amp;quot;2643743&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Code HelloWord ===&lt;br /&gt;
&lt;br /&gt;
 Basé sur le code https://github.com/HalfSweetStudio/EPaperDrive/blob/main/examples/HelloWorld/HelloWorld.ino&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
	* @file HelloWorld.ino&lt;br /&gt;
	* @author HalfSweet (Email:HalfSweet@HalfSweet.cn or QQ:2522182733)&lt;br /&gt;
	* @brief Ce fichier est un exemple de programme permettant d&amp;#039;afficher «Hello World» sur un écran à encre électronique. &lt;br /&gt;
        * Il illustre uniquement la méthode la plus simple pour allumer l&amp;#039;écran. &lt;br /&gt;
        * Veuillez consulter la documentation pour connaître l&amp;#039;utilisation des différentes fonctions.&lt;br /&gt;
	* @version 0.1&lt;br /&gt;
	* @date 2022-01-30&lt;br /&gt;
	*&lt;br /&gt;
	* @copyright Copyright (c) 2022&lt;br /&gt;
	*&lt;br /&gt;
*/ &lt;br /&gt;
#include &amp;lt;Arduino.h&amp;gt;&lt;br /&gt;
#include &amp;lt;EPaperDrive.h&amp;gt;&lt;br /&gt;
// Inclure le système de fichiers à utiliser, par exemple:&lt;br /&gt;
#include &amp;lt;LittleFS.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define BAUD_SPEED 74880 // Débit en bauds pour le débogage du port série, modifiable selon les besoins&lt;br /&gt;
&lt;br /&gt;
#define CS 15&lt;br /&gt;
#define RST 2&lt;br /&gt;
#define DC 0&lt;br /&gt;
#define BUSY 4&lt;br /&gt;
#define CLK 14&lt;br /&gt;
#define DIN 13&lt;br /&gt;
&lt;br /&gt;
EPaperDrive EPD(0, CS, RST, DC, BUSY, CLK, DIN); //Instanciation de la bibliothèque de pilotes, utilisant ici le protocole SPI logiciel&lt;br /&gt;
&lt;br /&gt;
const uint8_t city_icon[24] = {&lt;br /&gt;
	/* 0X01,0X01,0X0C,0X00,0X0C,0X00, */&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X1C,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X77,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X41,&lt;br /&gt;
	0X80,&lt;br /&gt;
	0X9C,&lt;br /&gt;
	0X60,&lt;br /&gt;
	0XA2,&lt;br /&gt;
	0X30,&lt;br /&gt;
	0XA2,&lt;br /&gt;
	0X30,&lt;br /&gt;
	0X9C,&lt;br /&gt;
	0XC0,&lt;br /&gt;
	0X41,&lt;br /&gt;
	0X80,&lt;br /&gt;
	0X77,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X1C,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
	void setup()&lt;br /&gt;
	{&lt;br /&gt;
	Serial.begin(BAUD_SPEED);&lt;br /&gt;
	LittleFS.begin(); 			  // Veuillez initialiser manuellement le système de fichiers avant de passer le pointeur.&lt;br /&gt;
&lt;br /&gt;
	EPD.SetFS(&amp;amp;LittleFS); 			 // Définit le système de fichiers pour le stockage des polices. La valeur passée est le pointeur d&amp;#039;opération pour ce système de fichiers. &lt;br /&gt;
                                                 //Vous pouvez la modifier.&lt;br /&gt;
	EPD.EPD_Set_Model(HINKE0266A15A0); 	 // Définit le type d&amp;#039;écran. Consultez la documentation pour les modèles spécifiques.&lt;br /&gt;
	EPD.EPD_init_Full(); 			// Initialisation du rafraîchissement complet, en utilisant la forme d&amp;#039;onde de rafraîchissement complet.&lt;br /&gt;
	EPD.clearbuffer(); 		        // Efface le tampon (écran blanc).&lt;br /&gt;
	EPD.fontscale = 2; 			// Facteur d&amp;#039;échelle des polices (1 et 2 pris en charge, également applicable aux images. &lt;br /&gt;
                                                // N&amp;#039;oubliez pas de le remettre à 1 après utilisation).&lt;br /&gt;
	EPD.SetFont(FONT12); 		       // Sélectionne la police. Consultez la documentation pour connaître les polices prises en charge.&lt;br /&gt;
	EPD.DrawUTF(0, 0, &amp;quot;Hello&amp;quot;);            // Dessiner la chaîne&lt;br /&gt;
	EPD.DrawUTF(26, 0, &amp;quot;J&amp;#039;aime les écrans à encre électronique&amp;quot;); 	&lt;br /&gt;
                                               // Dessiner la chaîne&lt;br /&gt;
	EPD.fontscale = 1; 		       // Rétablir le facteur d&amp;#039;échelle de la police à 1&lt;br /&gt;
	EPD.DrawXbm_P(60, 0, 12, 12, (uint8_t *)city_icon); 			 // Dessiner l&amp;#039;image&lt;br /&gt;
&lt;br /&gt;
	Serial.printf(&amp;quot;Image tamponnée dessinée, prête pour un rafraîchissement complet\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_Dis_Full((uint8_t *)EPD.EPDbuffer, 1); // Transmettre l&amp;#039;image tamponnée à la puce de contrôle de l&amp;#039;écran pour un rafraîchissement complet&lt;br /&gt;
	EPD.deepsleep(); // Mettre l&amp;#039;écran en veille&lt;br /&gt;
	Serial.println(&amp;quot;Rafraîchissement complet terminé&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	delay(5000);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_init_Part(); // Initialiser la partie Actualisation&lt;br /&gt;
	EPD.clearbuffer();&lt;br /&gt;
	EPD.fontscale = 2;&lt;br /&gt;
	EPD.SetFont(FONT12); EPD.DrawUTF(0, 0, &amp;quot;Actualisation locale activée&amp;quot;);&lt;br /&gt;
	Serial.printf(&amp;quot;Actualisation locale en cours\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_Dis_Part(0, 23, 0, 199, (uint8_t *)EPD.EPDbuffer, 1); // Transfert de l&amp;#039;image du tampon vers la puce de contrôle d&amp;#039;écran pour l&amp;#039;actualisation locale sur le nouvel écran&lt;br /&gt;
	Serial.printf(&amp;quot;Actualisation locale terminée\n&amp;quot;);&lt;br /&gt;
	EPD.deepsleep();&lt;br /&gt;
&lt;br /&gt;
} void loop()&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
	delay(1); // Empêcher le chien de garde de s&amp;#039;interrompre&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>144.2.107.134</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1953</id>
		<title>CrowPanel-ESP32-E-Paper-HMI-1.54</title>
		<link rel="alternate" type="text/html" href="https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1953"/>
		<updated>2025-12-01T23:17:11Z</updated>

		<summary type="html">&lt;p&gt;144.2.107.134: /* Code Exemples */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== E-Paper-HMI-1.54 (Elecrow) ==&lt;br /&gt;
&lt;br /&gt;
=== Liens externes ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_HMI_1.54-inch_Display.html Wiki&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_1.54-inch_Arduino_Tutorial.html Arduino Setup&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/crowpanel-esp32-1-54-e-paper-hmi-display-with-152-152-resolution-black-white-color-driven-by-spi-interface.html Shop&lt;br /&gt;
&lt;br /&gt;
 BLE debugging assistant&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/1-54-inch-152-152-e-paper-display-black-white-e-ink-display-with-spi-communication.html&lt;br /&gt;
&lt;br /&gt;
=== Caractéristiques ===&lt;br /&gt;
&lt;br /&gt;
Model: DIE09154S&amp;lt;br&amp;gt;&lt;br /&gt;
Driver Chip : &amp;lt;b&amp;gt;SSD1680&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Résolution 152*152&amp;lt;br&amp;gt;&lt;br /&gt;
Couleur noir et blanc&amp;lt;br&amp;gt;&lt;br /&gt;
Pilote ESP32-S3 comme contrôleur principal&amp;lt;br&amp;gt;&lt;br /&gt;
PSRAM : 8MB&amp;lt;br&amp;gt;&lt;br /&gt;
Flash :	8MB&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Images ===&lt;br /&gt;
[[File:E-Paper-HMI-1.54-1.png|300px]]&lt;br /&gt;
&lt;br /&gt;
[[File:E-Paper-HMI-1.54-2.png|300px]]&lt;br /&gt;
[[File:E-Paper-HMI-1.54-3.png|300px]]&lt;br /&gt;
&lt;br /&gt;
=== Ressources ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/download/product/CrowPanel/E-paper/Image2Lcd_v2.9.zip Image2Lcd_v2.9&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152 GitHub&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152/archive/refs/heads/master.zip GitHub ZIP&lt;br /&gt;
&lt;br /&gt;
=== Arduine Mise en route (Setup) ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. Téléchargez les fichiers de bibliothèque utilisés par ce produit dans le dossier « bibliothèques ».&lt;br /&gt;
&lt;br /&gt;
C:\Users\Documents\Arduino\libraries\&lt;br /&gt;
&lt;br /&gt;
[[File:CrowPanel-ESP32-Setup-Arduino-1.png|600px]]&lt;br /&gt;
&lt;br /&gt;
CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152-master/example/arduino/libraries/ &amp;lt;b&amp;gt;Voir sur GitHub&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Ouvrez l&amp;#039;IDE Arduino&amp;lt;br&amp;gt;&lt;br /&gt;
chercher &amp;lt;b&amp;gt;ESP32&amp;lt;/b&amp;gt; dans Boards Manager, installez si cela n&amp;#039;est pas déjà fait &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;by Espressif Systems&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:CrowPanel-ESP32-Setup-Arduino-2.jpg|400px]]&lt;br /&gt;
&lt;br /&gt;
3. Click &amp;quot;Tools&amp;quot;-&amp;gt;&amp;quot;Board&amp;quot;-&amp;gt;&amp;quot;esp32&amp;quot;-&amp;gt;&amp;quot;&amp;lt;b&amp;gt;ESP32S3 Dev Module&amp;lt;/b&amp;gt;&amp;quot;, &lt;br /&gt;
&lt;br /&gt;
and the &amp;quot;Partition Scheme&amp;quot; select &lt;br /&gt;
&amp;quot;Huge APP (3MB No OTA/1MB SPIFFS)&amp;quot;, &lt;br /&gt;
&amp;quot;PSRAM&amp;quot; select &amp;quot;OPI PSRAM&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[File:Setup-Arduino-1.png|300px]]&lt;br /&gt;
&lt;br /&gt;
=== Librairies ===&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;Arduino.h&amp;gt;   // Inclure la bibliothèque principale Arduino&lt;br /&gt;
 #include &amp;quot;EPD_GUI.h&amp;quot;   // Inclure la bibliothèque pour l&amp;#039;écran à encre électronique&lt;br /&gt;
 #include &amp;quot;Pic.h&amp;quot;       // Inclure la bibliothèque de fonctions personnalisées&lt;br /&gt;
 #include &amp;quot;FS.h&amp;quot;        // Bibliothèque du système de fichiers pour les opérations sur les fichiers&lt;br /&gt;
 #include &amp;quot;SPIFFS.h&amp;quot;    // Bibliothèque du système de fichiers SPIFFS pour la lecture et l&amp;#039;écriture de fichiers&lt;br /&gt;
 #include &amp;lt;WiFi.h&amp;gt;      // Bibliothèque WiFi pour la création et la gestion des connexions WiFi&lt;br /&gt;
 #include &amp;lt;Ticker.h&amp;gt;    // Bibliothèque de chronométrage&lt;br /&gt;
 #include &amp;lt;WebServer.h&amp;gt; // Bibliothèque de serveur Web pour la création d&amp;#039;un serveur HTTP&lt;br /&gt;
&lt;br /&gt;
=== Code Exemples ===&lt;br /&gt;
&lt;br /&gt;
Arduino Code for demos&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_WIFI_refresh.ino &amp;lt;b&amp;gt;Update via WiFi&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_ble_refresh.ino  &amp;lt;b&amp;gt;Update via Bluetooth&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_wifi_http_openweather.ino&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arduino Code for examples&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_PWR.ino&amp;lt;br&amp;gt;&lt;br /&gt;
[[1.54_wifi.ino| 1.54_wifi.ino]]&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_BLE.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_key.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_Global_refresh.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_partial_refresh.ino&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[epd1in54bV2-demo.ino| epd1in54bV2-demo.ino]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get Started with Crowpanel E-Paper Screen:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=smDFHRxDYdw&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=-9DeXQIjOc0&amp;lt;br&amp;gt;&lt;br /&gt;
Lesson 02 - Display Images&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=7PN9q9b3nKk&amp;lt;br&amp;gt;&lt;br /&gt;
Lesson 03 - Display Text&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=x70f8aAUQBk&amp;lt;br&amp;gt;&lt;br /&gt;
Lesson 04 - Transmit Images via Bluetooth&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=vzq8-aMmTOQ&amp;lt;br&amp;gt;&lt;br /&gt;
Lesson 05 - Transmit Images via WiFi&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=Nb-hP7yaf7Q&amp;lt;br&amp;gt;&lt;br /&gt;
Lesson 06 - Setting Up the Calendar Desktop&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Code wifi_http_openweather ===&lt;br /&gt;
&lt;br /&gt;
https://openweathermap.org/ Veuillez vous enregistrer afin de vous procurer votre OpenWeatherMap API key&lt;br /&gt;
&lt;br /&gt;
http://bulk.openweathermap.org/sample/ on trouve ici : &amp;lt;b&amp;gt;city.list.json.gz&amp;lt;/b&amp;gt;, le countryCode de votre ville (variable city)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;lt;HTTPClient.h&amp;gt;&lt;br /&gt;
#include &amp;lt;Arduino_JSON.h&amp;gt;&lt;br /&gt;
#include &amp;quot;EPD_GUI.h&amp;quot;&lt;br /&gt;
#include &amp;quot;Pic.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
// Define an array for black and white image data, which serves as the buffer for the e-paper display.&lt;br /&gt;
// The size of the buffer is determined according to the resolution of the e-paper display.&lt;br /&gt;
uint8_t ImageBW[2888];&lt;br /&gt;
&lt;br /&gt;
// WiFi network name // WiFi password&lt;br /&gt;
const char* ssid = &amp;quot;yanfa_software&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;yanfa-123456&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// OpenWeatherMap API key. This key is used to access weather data from the OpenWeatherMap API.&lt;br /&gt;
String openWeatherMapApiKey = &amp;quot;3c03d1f4e2dd3e14474a9a3a2f2299ff&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// City and country code for which weather data will be fetched.&lt;br /&gt;
String city = &amp;quot;London&amp;quot;;&lt;br /&gt;
String countryCode = &amp;quot;2643743&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Variables related to timing and API calls.&lt;br /&gt;
// lastTime keeps track of the last time the API was called.&lt;br /&gt;
unsigned long lastTime = 0;&lt;br /&gt;
// timerDelay determines the time interval between API calls. For testing, it&amp;#039;s set to 10 seconds (10000 milliseconds).&lt;br /&gt;
// In a final application, this should be set according to the API call limits per hour/minute.&lt;br /&gt;
unsigned long timerDelay = 10000;&lt;br /&gt;
&lt;br /&gt;
// Variables related to JSON data.&lt;br /&gt;
// jsonBuffer stores the raw JSON data received from the API.&lt;br /&gt;
String jsonBuffer;&lt;br /&gt;
// httpResponseCode holds the response code from the HTTP request.&lt;br /&gt;
int httpResponseCode;&lt;br /&gt;
// myObject is a JSON variable that will hold the parsed JSON data.&lt;br /&gt;
JSONVar myObject;&lt;br /&gt;
&lt;br /&gt;
// Variables related to weather information.&lt;br /&gt;
// weather stores the main weather description.&lt;br /&gt;
String weather;&lt;br /&gt;
// temperature stores the temperature value.&lt;br /&gt;
String temperature;&lt;br /&gt;
// humidity stores the humidity value.&lt;br /&gt;
String humidity;&lt;br /&gt;
// sea_level stores the sea level value.&lt;br /&gt;
String sea_level;&lt;br /&gt;
// wind_speed stores the wind speed value.&lt;br /&gt;
String wind_speed;&lt;br /&gt;
// city_js stores the name of the city.&lt;br /&gt;
String city_js;&lt;br /&gt;
// weather_flag is a flag that determines which weather icon to display based on the weather description.&lt;br /&gt;
int weather_flag = 0;&lt;br /&gt;
&lt;br /&gt;
// Function to display weather forecast on the e-paper display.&lt;br /&gt;
void UI_weather_forecast()&lt;br /&gt;
{&lt;br /&gt;
  char buffer[40];&lt;br /&gt;
&lt;br /&gt;
  EPD_HW_RESET();&lt;br /&gt;
&lt;br /&gt;
  // Display a background picture on the e-paper.&lt;br /&gt;
  EPD_ShowPicture(0, 0, 152, 152, pic, BLACK);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  //If you need to replace the display options,&lt;br /&gt;
  //open the following options: temp, wind, visit, hum&lt;br /&gt;
  //The following uses the hum option as an example&lt;br /&gt;
&lt;br /&gt;
  //Visit&lt;br /&gt;
  //EPD_ShowPicture(76, 92, 56, 72, gImage_visit, BLACK);&lt;br /&gt;
  //Wind&lt;br /&gt;
  //EPD_ShowPicture(76, 92, 56, 72, gImage_wind, BLACK);&lt;br /&gt;
  //Temp&lt;br /&gt;
  //  EPD_ShowPicture(92, 0, 56, 72, gImage_temp, BLACK);&lt;br /&gt;
  //Hum&lt;br /&gt;
&lt;br /&gt;
  EPD_Display(ImageBW);&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_DeepSleep();&lt;br /&gt;
&lt;br /&gt;
  EPD_GPIOInit();&lt;br /&gt;
  Paint_NewImage(ImageBW, EPD_W, EPD_H, 270, WHITE);&lt;br /&gt;
  // Paint_Clear(WHITE);&lt;br /&gt;
  EPD_FastMode1Init();&lt;br /&gt;
  // EPD_Display_Clear();&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_Clear_R26H();&lt;br /&gt;
&lt;br /&gt;
  // Display the update time (it seems to be mislabeled as city_js here, might need to be corrected depending on the actual intention).&lt;br /&gt;
  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, city_js);&lt;br /&gt;
  EPD_ShowString(20, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //If you need to replace the display options,&lt;br /&gt;
  //open the following options: temp, wind, visit, hum&lt;br /&gt;
  //The following uses the hum option as an example&lt;br /&gt;
&lt;br /&gt;
  //Hum&lt;br /&gt;
  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, humidity);&lt;br /&gt;
  EPD_ShowString(105, 140, buffer,  12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //Temp&lt;br /&gt;
  //       memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  //       snprintf(buffer, sizeof(buffer), &amp;quot;%s C&amp;quot;, temperature);&lt;br /&gt;
  //       EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //Wind&lt;br /&gt;
  // memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  // snprintf(buffer, sizeof(buffer), &amp;quot;%s m/s&amp;quot;, wind_speed);&lt;br /&gt;
  // EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //visit&lt;br /&gt;
  //  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  //  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, sea_level);&lt;br /&gt;
  //  EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  // Update the e-paper display with the new content.&lt;br /&gt;
  EPD_Display(ImageBW);&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_DeepSleep();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200); // Initialize the serial communication.&lt;br /&gt;
&lt;br /&gt;
  // Connect to the WiFi network.&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  Serial.println(&amp;quot;Connecting&amp;quot;);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot;&amp;quot;);&lt;br /&gt;
  Serial.print(&amp;quot;Connected to WiFi network with IP Address: &amp;quot;);&lt;br /&gt;
  Serial.println(WiFi.localIP()); // Print the IP address of the device after successful connection.&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Timer set to 10 seconds (timerDelay variable), it will take 10 seconds before publishing the first reading.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Set pin 7 as an output pin to control the power of the e-paper display.&lt;br /&gt;
  pinMode(7, OUTPUT);&lt;br /&gt;
  digitalWrite(7, HIGH);&lt;br /&gt;
&lt;br /&gt;
  EPD_GPIOInit();&lt;br /&gt;
  Paint_NewImage(ImageBW, EPD_W, EPD_H, 0, WHITE);&lt;br /&gt;
  Paint_Clear(WHITE);&lt;br /&gt;
  EPD_FastMode1Init();&lt;br /&gt;
  EPD_Display_Clear();&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_Clear_R26H();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  js_analysis();&lt;br /&gt;
  UI_weather_forecast();&lt;br /&gt;
  delay(1000 * 60 * 60);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void js_analysis()&lt;br /&gt;
{&lt;br /&gt;
  // Check if the device is connected to the WiFi network.&lt;br /&gt;
  if (WiFi.status() == WL_CONNECTED) {&lt;br /&gt;
    // Construct the URL for the OpenWeatherMap API request.&lt;br /&gt;
    String serverPath = &amp;quot;http://api.openweathermap.org/data/2.5/weather?q=&amp;quot; + city + &amp;quot;,&amp;quot; + countryCode + &amp;quot;&amp;amp;APPID=&amp;quot; + openWeatherMapApiKey + &amp;quot;&amp;amp;units=metric&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    // Keep trying until a successful response (status code 200) is received.&lt;br /&gt;
    while (httpResponseCode != 200) {&lt;br /&gt;
      // Make an HTTP GET request to the API and store the response in jsonBuffer.&lt;br /&gt;
      jsonBuffer = httpGETRequest(serverPath.c_str());&lt;br /&gt;
      Serial.println(jsonBuffer);&lt;br /&gt;
      myObject = JSON.parse(jsonBuffer);&lt;br /&gt;
&lt;br /&gt;
      // Check if the JSON parsing was successful.&lt;br /&gt;
      if (JSON.typeof(myObject) == &amp;quot;undefined&amp;quot;) {&lt;br /&gt;
        Serial.println(&amp;quot;Parsing input failed!&amp;quot;);&lt;br /&gt;
        return;&lt;br /&gt;
      }&lt;br /&gt;
      delay(2000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Extract weather information from the parsed JSON data.&lt;br /&gt;
    weather = JSON.stringify(myObject[&amp;quot;weather&amp;quot;][0][&amp;quot;main&amp;quot;]);&lt;br /&gt;
    temperature = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;temp&amp;quot;]);&lt;br /&gt;
    humidity = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;humidity&amp;quot;]);&lt;br /&gt;
    sea_level = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;sea_level&amp;quot;]);&lt;br /&gt;
    wind_speed = JSON.stringify(myObject[&amp;quot;wind&amp;quot;][&amp;quot;speed&amp;quot;]);&lt;br /&gt;
    city_js = JSON.stringify(myObject[&amp;quot;name&amp;quot;]);&lt;br /&gt;
&lt;br /&gt;
    // Print the extracted weather information for debugging purposes.&lt;br /&gt;
    Serial.print(&amp;quot;String weather: &amp;quot;);&lt;br /&gt;
    Serial.println(weather);&lt;br /&gt;
    Serial.print(&amp;quot;String Temperature: &amp;quot;);&lt;br /&gt;
    Serial.println(temperature);&lt;br /&gt;
    Serial.print(&amp;quot;String humidity: &amp;quot;);&lt;br /&gt;
    Serial.println(humidity);&lt;br /&gt;
    Serial.print(&amp;quot;String sea_level: &amp;quot;);&lt;br /&gt;
    Serial.println(sea_level);&lt;br /&gt;
    Serial.print(&amp;quot;String wind_speed: &amp;quot;);&lt;br /&gt;
    Serial.println(wind_speed);&lt;br /&gt;
    Serial.print(&amp;quot;String city_js: &amp;quot;);&lt;br /&gt;
    Serial.println(city_js);&lt;br /&gt;
&lt;br /&gt;
    // Determine the weather icon based on the weather description.&lt;br /&gt;
    if (weather.indexOf(&amp;quot;clouds&amp;quot;) != -1 || weather.indexOf(&amp;quot;Clouds&amp;quot;) != -1 ) {&lt;br /&gt;
      weather_flag = 1;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;clear sky&amp;quot;) != -1 || weather.indexOf(&amp;quot;Clear sky&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 3;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;rain&amp;quot;) != -1 || weather.indexOf(&amp;quot;Rain&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 5;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;thunderstorm&amp;quot;) != -1 || weather.indexOf(&amp;quot;Thunderstorm&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 2;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;snow&amp;quot;) != -1 || weather.indexOf(&amp;quot;Snow&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 4;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;mist&amp;quot;) != -1 || weather.indexOf(&amp;quot;Mist&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 0;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
    // Print a message if the device is not connected to the WiFi network.&lt;br /&gt;
    Serial.println(&amp;quot;WiFi Disconnected&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Function to make an HTTP GET request and return the response.&lt;br /&gt;
String httpGETRequest(const char* serverName) {&lt;br /&gt;
  WiFiClient client;&lt;br /&gt;
  HTTPClient http;&lt;br /&gt;
&lt;br /&gt;
  // Initialize the HTTP client with the server name.&lt;br /&gt;
  http.begin(client, serverName);&lt;br /&gt;
&lt;br /&gt;
  // Send an HTTP GET request.&lt;br /&gt;
  httpResponseCode = http.GET();&lt;br /&gt;
&lt;br /&gt;
  // Initialize the response payload as an empty JSON object.&lt;br /&gt;
  String payload = &amp;quot;{}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  // Check if the response code is positive (indicating a successful request).&lt;br /&gt;
  if (httpResponseCode &amp;gt; 0) {&lt;br /&gt;
    Serial.print(&amp;quot;HTTP Response code: &amp;quot;);&lt;br /&gt;
    Serial.println(httpResponseCode);&lt;br /&gt;
    payload = http.getString();&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
    Serial.print(&amp;quot;Error code: &amp;quot;);&lt;br /&gt;
    Serial.println(httpResponseCode);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Close the HTTP connection.&lt;br /&gt;
  http.end();&lt;br /&gt;
&lt;br /&gt;
  return payload;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 Explications : Partie à modifier avec vos données, ssid, password, openWeatherMapApiKey, city, countryCode&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// WiFi network name // WiFi password&lt;br /&gt;
&lt;br /&gt;
const char* ssid = &amp;quot;yanfa_software&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;yanfa-123456&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// OpenWeatherMap API key. This key is used to access weather data from the OpenWeatherMap API.&lt;br /&gt;
String openWeatherMapApiKey = &amp;quot;3c03d1f4e2dd3e14474a9a3a2f2299ff&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// City and country code for which weather data will be fetched.&lt;br /&gt;
String city = &amp;quot;London&amp;quot;;&lt;br /&gt;
String countryCode = &amp;quot;2643743&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Code HelloWord ===&lt;br /&gt;
&lt;br /&gt;
 Basé sur le code https://github.com/HalfSweetStudio/EPaperDrive/blob/main/examples/HelloWorld/HelloWorld.ino&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
	* @file HelloWorld.ino&lt;br /&gt;
	* @author HalfSweet (Email:HalfSweet@HalfSweet.cn or QQ:2522182733)&lt;br /&gt;
	* @brief Ce fichier est un exemple de programme permettant d&amp;#039;afficher «Hello World» sur un écran à encre électronique. &lt;br /&gt;
        * Il illustre uniquement la méthode la plus simple pour allumer l&amp;#039;écran. &lt;br /&gt;
        * Veuillez consulter la documentation pour connaître l&amp;#039;utilisation des différentes fonctions.&lt;br /&gt;
	* @version 0.1&lt;br /&gt;
	* @date 2022-01-30&lt;br /&gt;
	*&lt;br /&gt;
	* @copyright Copyright (c) 2022&lt;br /&gt;
	*&lt;br /&gt;
*/ &lt;br /&gt;
#include &amp;lt;Arduino.h&amp;gt;&lt;br /&gt;
#include &amp;lt;EPaperDrive.h&amp;gt;&lt;br /&gt;
// Inclure le système de fichiers à utiliser, par exemple:&lt;br /&gt;
#include &amp;lt;LittleFS.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define BAUD_SPEED 74880 // Débit en bauds pour le débogage du port série, modifiable selon les besoins&lt;br /&gt;
&lt;br /&gt;
#define CS 15&lt;br /&gt;
#define RST 2&lt;br /&gt;
#define DC 0&lt;br /&gt;
#define BUSY 4&lt;br /&gt;
#define CLK 14&lt;br /&gt;
#define DIN 13&lt;br /&gt;
&lt;br /&gt;
EPaperDrive EPD(0, CS, RST, DC, BUSY, CLK, DIN); //Instanciation de la bibliothèque de pilotes, utilisant ici le protocole SPI logiciel&lt;br /&gt;
&lt;br /&gt;
const uint8_t city_icon[24] = {&lt;br /&gt;
	/* 0X01,0X01,0X0C,0X00,0X0C,0X00, */&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X1C,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X77,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X41,&lt;br /&gt;
	0X80,&lt;br /&gt;
	0X9C,&lt;br /&gt;
	0X60,&lt;br /&gt;
	0XA2,&lt;br /&gt;
	0X30,&lt;br /&gt;
	0XA2,&lt;br /&gt;
	0X30,&lt;br /&gt;
	0X9C,&lt;br /&gt;
	0XC0,&lt;br /&gt;
	0X41,&lt;br /&gt;
	0X80,&lt;br /&gt;
	0X77,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X1C,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
	void setup()&lt;br /&gt;
	{&lt;br /&gt;
	Serial.begin(BAUD_SPEED);&lt;br /&gt;
	LittleFS.begin(); 			  // Veuillez initialiser manuellement le système de fichiers avant de passer le pointeur.&lt;br /&gt;
&lt;br /&gt;
	EPD.SetFS(&amp;amp;LittleFS); 			 // Définit le système de fichiers pour le stockage des polices. La valeur passée est le pointeur d&amp;#039;opération pour ce système de fichiers. &lt;br /&gt;
                                                 //Vous pouvez la modifier.&lt;br /&gt;
	EPD.EPD_Set_Model(HINKE0266A15A0); 	 // Définit le type d&amp;#039;écran. Consultez la documentation pour les modèles spécifiques.&lt;br /&gt;
	EPD.EPD_init_Full(); 			// Initialisation du rafraîchissement complet, en utilisant la forme d&amp;#039;onde de rafraîchissement complet.&lt;br /&gt;
	EPD.clearbuffer(); 		        // Efface le tampon (écran blanc).&lt;br /&gt;
	EPD.fontscale = 2; 			// Facteur d&amp;#039;échelle des polices (1 et 2 pris en charge, également applicable aux images. &lt;br /&gt;
                                                // N&amp;#039;oubliez pas de le remettre à 1 après utilisation).&lt;br /&gt;
	EPD.SetFont(FONT12); 		       // Sélectionne la police. Consultez la documentation pour connaître les polices prises en charge.&lt;br /&gt;
	EPD.DrawUTF(0, 0, &amp;quot;Hello&amp;quot;);            // Dessiner la chaîne&lt;br /&gt;
	EPD.DrawUTF(26, 0, &amp;quot;J&amp;#039;aime les écrans à encre électronique&amp;quot;); 	&lt;br /&gt;
                                               // Dessiner la chaîne&lt;br /&gt;
	EPD.fontscale = 1; 		       // Rétablir le facteur d&amp;#039;échelle de la police à 1&lt;br /&gt;
	EPD.DrawXbm_P(60, 0, 12, 12, (uint8_t *)city_icon); 			 // Dessiner l&amp;#039;image&lt;br /&gt;
&lt;br /&gt;
	Serial.printf(&amp;quot;Image tamponnée dessinée, prête pour un rafraîchissement complet\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_Dis_Full((uint8_t *)EPD.EPDbuffer, 1); // Transmettre l&amp;#039;image tamponnée à la puce de contrôle de l&amp;#039;écran pour un rafraîchissement complet&lt;br /&gt;
	EPD.deepsleep(); // Mettre l&amp;#039;écran en veille&lt;br /&gt;
	Serial.println(&amp;quot;Rafraîchissement complet terminé&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	delay(5000);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_init_Part(); // Initialiser la partie Actualisation&lt;br /&gt;
	EPD.clearbuffer();&lt;br /&gt;
	EPD.fontscale = 2;&lt;br /&gt;
	EPD.SetFont(FONT12); EPD.DrawUTF(0, 0, &amp;quot;Actualisation locale activée&amp;quot;);&lt;br /&gt;
	Serial.printf(&amp;quot;Actualisation locale en cours\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_Dis_Part(0, 23, 0, 199, (uint8_t *)EPD.EPDbuffer, 1); // Transfert de l&amp;#039;image du tampon vers la puce de contrôle d&amp;#039;écran pour l&amp;#039;actualisation locale sur le nouvel écran&lt;br /&gt;
	Serial.printf(&amp;quot;Actualisation locale terminée\n&amp;quot;);&lt;br /&gt;
	EPD.deepsleep();&lt;br /&gt;
&lt;br /&gt;
} void loop()&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
	delay(1); // Empêcher le chien de garde de s&amp;#039;interrompre&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>144.2.107.134</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1952</id>
		<title>CrowPanel-ESP32-E-Paper-HMI-1.54</title>
		<link rel="alternate" type="text/html" href="https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1952"/>
		<updated>2025-12-01T23:16:29Z</updated>

		<summary type="html">&lt;p&gt;144.2.107.134: /* Code Exemples */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== E-Paper-HMI-1.54 (Elecrow) ==&lt;br /&gt;
&lt;br /&gt;
=== Liens externes ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_HMI_1.54-inch_Display.html Wiki&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_1.54-inch_Arduino_Tutorial.html Arduino Setup&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/crowpanel-esp32-1-54-e-paper-hmi-display-with-152-152-resolution-black-white-color-driven-by-spi-interface.html Shop&lt;br /&gt;
&lt;br /&gt;
 BLE debugging assistant&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/1-54-inch-152-152-e-paper-display-black-white-e-ink-display-with-spi-communication.html&lt;br /&gt;
&lt;br /&gt;
=== Caractéristiques ===&lt;br /&gt;
&lt;br /&gt;
Model: DIE09154S&amp;lt;br&amp;gt;&lt;br /&gt;
Driver Chip : &amp;lt;b&amp;gt;SSD1680&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Résolution 152*152&amp;lt;br&amp;gt;&lt;br /&gt;
Couleur noir et blanc&amp;lt;br&amp;gt;&lt;br /&gt;
Pilote ESP32-S3 comme contrôleur principal&amp;lt;br&amp;gt;&lt;br /&gt;
PSRAM : 8MB&amp;lt;br&amp;gt;&lt;br /&gt;
Flash :	8MB&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Images ===&lt;br /&gt;
[[File:E-Paper-HMI-1.54-1.png|300px]]&lt;br /&gt;
&lt;br /&gt;
[[File:E-Paper-HMI-1.54-2.png|300px]]&lt;br /&gt;
[[File:E-Paper-HMI-1.54-3.png|300px]]&lt;br /&gt;
&lt;br /&gt;
=== Ressources ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/download/product/CrowPanel/E-paper/Image2Lcd_v2.9.zip Image2Lcd_v2.9&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152 GitHub&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152/archive/refs/heads/master.zip GitHub ZIP&lt;br /&gt;
&lt;br /&gt;
=== Arduine Mise en route (Setup) ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. Téléchargez les fichiers de bibliothèque utilisés par ce produit dans le dossier « bibliothèques ».&lt;br /&gt;
&lt;br /&gt;
C:\Users\Documents\Arduino\libraries\&lt;br /&gt;
&lt;br /&gt;
[[File:CrowPanel-ESP32-Setup-Arduino-1.png|600px]]&lt;br /&gt;
&lt;br /&gt;
CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152-master/example/arduino/libraries/ &amp;lt;b&amp;gt;Voir sur GitHub&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Ouvrez l&amp;#039;IDE Arduino&amp;lt;br&amp;gt;&lt;br /&gt;
chercher &amp;lt;b&amp;gt;ESP32&amp;lt;/b&amp;gt; dans Boards Manager, installez si cela n&amp;#039;est pas déjà fait &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;by Espressif Systems&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:CrowPanel-ESP32-Setup-Arduino-2.jpg|400px]]&lt;br /&gt;
&lt;br /&gt;
3. Click &amp;quot;Tools&amp;quot;-&amp;gt;&amp;quot;Board&amp;quot;-&amp;gt;&amp;quot;esp32&amp;quot;-&amp;gt;&amp;quot;&amp;lt;b&amp;gt;ESP32S3 Dev Module&amp;lt;/b&amp;gt;&amp;quot;, &lt;br /&gt;
&lt;br /&gt;
and the &amp;quot;Partition Scheme&amp;quot; select &lt;br /&gt;
&amp;quot;Huge APP (3MB No OTA/1MB SPIFFS)&amp;quot;, &lt;br /&gt;
&amp;quot;PSRAM&amp;quot; select &amp;quot;OPI PSRAM&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[File:Setup-Arduino-1.png|300px]]&lt;br /&gt;
&lt;br /&gt;
=== Librairies ===&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;Arduino.h&amp;gt;   // Inclure la bibliothèque principale Arduino&lt;br /&gt;
 #include &amp;quot;EPD_GUI.h&amp;quot;   // Inclure la bibliothèque pour l&amp;#039;écran à encre électronique&lt;br /&gt;
 #include &amp;quot;Pic.h&amp;quot;       // Inclure la bibliothèque de fonctions personnalisées&lt;br /&gt;
 #include &amp;quot;FS.h&amp;quot;        // Bibliothèque du système de fichiers pour les opérations sur les fichiers&lt;br /&gt;
 #include &amp;quot;SPIFFS.h&amp;quot;    // Bibliothèque du système de fichiers SPIFFS pour la lecture et l&amp;#039;écriture de fichiers&lt;br /&gt;
 #include &amp;lt;WiFi.h&amp;gt;      // Bibliothèque WiFi pour la création et la gestion des connexions WiFi&lt;br /&gt;
 #include &amp;lt;Ticker.h&amp;gt;    // Bibliothèque de chronométrage&lt;br /&gt;
 #include &amp;lt;WebServer.h&amp;gt; // Bibliothèque de serveur Web pour la création d&amp;#039;un serveur HTTP&lt;br /&gt;
&lt;br /&gt;
=== Code Exemples ===&lt;br /&gt;
&lt;br /&gt;
Arduino Code for demos&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_WIFI_refresh.ino &amp;lt;b&amp;gt;Update via WiFi&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_ble_refresh.ino  &amp;lt;b&amp;gt;Update via Bluetooth&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_wifi_http_openweather.ino&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arduino Code for examples&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_PWR.ino&amp;lt;br&amp;gt;&lt;br /&gt;
[[1.54_wifi.ino| 1.54_wifi.ino]]&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_BLE.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_key.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_Global_refresh.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_partial_refresh.ino&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[epd1in54bV2-demo.ino| epd1in54bV2-demo.ino]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get Started with Crowpanel E-Paper Screen:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=smDFHRxDYdw&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=-9DeXQIjOc0&amp;lt;br&amp;gt;&lt;br /&gt;
Lesson 02 - Display Images&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=7PN9q9b3nKk&amp;lt;br&amp;gt;&lt;br /&gt;
Lesson 03 - Display Text&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=x70f8aAUQBk&amp;lt;br&amp;gt;&lt;br /&gt;
Lesson 04 - Transmit Images via Bluetooth&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=vzq8-aMmTOQ&amp;lt;br&amp;gt;&lt;br /&gt;
Lesson 05 - Transmit Images via WiFi&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=Nb-hP7yaf7Q&amp;lt;br&amp;gt;&lt;br /&gt;
Lesson 06 - Setting Up the Calendar Desktop&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Code wifi_http_openweather ===&lt;br /&gt;
&lt;br /&gt;
https://openweathermap.org/ Veuillez vous enregistrer afin de vous procurer votre OpenWeatherMap API key&lt;br /&gt;
&lt;br /&gt;
http://bulk.openweathermap.org/sample/ on trouve ici : &amp;lt;b&amp;gt;city.list.json.gz&amp;lt;/b&amp;gt;, le countryCode de votre ville (variable city)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;lt;HTTPClient.h&amp;gt;&lt;br /&gt;
#include &amp;lt;Arduino_JSON.h&amp;gt;&lt;br /&gt;
#include &amp;quot;EPD_GUI.h&amp;quot;&lt;br /&gt;
#include &amp;quot;Pic.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
// Define an array for black and white image data, which serves as the buffer for the e-paper display.&lt;br /&gt;
// The size of the buffer is determined according to the resolution of the e-paper display.&lt;br /&gt;
uint8_t ImageBW[2888];&lt;br /&gt;
&lt;br /&gt;
// WiFi network name // WiFi password&lt;br /&gt;
const char* ssid = &amp;quot;yanfa_software&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;yanfa-123456&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// OpenWeatherMap API key. This key is used to access weather data from the OpenWeatherMap API.&lt;br /&gt;
String openWeatherMapApiKey = &amp;quot;3c03d1f4e2dd3e14474a9a3a2f2299ff&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// City and country code for which weather data will be fetched.&lt;br /&gt;
String city = &amp;quot;London&amp;quot;;&lt;br /&gt;
String countryCode = &amp;quot;2643743&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Variables related to timing and API calls.&lt;br /&gt;
// lastTime keeps track of the last time the API was called.&lt;br /&gt;
unsigned long lastTime = 0;&lt;br /&gt;
// timerDelay determines the time interval between API calls. For testing, it&amp;#039;s set to 10 seconds (10000 milliseconds).&lt;br /&gt;
// In a final application, this should be set according to the API call limits per hour/minute.&lt;br /&gt;
unsigned long timerDelay = 10000;&lt;br /&gt;
&lt;br /&gt;
// Variables related to JSON data.&lt;br /&gt;
// jsonBuffer stores the raw JSON data received from the API.&lt;br /&gt;
String jsonBuffer;&lt;br /&gt;
// httpResponseCode holds the response code from the HTTP request.&lt;br /&gt;
int httpResponseCode;&lt;br /&gt;
// myObject is a JSON variable that will hold the parsed JSON data.&lt;br /&gt;
JSONVar myObject;&lt;br /&gt;
&lt;br /&gt;
// Variables related to weather information.&lt;br /&gt;
// weather stores the main weather description.&lt;br /&gt;
String weather;&lt;br /&gt;
// temperature stores the temperature value.&lt;br /&gt;
String temperature;&lt;br /&gt;
// humidity stores the humidity value.&lt;br /&gt;
String humidity;&lt;br /&gt;
// sea_level stores the sea level value.&lt;br /&gt;
String sea_level;&lt;br /&gt;
// wind_speed stores the wind speed value.&lt;br /&gt;
String wind_speed;&lt;br /&gt;
// city_js stores the name of the city.&lt;br /&gt;
String city_js;&lt;br /&gt;
// weather_flag is a flag that determines which weather icon to display based on the weather description.&lt;br /&gt;
int weather_flag = 0;&lt;br /&gt;
&lt;br /&gt;
// Function to display weather forecast on the e-paper display.&lt;br /&gt;
void UI_weather_forecast()&lt;br /&gt;
{&lt;br /&gt;
  char buffer[40];&lt;br /&gt;
&lt;br /&gt;
  EPD_HW_RESET();&lt;br /&gt;
&lt;br /&gt;
  // Display a background picture on the e-paper.&lt;br /&gt;
  EPD_ShowPicture(0, 0, 152, 152, pic, BLACK);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  //If you need to replace the display options,&lt;br /&gt;
  //open the following options: temp, wind, visit, hum&lt;br /&gt;
  //The following uses the hum option as an example&lt;br /&gt;
&lt;br /&gt;
  //Visit&lt;br /&gt;
  //EPD_ShowPicture(76, 92, 56, 72, gImage_visit, BLACK);&lt;br /&gt;
  //Wind&lt;br /&gt;
  //EPD_ShowPicture(76, 92, 56, 72, gImage_wind, BLACK);&lt;br /&gt;
  //Temp&lt;br /&gt;
  //  EPD_ShowPicture(92, 0, 56, 72, gImage_temp, BLACK);&lt;br /&gt;
  //Hum&lt;br /&gt;
&lt;br /&gt;
  EPD_Display(ImageBW);&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_DeepSleep();&lt;br /&gt;
&lt;br /&gt;
  EPD_GPIOInit();&lt;br /&gt;
  Paint_NewImage(ImageBW, EPD_W, EPD_H, 270, WHITE);&lt;br /&gt;
  // Paint_Clear(WHITE);&lt;br /&gt;
  EPD_FastMode1Init();&lt;br /&gt;
  // EPD_Display_Clear();&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_Clear_R26H();&lt;br /&gt;
&lt;br /&gt;
  // Display the update time (it seems to be mislabeled as city_js here, might need to be corrected depending on the actual intention).&lt;br /&gt;
  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, city_js);&lt;br /&gt;
  EPD_ShowString(20, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //If you need to replace the display options,&lt;br /&gt;
  //open the following options: temp, wind, visit, hum&lt;br /&gt;
  //The following uses the hum option as an example&lt;br /&gt;
&lt;br /&gt;
  //Hum&lt;br /&gt;
  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, humidity);&lt;br /&gt;
  EPD_ShowString(105, 140, buffer,  12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //Temp&lt;br /&gt;
  //       memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  //       snprintf(buffer, sizeof(buffer), &amp;quot;%s C&amp;quot;, temperature);&lt;br /&gt;
  //       EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //Wind&lt;br /&gt;
  // memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  // snprintf(buffer, sizeof(buffer), &amp;quot;%s m/s&amp;quot;, wind_speed);&lt;br /&gt;
  // EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //visit&lt;br /&gt;
  //  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  //  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, sea_level);&lt;br /&gt;
  //  EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  // Update the e-paper display with the new content.&lt;br /&gt;
  EPD_Display(ImageBW);&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_DeepSleep();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200); // Initialize the serial communication.&lt;br /&gt;
&lt;br /&gt;
  // Connect to the WiFi network.&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  Serial.println(&amp;quot;Connecting&amp;quot;);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot;&amp;quot;);&lt;br /&gt;
  Serial.print(&amp;quot;Connected to WiFi network with IP Address: &amp;quot;);&lt;br /&gt;
  Serial.println(WiFi.localIP()); // Print the IP address of the device after successful connection.&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Timer set to 10 seconds (timerDelay variable), it will take 10 seconds before publishing the first reading.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Set pin 7 as an output pin to control the power of the e-paper display.&lt;br /&gt;
  pinMode(7, OUTPUT);&lt;br /&gt;
  digitalWrite(7, HIGH);&lt;br /&gt;
&lt;br /&gt;
  EPD_GPIOInit();&lt;br /&gt;
  Paint_NewImage(ImageBW, EPD_W, EPD_H, 0, WHITE);&lt;br /&gt;
  Paint_Clear(WHITE);&lt;br /&gt;
  EPD_FastMode1Init();&lt;br /&gt;
  EPD_Display_Clear();&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_Clear_R26H();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  js_analysis();&lt;br /&gt;
  UI_weather_forecast();&lt;br /&gt;
  delay(1000 * 60 * 60);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void js_analysis()&lt;br /&gt;
{&lt;br /&gt;
  // Check if the device is connected to the WiFi network.&lt;br /&gt;
  if (WiFi.status() == WL_CONNECTED) {&lt;br /&gt;
    // Construct the URL for the OpenWeatherMap API request.&lt;br /&gt;
    String serverPath = &amp;quot;http://api.openweathermap.org/data/2.5/weather?q=&amp;quot; + city + &amp;quot;,&amp;quot; + countryCode + &amp;quot;&amp;amp;APPID=&amp;quot; + openWeatherMapApiKey + &amp;quot;&amp;amp;units=metric&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    // Keep trying until a successful response (status code 200) is received.&lt;br /&gt;
    while (httpResponseCode != 200) {&lt;br /&gt;
      // Make an HTTP GET request to the API and store the response in jsonBuffer.&lt;br /&gt;
      jsonBuffer = httpGETRequest(serverPath.c_str());&lt;br /&gt;
      Serial.println(jsonBuffer);&lt;br /&gt;
      myObject = JSON.parse(jsonBuffer);&lt;br /&gt;
&lt;br /&gt;
      // Check if the JSON parsing was successful.&lt;br /&gt;
      if (JSON.typeof(myObject) == &amp;quot;undefined&amp;quot;) {&lt;br /&gt;
        Serial.println(&amp;quot;Parsing input failed!&amp;quot;);&lt;br /&gt;
        return;&lt;br /&gt;
      }&lt;br /&gt;
      delay(2000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Extract weather information from the parsed JSON data.&lt;br /&gt;
    weather = JSON.stringify(myObject[&amp;quot;weather&amp;quot;][0][&amp;quot;main&amp;quot;]);&lt;br /&gt;
    temperature = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;temp&amp;quot;]);&lt;br /&gt;
    humidity = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;humidity&amp;quot;]);&lt;br /&gt;
    sea_level = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;sea_level&amp;quot;]);&lt;br /&gt;
    wind_speed = JSON.stringify(myObject[&amp;quot;wind&amp;quot;][&amp;quot;speed&amp;quot;]);&lt;br /&gt;
    city_js = JSON.stringify(myObject[&amp;quot;name&amp;quot;]);&lt;br /&gt;
&lt;br /&gt;
    // Print the extracted weather information for debugging purposes.&lt;br /&gt;
    Serial.print(&amp;quot;String weather: &amp;quot;);&lt;br /&gt;
    Serial.println(weather);&lt;br /&gt;
    Serial.print(&amp;quot;String Temperature: &amp;quot;);&lt;br /&gt;
    Serial.println(temperature);&lt;br /&gt;
    Serial.print(&amp;quot;String humidity: &amp;quot;);&lt;br /&gt;
    Serial.println(humidity);&lt;br /&gt;
    Serial.print(&amp;quot;String sea_level: &amp;quot;);&lt;br /&gt;
    Serial.println(sea_level);&lt;br /&gt;
    Serial.print(&amp;quot;String wind_speed: &amp;quot;);&lt;br /&gt;
    Serial.println(wind_speed);&lt;br /&gt;
    Serial.print(&amp;quot;String city_js: &amp;quot;);&lt;br /&gt;
    Serial.println(city_js);&lt;br /&gt;
&lt;br /&gt;
    // Determine the weather icon based on the weather description.&lt;br /&gt;
    if (weather.indexOf(&amp;quot;clouds&amp;quot;) != -1 || weather.indexOf(&amp;quot;Clouds&amp;quot;) != -1 ) {&lt;br /&gt;
      weather_flag = 1;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;clear sky&amp;quot;) != -1 || weather.indexOf(&amp;quot;Clear sky&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 3;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;rain&amp;quot;) != -1 || weather.indexOf(&amp;quot;Rain&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 5;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;thunderstorm&amp;quot;) != -1 || weather.indexOf(&amp;quot;Thunderstorm&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 2;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;snow&amp;quot;) != -1 || weather.indexOf(&amp;quot;Snow&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 4;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;mist&amp;quot;) != -1 || weather.indexOf(&amp;quot;Mist&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 0;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
    // Print a message if the device is not connected to the WiFi network.&lt;br /&gt;
    Serial.println(&amp;quot;WiFi Disconnected&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Function to make an HTTP GET request and return the response.&lt;br /&gt;
String httpGETRequest(const char* serverName) {&lt;br /&gt;
  WiFiClient client;&lt;br /&gt;
  HTTPClient http;&lt;br /&gt;
&lt;br /&gt;
  // Initialize the HTTP client with the server name.&lt;br /&gt;
  http.begin(client, serverName);&lt;br /&gt;
&lt;br /&gt;
  // Send an HTTP GET request.&lt;br /&gt;
  httpResponseCode = http.GET();&lt;br /&gt;
&lt;br /&gt;
  // Initialize the response payload as an empty JSON object.&lt;br /&gt;
  String payload = &amp;quot;{}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  // Check if the response code is positive (indicating a successful request).&lt;br /&gt;
  if (httpResponseCode &amp;gt; 0) {&lt;br /&gt;
    Serial.print(&amp;quot;HTTP Response code: &amp;quot;);&lt;br /&gt;
    Serial.println(httpResponseCode);&lt;br /&gt;
    payload = http.getString();&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
    Serial.print(&amp;quot;Error code: &amp;quot;);&lt;br /&gt;
    Serial.println(httpResponseCode);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Close the HTTP connection.&lt;br /&gt;
  http.end();&lt;br /&gt;
&lt;br /&gt;
  return payload;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 Explications : Partie à modifier avec vos données, ssid, password, openWeatherMapApiKey, city, countryCode&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// WiFi network name // WiFi password&lt;br /&gt;
&lt;br /&gt;
const char* ssid = &amp;quot;yanfa_software&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;yanfa-123456&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// OpenWeatherMap API key. This key is used to access weather data from the OpenWeatherMap API.&lt;br /&gt;
String openWeatherMapApiKey = &amp;quot;3c03d1f4e2dd3e14474a9a3a2f2299ff&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// City and country code for which weather data will be fetched.&lt;br /&gt;
String city = &amp;quot;London&amp;quot;;&lt;br /&gt;
String countryCode = &amp;quot;2643743&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Code HelloWord ===&lt;br /&gt;
&lt;br /&gt;
 Basé sur le code https://github.com/HalfSweetStudio/EPaperDrive/blob/main/examples/HelloWorld/HelloWorld.ino&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
	* @file HelloWorld.ino&lt;br /&gt;
	* @author HalfSweet (Email:HalfSweet@HalfSweet.cn or QQ:2522182733)&lt;br /&gt;
	* @brief Ce fichier est un exemple de programme permettant d&amp;#039;afficher «Hello World» sur un écran à encre électronique. &lt;br /&gt;
        * Il illustre uniquement la méthode la plus simple pour allumer l&amp;#039;écran. &lt;br /&gt;
        * Veuillez consulter la documentation pour connaître l&amp;#039;utilisation des différentes fonctions.&lt;br /&gt;
	* @version 0.1&lt;br /&gt;
	* @date 2022-01-30&lt;br /&gt;
	*&lt;br /&gt;
	* @copyright Copyright (c) 2022&lt;br /&gt;
	*&lt;br /&gt;
*/ &lt;br /&gt;
#include &amp;lt;Arduino.h&amp;gt;&lt;br /&gt;
#include &amp;lt;EPaperDrive.h&amp;gt;&lt;br /&gt;
// Inclure le système de fichiers à utiliser, par exemple:&lt;br /&gt;
#include &amp;lt;LittleFS.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define BAUD_SPEED 74880 // Débit en bauds pour le débogage du port série, modifiable selon les besoins&lt;br /&gt;
&lt;br /&gt;
#define CS 15&lt;br /&gt;
#define RST 2&lt;br /&gt;
#define DC 0&lt;br /&gt;
#define BUSY 4&lt;br /&gt;
#define CLK 14&lt;br /&gt;
#define DIN 13&lt;br /&gt;
&lt;br /&gt;
EPaperDrive EPD(0, CS, RST, DC, BUSY, CLK, DIN); //Instanciation de la bibliothèque de pilotes, utilisant ici le protocole SPI logiciel&lt;br /&gt;
&lt;br /&gt;
const uint8_t city_icon[24] = {&lt;br /&gt;
	/* 0X01,0X01,0X0C,0X00,0X0C,0X00, */&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X1C,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X77,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X41,&lt;br /&gt;
	0X80,&lt;br /&gt;
	0X9C,&lt;br /&gt;
	0X60,&lt;br /&gt;
	0XA2,&lt;br /&gt;
	0X30,&lt;br /&gt;
	0XA2,&lt;br /&gt;
	0X30,&lt;br /&gt;
	0X9C,&lt;br /&gt;
	0XC0,&lt;br /&gt;
	0X41,&lt;br /&gt;
	0X80,&lt;br /&gt;
	0X77,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X1C,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
	void setup()&lt;br /&gt;
	{&lt;br /&gt;
	Serial.begin(BAUD_SPEED);&lt;br /&gt;
	LittleFS.begin(); 			  // Veuillez initialiser manuellement le système de fichiers avant de passer le pointeur.&lt;br /&gt;
&lt;br /&gt;
	EPD.SetFS(&amp;amp;LittleFS); 			 // Définit le système de fichiers pour le stockage des polices. La valeur passée est le pointeur d&amp;#039;opération pour ce système de fichiers. &lt;br /&gt;
                                                 //Vous pouvez la modifier.&lt;br /&gt;
	EPD.EPD_Set_Model(HINKE0266A15A0); 	 // Définit le type d&amp;#039;écran. Consultez la documentation pour les modèles spécifiques.&lt;br /&gt;
	EPD.EPD_init_Full(); 			// Initialisation du rafraîchissement complet, en utilisant la forme d&amp;#039;onde de rafraîchissement complet.&lt;br /&gt;
	EPD.clearbuffer(); 		        // Efface le tampon (écran blanc).&lt;br /&gt;
	EPD.fontscale = 2; 			// Facteur d&amp;#039;échelle des polices (1 et 2 pris en charge, également applicable aux images. &lt;br /&gt;
                                                // N&amp;#039;oubliez pas de le remettre à 1 après utilisation).&lt;br /&gt;
	EPD.SetFont(FONT12); 		       // Sélectionne la police. Consultez la documentation pour connaître les polices prises en charge.&lt;br /&gt;
	EPD.DrawUTF(0, 0, &amp;quot;Hello&amp;quot;);            // Dessiner la chaîne&lt;br /&gt;
	EPD.DrawUTF(26, 0, &amp;quot;J&amp;#039;aime les écrans à encre électronique&amp;quot;); 	&lt;br /&gt;
                                               // Dessiner la chaîne&lt;br /&gt;
	EPD.fontscale = 1; 		       // Rétablir le facteur d&amp;#039;échelle de la police à 1&lt;br /&gt;
	EPD.DrawXbm_P(60, 0, 12, 12, (uint8_t *)city_icon); 			 // Dessiner l&amp;#039;image&lt;br /&gt;
&lt;br /&gt;
	Serial.printf(&amp;quot;Image tamponnée dessinée, prête pour un rafraîchissement complet\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_Dis_Full((uint8_t *)EPD.EPDbuffer, 1); // Transmettre l&amp;#039;image tamponnée à la puce de contrôle de l&amp;#039;écran pour un rafraîchissement complet&lt;br /&gt;
	EPD.deepsleep(); // Mettre l&amp;#039;écran en veille&lt;br /&gt;
	Serial.println(&amp;quot;Rafraîchissement complet terminé&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	delay(5000);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_init_Part(); // Initialiser la partie Actualisation&lt;br /&gt;
	EPD.clearbuffer();&lt;br /&gt;
	EPD.fontscale = 2;&lt;br /&gt;
	EPD.SetFont(FONT12); EPD.DrawUTF(0, 0, &amp;quot;Actualisation locale activée&amp;quot;);&lt;br /&gt;
	Serial.printf(&amp;quot;Actualisation locale en cours\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_Dis_Part(0, 23, 0, 199, (uint8_t *)EPD.EPDbuffer, 1); // Transfert de l&amp;#039;image du tampon vers la puce de contrôle d&amp;#039;écran pour l&amp;#039;actualisation locale sur le nouvel écran&lt;br /&gt;
	Serial.printf(&amp;quot;Actualisation locale terminée\n&amp;quot;);&lt;br /&gt;
	EPD.deepsleep();&lt;br /&gt;
&lt;br /&gt;
} void loop()&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
	delay(1); // Empêcher le chien de garde de s&amp;#039;interrompre&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>144.2.107.134</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1951</id>
		<title>CrowPanel-ESP32-E-Paper-HMI-1.54</title>
		<link rel="alternate" type="text/html" href="https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1951"/>
		<updated>2025-12-01T23:15:55Z</updated>

		<summary type="html">&lt;p&gt;144.2.107.134: /* Code Exemples */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== E-Paper-HMI-1.54 (Elecrow) ==&lt;br /&gt;
&lt;br /&gt;
=== Liens externes ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_HMI_1.54-inch_Display.html Wiki&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_1.54-inch_Arduino_Tutorial.html Arduino Setup&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/crowpanel-esp32-1-54-e-paper-hmi-display-with-152-152-resolution-black-white-color-driven-by-spi-interface.html Shop&lt;br /&gt;
&lt;br /&gt;
 BLE debugging assistant&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/1-54-inch-152-152-e-paper-display-black-white-e-ink-display-with-spi-communication.html&lt;br /&gt;
&lt;br /&gt;
=== Caractéristiques ===&lt;br /&gt;
&lt;br /&gt;
Model: DIE09154S&amp;lt;br&amp;gt;&lt;br /&gt;
Driver Chip : &amp;lt;b&amp;gt;SSD1680&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Résolution 152*152&amp;lt;br&amp;gt;&lt;br /&gt;
Couleur noir et blanc&amp;lt;br&amp;gt;&lt;br /&gt;
Pilote ESP32-S3 comme contrôleur principal&amp;lt;br&amp;gt;&lt;br /&gt;
PSRAM : 8MB&amp;lt;br&amp;gt;&lt;br /&gt;
Flash :	8MB&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Images ===&lt;br /&gt;
[[File:E-Paper-HMI-1.54-1.png|300px]]&lt;br /&gt;
&lt;br /&gt;
[[File:E-Paper-HMI-1.54-2.png|300px]]&lt;br /&gt;
[[File:E-Paper-HMI-1.54-3.png|300px]]&lt;br /&gt;
&lt;br /&gt;
=== Ressources ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/download/product/CrowPanel/E-paper/Image2Lcd_v2.9.zip Image2Lcd_v2.9&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152 GitHub&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152/archive/refs/heads/master.zip GitHub ZIP&lt;br /&gt;
&lt;br /&gt;
=== Arduine Mise en route (Setup) ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. Téléchargez les fichiers de bibliothèque utilisés par ce produit dans le dossier « bibliothèques ».&lt;br /&gt;
&lt;br /&gt;
C:\Users\Documents\Arduino\libraries\&lt;br /&gt;
&lt;br /&gt;
[[File:CrowPanel-ESP32-Setup-Arduino-1.png|600px]]&lt;br /&gt;
&lt;br /&gt;
CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152-master/example/arduino/libraries/ &amp;lt;b&amp;gt;Voir sur GitHub&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Ouvrez l&amp;#039;IDE Arduino&amp;lt;br&amp;gt;&lt;br /&gt;
chercher &amp;lt;b&amp;gt;ESP32&amp;lt;/b&amp;gt; dans Boards Manager, installez si cela n&amp;#039;est pas déjà fait &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;by Espressif Systems&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:CrowPanel-ESP32-Setup-Arduino-2.jpg|400px]]&lt;br /&gt;
&lt;br /&gt;
3. Click &amp;quot;Tools&amp;quot;-&amp;gt;&amp;quot;Board&amp;quot;-&amp;gt;&amp;quot;esp32&amp;quot;-&amp;gt;&amp;quot;&amp;lt;b&amp;gt;ESP32S3 Dev Module&amp;lt;/b&amp;gt;&amp;quot;, &lt;br /&gt;
&lt;br /&gt;
and the &amp;quot;Partition Scheme&amp;quot; select &lt;br /&gt;
&amp;quot;Huge APP (3MB No OTA/1MB SPIFFS)&amp;quot;, &lt;br /&gt;
&amp;quot;PSRAM&amp;quot; select &amp;quot;OPI PSRAM&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[File:Setup-Arduino-1.png|300px]]&lt;br /&gt;
&lt;br /&gt;
=== Librairies ===&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;Arduino.h&amp;gt;   // Inclure la bibliothèque principale Arduino&lt;br /&gt;
 #include &amp;quot;EPD_GUI.h&amp;quot;   // Inclure la bibliothèque pour l&amp;#039;écran à encre électronique&lt;br /&gt;
 #include &amp;quot;Pic.h&amp;quot;       // Inclure la bibliothèque de fonctions personnalisées&lt;br /&gt;
 #include &amp;quot;FS.h&amp;quot;        // Bibliothèque du système de fichiers pour les opérations sur les fichiers&lt;br /&gt;
 #include &amp;quot;SPIFFS.h&amp;quot;    // Bibliothèque du système de fichiers SPIFFS pour la lecture et l&amp;#039;écriture de fichiers&lt;br /&gt;
 #include &amp;lt;WiFi.h&amp;gt;      // Bibliothèque WiFi pour la création et la gestion des connexions WiFi&lt;br /&gt;
 #include &amp;lt;Ticker.h&amp;gt;    // Bibliothèque de chronométrage&lt;br /&gt;
 #include &amp;lt;WebServer.h&amp;gt; // Bibliothèque de serveur Web pour la création d&amp;#039;un serveur HTTP&lt;br /&gt;
&lt;br /&gt;
=== Code Exemples ===&lt;br /&gt;
&lt;br /&gt;
Arduino Code for demos&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_WIFI_refresh.ino &amp;lt;b&amp;gt;Update via WiFi&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_ble_refresh.ino  &amp;lt;b&amp;gt;Update via Bluetooth&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_wifi_http_openweather.ino&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arduino Code for examples&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_PWR.ino&amp;lt;br&amp;gt;&lt;br /&gt;
[[1.54_wifi.ino| 1.54_wifi.ino]]&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_BLE.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_key.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_Global_refresh.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_partial_refresh.ino&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[epd1in54bV2-demo.ino| epd1in54bV2-demo.ino]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get Started with Crowpanel E-Paper Screen:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=smDFHRxDYdw&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=-9DeXQIjOc0&amp;lt;br&amp;gt;&lt;br /&gt;
Lesson 02 - Display Images&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=7PN9q9b3nKk&amp;lt;br&amp;gt;&lt;br /&gt;
Lesson 03 - Display Text&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=x70f8aAUQBk&amp;lt;br&amp;gt;&lt;br /&gt;
Lesson 04 - Transmit Images via Bluetooth&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=vzq8-aMmTOQ&amp;lt;br&amp;gt;&lt;br /&gt;
Lesson 05 - Transmit Images via WiFi&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=Nb-hP7yaf7Q&amp;lt;br&amp;gt;&lt;br /&gt;
Lesson 06 - Setting Up the Calendar Desktop&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Code wifi_http_openweather ===&lt;br /&gt;
&lt;br /&gt;
https://openweathermap.org/ Veuillez vous enregistrer afin de vous procurer votre OpenWeatherMap API key&lt;br /&gt;
&lt;br /&gt;
http://bulk.openweathermap.org/sample/ on trouve ici : &amp;lt;b&amp;gt;city.list.json.gz&amp;lt;/b&amp;gt;, le countryCode de votre ville (variable city)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;lt;HTTPClient.h&amp;gt;&lt;br /&gt;
#include &amp;lt;Arduino_JSON.h&amp;gt;&lt;br /&gt;
#include &amp;quot;EPD_GUI.h&amp;quot;&lt;br /&gt;
#include &amp;quot;Pic.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
// Define an array for black and white image data, which serves as the buffer for the e-paper display.&lt;br /&gt;
// The size of the buffer is determined according to the resolution of the e-paper display.&lt;br /&gt;
uint8_t ImageBW[2888];&lt;br /&gt;
&lt;br /&gt;
// WiFi network name // WiFi password&lt;br /&gt;
const char* ssid = &amp;quot;yanfa_software&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;yanfa-123456&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// OpenWeatherMap API key. This key is used to access weather data from the OpenWeatherMap API.&lt;br /&gt;
String openWeatherMapApiKey = &amp;quot;3c03d1f4e2dd3e14474a9a3a2f2299ff&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// City and country code for which weather data will be fetched.&lt;br /&gt;
String city = &amp;quot;London&amp;quot;;&lt;br /&gt;
String countryCode = &amp;quot;2643743&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Variables related to timing and API calls.&lt;br /&gt;
// lastTime keeps track of the last time the API was called.&lt;br /&gt;
unsigned long lastTime = 0;&lt;br /&gt;
// timerDelay determines the time interval between API calls. For testing, it&amp;#039;s set to 10 seconds (10000 milliseconds).&lt;br /&gt;
// In a final application, this should be set according to the API call limits per hour/minute.&lt;br /&gt;
unsigned long timerDelay = 10000;&lt;br /&gt;
&lt;br /&gt;
// Variables related to JSON data.&lt;br /&gt;
// jsonBuffer stores the raw JSON data received from the API.&lt;br /&gt;
String jsonBuffer;&lt;br /&gt;
// httpResponseCode holds the response code from the HTTP request.&lt;br /&gt;
int httpResponseCode;&lt;br /&gt;
// myObject is a JSON variable that will hold the parsed JSON data.&lt;br /&gt;
JSONVar myObject;&lt;br /&gt;
&lt;br /&gt;
// Variables related to weather information.&lt;br /&gt;
// weather stores the main weather description.&lt;br /&gt;
String weather;&lt;br /&gt;
// temperature stores the temperature value.&lt;br /&gt;
String temperature;&lt;br /&gt;
// humidity stores the humidity value.&lt;br /&gt;
String humidity;&lt;br /&gt;
// sea_level stores the sea level value.&lt;br /&gt;
String sea_level;&lt;br /&gt;
// wind_speed stores the wind speed value.&lt;br /&gt;
String wind_speed;&lt;br /&gt;
// city_js stores the name of the city.&lt;br /&gt;
String city_js;&lt;br /&gt;
// weather_flag is a flag that determines which weather icon to display based on the weather description.&lt;br /&gt;
int weather_flag = 0;&lt;br /&gt;
&lt;br /&gt;
// Function to display weather forecast on the e-paper display.&lt;br /&gt;
void UI_weather_forecast()&lt;br /&gt;
{&lt;br /&gt;
  char buffer[40];&lt;br /&gt;
&lt;br /&gt;
  EPD_HW_RESET();&lt;br /&gt;
&lt;br /&gt;
  // Display a background picture on the e-paper.&lt;br /&gt;
  EPD_ShowPicture(0, 0, 152, 152, pic, BLACK);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  //If you need to replace the display options,&lt;br /&gt;
  //open the following options: temp, wind, visit, hum&lt;br /&gt;
  //The following uses the hum option as an example&lt;br /&gt;
&lt;br /&gt;
  //Visit&lt;br /&gt;
  //EPD_ShowPicture(76, 92, 56, 72, gImage_visit, BLACK);&lt;br /&gt;
  //Wind&lt;br /&gt;
  //EPD_ShowPicture(76, 92, 56, 72, gImage_wind, BLACK);&lt;br /&gt;
  //Temp&lt;br /&gt;
  //  EPD_ShowPicture(92, 0, 56, 72, gImage_temp, BLACK);&lt;br /&gt;
  //Hum&lt;br /&gt;
&lt;br /&gt;
  EPD_Display(ImageBW);&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_DeepSleep();&lt;br /&gt;
&lt;br /&gt;
  EPD_GPIOInit();&lt;br /&gt;
  Paint_NewImage(ImageBW, EPD_W, EPD_H, 270, WHITE);&lt;br /&gt;
  // Paint_Clear(WHITE);&lt;br /&gt;
  EPD_FastMode1Init();&lt;br /&gt;
  // EPD_Display_Clear();&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_Clear_R26H();&lt;br /&gt;
&lt;br /&gt;
  // Display the update time (it seems to be mislabeled as city_js here, might need to be corrected depending on the actual intention).&lt;br /&gt;
  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, city_js);&lt;br /&gt;
  EPD_ShowString(20, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //If you need to replace the display options,&lt;br /&gt;
  //open the following options: temp, wind, visit, hum&lt;br /&gt;
  //The following uses the hum option as an example&lt;br /&gt;
&lt;br /&gt;
  //Hum&lt;br /&gt;
  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, humidity);&lt;br /&gt;
  EPD_ShowString(105, 140, buffer,  12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //Temp&lt;br /&gt;
  //       memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  //       snprintf(buffer, sizeof(buffer), &amp;quot;%s C&amp;quot;, temperature);&lt;br /&gt;
  //       EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //Wind&lt;br /&gt;
  // memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  // snprintf(buffer, sizeof(buffer), &amp;quot;%s m/s&amp;quot;, wind_speed);&lt;br /&gt;
  // EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //visit&lt;br /&gt;
  //  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  //  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, sea_level);&lt;br /&gt;
  //  EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  // Update the e-paper display with the new content.&lt;br /&gt;
  EPD_Display(ImageBW);&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_DeepSleep();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200); // Initialize the serial communication.&lt;br /&gt;
&lt;br /&gt;
  // Connect to the WiFi network.&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  Serial.println(&amp;quot;Connecting&amp;quot;);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot;&amp;quot;);&lt;br /&gt;
  Serial.print(&amp;quot;Connected to WiFi network with IP Address: &amp;quot;);&lt;br /&gt;
  Serial.println(WiFi.localIP()); // Print the IP address of the device after successful connection.&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Timer set to 10 seconds (timerDelay variable), it will take 10 seconds before publishing the first reading.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Set pin 7 as an output pin to control the power of the e-paper display.&lt;br /&gt;
  pinMode(7, OUTPUT);&lt;br /&gt;
  digitalWrite(7, HIGH);&lt;br /&gt;
&lt;br /&gt;
  EPD_GPIOInit();&lt;br /&gt;
  Paint_NewImage(ImageBW, EPD_W, EPD_H, 0, WHITE);&lt;br /&gt;
  Paint_Clear(WHITE);&lt;br /&gt;
  EPD_FastMode1Init();&lt;br /&gt;
  EPD_Display_Clear();&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_Clear_R26H();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  js_analysis();&lt;br /&gt;
  UI_weather_forecast();&lt;br /&gt;
  delay(1000 * 60 * 60);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void js_analysis()&lt;br /&gt;
{&lt;br /&gt;
  // Check if the device is connected to the WiFi network.&lt;br /&gt;
  if (WiFi.status() == WL_CONNECTED) {&lt;br /&gt;
    // Construct the URL for the OpenWeatherMap API request.&lt;br /&gt;
    String serverPath = &amp;quot;http://api.openweathermap.org/data/2.5/weather?q=&amp;quot; + city + &amp;quot;,&amp;quot; + countryCode + &amp;quot;&amp;amp;APPID=&amp;quot; + openWeatherMapApiKey + &amp;quot;&amp;amp;units=metric&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    // Keep trying until a successful response (status code 200) is received.&lt;br /&gt;
    while (httpResponseCode != 200) {&lt;br /&gt;
      // Make an HTTP GET request to the API and store the response in jsonBuffer.&lt;br /&gt;
      jsonBuffer = httpGETRequest(serverPath.c_str());&lt;br /&gt;
      Serial.println(jsonBuffer);&lt;br /&gt;
      myObject = JSON.parse(jsonBuffer);&lt;br /&gt;
&lt;br /&gt;
      // Check if the JSON parsing was successful.&lt;br /&gt;
      if (JSON.typeof(myObject) == &amp;quot;undefined&amp;quot;) {&lt;br /&gt;
        Serial.println(&amp;quot;Parsing input failed!&amp;quot;);&lt;br /&gt;
        return;&lt;br /&gt;
      }&lt;br /&gt;
      delay(2000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Extract weather information from the parsed JSON data.&lt;br /&gt;
    weather = JSON.stringify(myObject[&amp;quot;weather&amp;quot;][0][&amp;quot;main&amp;quot;]);&lt;br /&gt;
    temperature = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;temp&amp;quot;]);&lt;br /&gt;
    humidity = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;humidity&amp;quot;]);&lt;br /&gt;
    sea_level = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;sea_level&amp;quot;]);&lt;br /&gt;
    wind_speed = JSON.stringify(myObject[&amp;quot;wind&amp;quot;][&amp;quot;speed&amp;quot;]);&lt;br /&gt;
    city_js = JSON.stringify(myObject[&amp;quot;name&amp;quot;]);&lt;br /&gt;
&lt;br /&gt;
    // Print the extracted weather information for debugging purposes.&lt;br /&gt;
    Serial.print(&amp;quot;String weather: &amp;quot;);&lt;br /&gt;
    Serial.println(weather);&lt;br /&gt;
    Serial.print(&amp;quot;String Temperature: &amp;quot;);&lt;br /&gt;
    Serial.println(temperature);&lt;br /&gt;
    Serial.print(&amp;quot;String humidity: &amp;quot;);&lt;br /&gt;
    Serial.println(humidity);&lt;br /&gt;
    Serial.print(&amp;quot;String sea_level: &amp;quot;);&lt;br /&gt;
    Serial.println(sea_level);&lt;br /&gt;
    Serial.print(&amp;quot;String wind_speed: &amp;quot;);&lt;br /&gt;
    Serial.println(wind_speed);&lt;br /&gt;
    Serial.print(&amp;quot;String city_js: &amp;quot;);&lt;br /&gt;
    Serial.println(city_js);&lt;br /&gt;
&lt;br /&gt;
    // Determine the weather icon based on the weather description.&lt;br /&gt;
    if (weather.indexOf(&amp;quot;clouds&amp;quot;) != -1 || weather.indexOf(&amp;quot;Clouds&amp;quot;) != -1 ) {&lt;br /&gt;
      weather_flag = 1;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;clear sky&amp;quot;) != -1 || weather.indexOf(&amp;quot;Clear sky&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 3;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;rain&amp;quot;) != -1 || weather.indexOf(&amp;quot;Rain&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 5;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;thunderstorm&amp;quot;) != -1 || weather.indexOf(&amp;quot;Thunderstorm&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 2;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;snow&amp;quot;) != -1 || weather.indexOf(&amp;quot;Snow&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 4;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;mist&amp;quot;) != -1 || weather.indexOf(&amp;quot;Mist&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 0;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
    // Print a message if the device is not connected to the WiFi network.&lt;br /&gt;
    Serial.println(&amp;quot;WiFi Disconnected&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Function to make an HTTP GET request and return the response.&lt;br /&gt;
String httpGETRequest(const char* serverName) {&lt;br /&gt;
  WiFiClient client;&lt;br /&gt;
  HTTPClient http;&lt;br /&gt;
&lt;br /&gt;
  // Initialize the HTTP client with the server name.&lt;br /&gt;
  http.begin(client, serverName);&lt;br /&gt;
&lt;br /&gt;
  // Send an HTTP GET request.&lt;br /&gt;
  httpResponseCode = http.GET();&lt;br /&gt;
&lt;br /&gt;
  // Initialize the response payload as an empty JSON object.&lt;br /&gt;
  String payload = &amp;quot;{}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  // Check if the response code is positive (indicating a successful request).&lt;br /&gt;
  if (httpResponseCode &amp;gt; 0) {&lt;br /&gt;
    Serial.print(&amp;quot;HTTP Response code: &amp;quot;);&lt;br /&gt;
    Serial.println(httpResponseCode);&lt;br /&gt;
    payload = http.getString();&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
    Serial.print(&amp;quot;Error code: &amp;quot;);&lt;br /&gt;
    Serial.println(httpResponseCode);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Close the HTTP connection.&lt;br /&gt;
  http.end();&lt;br /&gt;
&lt;br /&gt;
  return payload;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 Explications : Partie à modifier avec vos données, ssid, password, openWeatherMapApiKey, city, countryCode&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// WiFi network name // WiFi password&lt;br /&gt;
&lt;br /&gt;
const char* ssid = &amp;quot;yanfa_software&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;yanfa-123456&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// OpenWeatherMap API key. This key is used to access weather data from the OpenWeatherMap API.&lt;br /&gt;
String openWeatherMapApiKey = &amp;quot;3c03d1f4e2dd3e14474a9a3a2f2299ff&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// City and country code for which weather data will be fetched.&lt;br /&gt;
String city = &amp;quot;London&amp;quot;;&lt;br /&gt;
String countryCode = &amp;quot;2643743&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Code HelloWord ===&lt;br /&gt;
&lt;br /&gt;
 Basé sur le code https://github.com/HalfSweetStudio/EPaperDrive/blob/main/examples/HelloWorld/HelloWorld.ino&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
	* @file HelloWorld.ino&lt;br /&gt;
	* @author HalfSweet (Email:HalfSweet@HalfSweet.cn or QQ:2522182733)&lt;br /&gt;
	* @brief Ce fichier est un exemple de programme permettant d&amp;#039;afficher «Hello World» sur un écran à encre électronique. &lt;br /&gt;
        * Il illustre uniquement la méthode la plus simple pour allumer l&amp;#039;écran. &lt;br /&gt;
        * Veuillez consulter la documentation pour connaître l&amp;#039;utilisation des différentes fonctions.&lt;br /&gt;
	* @version 0.1&lt;br /&gt;
	* @date 2022-01-30&lt;br /&gt;
	*&lt;br /&gt;
	* @copyright Copyright (c) 2022&lt;br /&gt;
	*&lt;br /&gt;
*/ &lt;br /&gt;
#include &amp;lt;Arduino.h&amp;gt;&lt;br /&gt;
#include &amp;lt;EPaperDrive.h&amp;gt;&lt;br /&gt;
// Inclure le système de fichiers à utiliser, par exemple:&lt;br /&gt;
#include &amp;lt;LittleFS.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define BAUD_SPEED 74880 // Débit en bauds pour le débogage du port série, modifiable selon les besoins&lt;br /&gt;
&lt;br /&gt;
#define CS 15&lt;br /&gt;
#define RST 2&lt;br /&gt;
#define DC 0&lt;br /&gt;
#define BUSY 4&lt;br /&gt;
#define CLK 14&lt;br /&gt;
#define DIN 13&lt;br /&gt;
&lt;br /&gt;
EPaperDrive EPD(0, CS, RST, DC, BUSY, CLK, DIN); //Instanciation de la bibliothèque de pilotes, utilisant ici le protocole SPI logiciel&lt;br /&gt;
&lt;br /&gt;
const uint8_t city_icon[24] = {&lt;br /&gt;
	/* 0X01,0X01,0X0C,0X00,0X0C,0X00, */&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X1C,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X77,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X41,&lt;br /&gt;
	0X80,&lt;br /&gt;
	0X9C,&lt;br /&gt;
	0X60,&lt;br /&gt;
	0XA2,&lt;br /&gt;
	0X30,&lt;br /&gt;
	0XA2,&lt;br /&gt;
	0X30,&lt;br /&gt;
	0X9C,&lt;br /&gt;
	0XC0,&lt;br /&gt;
	0X41,&lt;br /&gt;
	0X80,&lt;br /&gt;
	0X77,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X1C,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
	void setup()&lt;br /&gt;
	{&lt;br /&gt;
	Serial.begin(BAUD_SPEED);&lt;br /&gt;
	LittleFS.begin(); 			  // Veuillez initialiser manuellement le système de fichiers avant de passer le pointeur.&lt;br /&gt;
&lt;br /&gt;
	EPD.SetFS(&amp;amp;LittleFS); 			 // Définit le système de fichiers pour le stockage des polices. La valeur passée est le pointeur d&amp;#039;opération pour ce système de fichiers. &lt;br /&gt;
                                                 //Vous pouvez la modifier.&lt;br /&gt;
	EPD.EPD_Set_Model(HINKE0266A15A0); 	 // Définit le type d&amp;#039;écran. Consultez la documentation pour les modèles spécifiques.&lt;br /&gt;
	EPD.EPD_init_Full(); 			// Initialisation du rafraîchissement complet, en utilisant la forme d&amp;#039;onde de rafraîchissement complet.&lt;br /&gt;
	EPD.clearbuffer(); 		        // Efface le tampon (écran blanc).&lt;br /&gt;
	EPD.fontscale = 2; 			// Facteur d&amp;#039;échelle des polices (1 et 2 pris en charge, également applicable aux images. &lt;br /&gt;
                                                // N&amp;#039;oubliez pas de le remettre à 1 après utilisation).&lt;br /&gt;
	EPD.SetFont(FONT12); 		       // Sélectionne la police. Consultez la documentation pour connaître les polices prises en charge.&lt;br /&gt;
	EPD.DrawUTF(0, 0, &amp;quot;Hello&amp;quot;);            // Dessiner la chaîne&lt;br /&gt;
	EPD.DrawUTF(26, 0, &amp;quot;J&amp;#039;aime les écrans à encre électronique&amp;quot;); 	&lt;br /&gt;
                                               // Dessiner la chaîne&lt;br /&gt;
	EPD.fontscale = 1; 		       // Rétablir le facteur d&amp;#039;échelle de la police à 1&lt;br /&gt;
	EPD.DrawXbm_P(60, 0, 12, 12, (uint8_t *)city_icon); 			 // Dessiner l&amp;#039;image&lt;br /&gt;
&lt;br /&gt;
	Serial.printf(&amp;quot;Image tamponnée dessinée, prête pour un rafraîchissement complet\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_Dis_Full((uint8_t *)EPD.EPDbuffer, 1); // Transmettre l&amp;#039;image tamponnée à la puce de contrôle de l&amp;#039;écran pour un rafraîchissement complet&lt;br /&gt;
	EPD.deepsleep(); // Mettre l&amp;#039;écran en veille&lt;br /&gt;
	Serial.println(&amp;quot;Rafraîchissement complet terminé&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	delay(5000);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_init_Part(); // Initialiser la partie Actualisation&lt;br /&gt;
	EPD.clearbuffer();&lt;br /&gt;
	EPD.fontscale = 2;&lt;br /&gt;
	EPD.SetFont(FONT12); EPD.DrawUTF(0, 0, &amp;quot;Actualisation locale activée&amp;quot;);&lt;br /&gt;
	Serial.printf(&amp;quot;Actualisation locale en cours\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_Dis_Part(0, 23, 0, 199, (uint8_t *)EPD.EPDbuffer, 1); // Transfert de l&amp;#039;image du tampon vers la puce de contrôle d&amp;#039;écran pour l&amp;#039;actualisation locale sur le nouvel écran&lt;br /&gt;
	Serial.printf(&amp;quot;Actualisation locale terminée\n&amp;quot;);&lt;br /&gt;
	EPD.deepsleep();&lt;br /&gt;
&lt;br /&gt;
} void loop()&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
	delay(1); // Empêcher le chien de garde de s&amp;#039;interrompre&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>144.2.107.134</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1950</id>
		<title>CrowPanel-ESP32-E-Paper-HMI-1.54</title>
		<link rel="alternate" type="text/html" href="https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1950"/>
		<updated>2025-12-01T23:15:22Z</updated>

		<summary type="html">&lt;p&gt;144.2.107.134: /* Code Exemples */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== E-Paper-HMI-1.54 (Elecrow) ==&lt;br /&gt;
&lt;br /&gt;
=== Liens externes ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_HMI_1.54-inch_Display.html Wiki&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_1.54-inch_Arduino_Tutorial.html Arduino Setup&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/crowpanel-esp32-1-54-e-paper-hmi-display-with-152-152-resolution-black-white-color-driven-by-spi-interface.html Shop&lt;br /&gt;
&lt;br /&gt;
 BLE debugging assistant&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/1-54-inch-152-152-e-paper-display-black-white-e-ink-display-with-spi-communication.html&lt;br /&gt;
&lt;br /&gt;
=== Caractéristiques ===&lt;br /&gt;
&lt;br /&gt;
Model: DIE09154S&amp;lt;br&amp;gt;&lt;br /&gt;
Driver Chip : &amp;lt;b&amp;gt;SSD1680&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Résolution 152*152&amp;lt;br&amp;gt;&lt;br /&gt;
Couleur noir et blanc&amp;lt;br&amp;gt;&lt;br /&gt;
Pilote ESP32-S3 comme contrôleur principal&amp;lt;br&amp;gt;&lt;br /&gt;
PSRAM : 8MB&amp;lt;br&amp;gt;&lt;br /&gt;
Flash :	8MB&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Images ===&lt;br /&gt;
[[File:E-Paper-HMI-1.54-1.png|300px]]&lt;br /&gt;
&lt;br /&gt;
[[File:E-Paper-HMI-1.54-2.png|300px]]&lt;br /&gt;
[[File:E-Paper-HMI-1.54-3.png|300px]]&lt;br /&gt;
&lt;br /&gt;
=== Ressources ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/download/product/CrowPanel/E-paper/Image2Lcd_v2.9.zip Image2Lcd_v2.9&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152 GitHub&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152/archive/refs/heads/master.zip GitHub ZIP&lt;br /&gt;
&lt;br /&gt;
=== Arduine Mise en route (Setup) ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. Téléchargez les fichiers de bibliothèque utilisés par ce produit dans le dossier « bibliothèques ».&lt;br /&gt;
&lt;br /&gt;
C:\Users\Documents\Arduino\libraries\&lt;br /&gt;
&lt;br /&gt;
[[File:CrowPanel-ESP32-Setup-Arduino-1.png|600px]]&lt;br /&gt;
&lt;br /&gt;
CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152-master/example/arduino/libraries/ &amp;lt;b&amp;gt;Voir sur GitHub&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Ouvrez l&amp;#039;IDE Arduino&amp;lt;br&amp;gt;&lt;br /&gt;
chercher &amp;lt;b&amp;gt;ESP32&amp;lt;/b&amp;gt; dans Boards Manager, installez si cela n&amp;#039;est pas déjà fait &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;by Espressif Systems&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:CrowPanel-ESP32-Setup-Arduino-2.jpg|400px]]&lt;br /&gt;
&lt;br /&gt;
3. Click &amp;quot;Tools&amp;quot;-&amp;gt;&amp;quot;Board&amp;quot;-&amp;gt;&amp;quot;esp32&amp;quot;-&amp;gt;&amp;quot;&amp;lt;b&amp;gt;ESP32S3 Dev Module&amp;lt;/b&amp;gt;&amp;quot;, &lt;br /&gt;
&lt;br /&gt;
and the &amp;quot;Partition Scheme&amp;quot; select &lt;br /&gt;
&amp;quot;Huge APP (3MB No OTA/1MB SPIFFS)&amp;quot;, &lt;br /&gt;
&amp;quot;PSRAM&amp;quot; select &amp;quot;OPI PSRAM&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[File:Setup-Arduino-1.png|300px]]&lt;br /&gt;
&lt;br /&gt;
=== Librairies ===&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;Arduino.h&amp;gt;   // Inclure la bibliothèque principale Arduino&lt;br /&gt;
 #include &amp;quot;EPD_GUI.h&amp;quot;   // Inclure la bibliothèque pour l&amp;#039;écran à encre électronique&lt;br /&gt;
 #include &amp;quot;Pic.h&amp;quot;       // Inclure la bibliothèque de fonctions personnalisées&lt;br /&gt;
 #include &amp;quot;FS.h&amp;quot;        // Bibliothèque du système de fichiers pour les opérations sur les fichiers&lt;br /&gt;
 #include &amp;quot;SPIFFS.h&amp;quot;    // Bibliothèque du système de fichiers SPIFFS pour la lecture et l&amp;#039;écriture de fichiers&lt;br /&gt;
 #include &amp;lt;WiFi.h&amp;gt;      // Bibliothèque WiFi pour la création et la gestion des connexions WiFi&lt;br /&gt;
 #include &amp;lt;Ticker.h&amp;gt;    // Bibliothèque de chronométrage&lt;br /&gt;
 #include &amp;lt;WebServer.h&amp;gt; // Bibliothèque de serveur Web pour la création d&amp;#039;un serveur HTTP&lt;br /&gt;
&lt;br /&gt;
=== Code Exemples ===&lt;br /&gt;
&lt;br /&gt;
Arduino Code for demos&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_WIFI_refresh.ino &amp;lt;b&amp;gt;Update via WiFi&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_ble_refresh.ino  &amp;lt;b&amp;gt;Update via Bluetooth&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_wifi_http_openweather.ino&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arduino Code for examples&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_PWR.ino&amp;lt;br&amp;gt;&lt;br /&gt;
[[1.54_wifi.ino| 1.54_wifi.ino]]&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_BLE.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_key.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_Global_refresh.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_partial_refresh.ino&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[epd1in54bV2-demo.ino| epd1in54bV2-demo.ino]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get Started with Crowpanel E-Paper Screen:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=smDFHRxDYdw&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=-9DeXQIjOc0&amp;lt;br&amp;gt;&lt;br /&gt;
Lesson 02 - Display Images&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=7PN9q9b3nKk&amp;lt;br&amp;gt;&lt;br /&gt;
Lesson 03 - Display Text&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=x70f8aAUQBk&amp;lt;br&amp;gt;&lt;br /&gt;
Lesson 04 - Transmit Images via Bluetooth&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=vzq8-aMmTOQ&amp;lt;br&amp;gt;&lt;br /&gt;
Lesson 05 - Transmit Images via WiFi&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=Nb-hP7yaf7Q&amp;lt;br&amp;gt;&lt;br /&gt;
Lesson 06 - Setting Up the Calendar Desktop&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Code wifi_http_openweather ===&lt;br /&gt;
&lt;br /&gt;
https://openweathermap.org/ Veuillez vous enregistrer afin de vous procurer votre OpenWeatherMap API key&lt;br /&gt;
&lt;br /&gt;
http://bulk.openweathermap.org/sample/ on trouve ici : &amp;lt;b&amp;gt;city.list.json.gz&amp;lt;/b&amp;gt;, le countryCode de votre ville (variable city)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;lt;HTTPClient.h&amp;gt;&lt;br /&gt;
#include &amp;lt;Arduino_JSON.h&amp;gt;&lt;br /&gt;
#include &amp;quot;EPD_GUI.h&amp;quot;&lt;br /&gt;
#include &amp;quot;Pic.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
// Define an array for black and white image data, which serves as the buffer for the e-paper display.&lt;br /&gt;
// The size of the buffer is determined according to the resolution of the e-paper display.&lt;br /&gt;
uint8_t ImageBW[2888];&lt;br /&gt;
&lt;br /&gt;
// WiFi network name // WiFi password&lt;br /&gt;
const char* ssid = &amp;quot;yanfa_software&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;yanfa-123456&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// OpenWeatherMap API key. This key is used to access weather data from the OpenWeatherMap API.&lt;br /&gt;
String openWeatherMapApiKey = &amp;quot;3c03d1f4e2dd3e14474a9a3a2f2299ff&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// City and country code for which weather data will be fetched.&lt;br /&gt;
String city = &amp;quot;London&amp;quot;;&lt;br /&gt;
String countryCode = &amp;quot;2643743&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Variables related to timing and API calls.&lt;br /&gt;
// lastTime keeps track of the last time the API was called.&lt;br /&gt;
unsigned long lastTime = 0;&lt;br /&gt;
// timerDelay determines the time interval between API calls. For testing, it&amp;#039;s set to 10 seconds (10000 milliseconds).&lt;br /&gt;
// In a final application, this should be set according to the API call limits per hour/minute.&lt;br /&gt;
unsigned long timerDelay = 10000;&lt;br /&gt;
&lt;br /&gt;
// Variables related to JSON data.&lt;br /&gt;
// jsonBuffer stores the raw JSON data received from the API.&lt;br /&gt;
String jsonBuffer;&lt;br /&gt;
// httpResponseCode holds the response code from the HTTP request.&lt;br /&gt;
int httpResponseCode;&lt;br /&gt;
// myObject is a JSON variable that will hold the parsed JSON data.&lt;br /&gt;
JSONVar myObject;&lt;br /&gt;
&lt;br /&gt;
// Variables related to weather information.&lt;br /&gt;
// weather stores the main weather description.&lt;br /&gt;
String weather;&lt;br /&gt;
// temperature stores the temperature value.&lt;br /&gt;
String temperature;&lt;br /&gt;
// humidity stores the humidity value.&lt;br /&gt;
String humidity;&lt;br /&gt;
// sea_level stores the sea level value.&lt;br /&gt;
String sea_level;&lt;br /&gt;
// wind_speed stores the wind speed value.&lt;br /&gt;
String wind_speed;&lt;br /&gt;
// city_js stores the name of the city.&lt;br /&gt;
String city_js;&lt;br /&gt;
// weather_flag is a flag that determines which weather icon to display based on the weather description.&lt;br /&gt;
int weather_flag = 0;&lt;br /&gt;
&lt;br /&gt;
// Function to display weather forecast on the e-paper display.&lt;br /&gt;
void UI_weather_forecast()&lt;br /&gt;
{&lt;br /&gt;
  char buffer[40];&lt;br /&gt;
&lt;br /&gt;
  EPD_HW_RESET();&lt;br /&gt;
&lt;br /&gt;
  // Display a background picture on the e-paper.&lt;br /&gt;
  EPD_ShowPicture(0, 0, 152, 152, pic, BLACK);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  //If you need to replace the display options,&lt;br /&gt;
  //open the following options: temp, wind, visit, hum&lt;br /&gt;
  //The following uses the hum option as an example&lt;br /&gt;
&lt;br /&gt;
  //Visit&lt;br /&gt;
  //EPD_ShowPicture(76, 92, 56, 72, gImage_visit, BLACK);&lt;br /&gt;
  //Wind&lt;br /&gt;
  //EPD_ShowPicture(76, 92, 56, 72, gImage_wind, BLACK);&lt;br /&gt;
  //Temp&lt;br /&gt;
  //  EPD_ShowPicture(92, 0, 56, 72, gImage_temp, BLACK);&lt;br /&gt;
  //Hum&lt;br /&gt;
&lt;br /&gt;
  EPD_Display(ImageBW);&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_DeepSleep();&lt;br /&gt;
&lt;br /&gt;
  EPD_GPIOInit();&lt;br /&gt;
  Paint_NewImage(ImageBW, EPD_W, EPD_H, 270, WHITE);&lt;br /&gt;
  // Paint_Clear(WHITE);&lt;br /&gt;
  EPD_FastMode1Init();&lt;br /&gt;
  // EPD_Display_Clear();&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_Clear_R26H();&lt;br /&gt;
&lt;br /&gt;
  // Display the update time (it seems to be mislabeled as city_js here, might need to be corrected depending on the actual intention).&lt;br /&gt;
  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, city_js);&lt;br /&gt;
  EPD_ShowString(20, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //If you need to replace the display options,&lt;br /&gt;
  //open the following options: temp, wind, visit, hum&lt;br /&gt;
  //The following uses the hum option as an example&lt;br /&gt;
&lt;br /&gt;
  //Hum&lt;br /&gt;
  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, humidity);&lt;br /&gt;
  EPD_ShowString(105, 140, buffer,  12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //Temp&lt;br /&gt;
  //       memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  //       snprintf(buffer, sizeof(buffer), &amp;quot;%s C&amp;quot;, temperature);&lt;br /&gt;
  //       EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //Wind&lt;br /&gt;
  // memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  // snprintf(buffer, sizeof(buffer), &amp;quot;%s m/s&amp;quot;, wind_speed);&lt;br /&gt;
  // EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //visit&lt;br /&gt;
  //  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  //  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, sea_level);&lt;br /&gt;
  //  EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  // Update the e-paper display with the new content.&lt;br /&gt;
  EPD_Display(ImageBW);&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_DeepSleep();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200); // Initialize the serial communication.&lt;br /&gt;
&lt;br /&gt;
  // Connect to the WiFi network.&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  Serial.println(&amp;quot;Connecting&amp;quot;);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot;&amp;quot;);&lt;br /&gt;
  Serial.print(&amp;quot;Connected to WiFi network with IP Address: &amp;quot;);&lt;br /&gt;
  Serial.println(WiFi.localIP()); // Print the IP address of the device after successful connection.&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Timer set to 10 seconds (timerDelay variable), it will take 10 seconds before publishing the first reading.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Set pin 7 as an output pin to control the power of the e-paper display.&lt;br /&gt;
  pinMode(7, OUTPUT);&lt;br /&gt;
  digitalWrite(7, HIGH);&lt;br /&gt;
&lt;br /&gt;
  EPD_GPIOInit();&lt;br /&gt;
  Paint_NewImage(ImageBW, EPD_W, EPD_H, 0, WHITE);&lt;br /&gt;
  Paint_Clear(WHITE);&lt;br /&gt;
  EPD_FastMode1Init();&lt;br /&gt;
  EPD_Display_Clear();&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_Clear_R26H();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  js_analysis();&lt;br /&gt;
  UI_weather_forecast();&lt;br /&gt;
  delay(1000 * 60 * 60);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void js_analysis()&lt;br /&gt;
{&lt;br /&gt;
  // Check if the device is connected to the WiFi network.&lt;br /&gt;
  if (WiFi.status() == WL_CONNECTED) {&lt;br /&gt;
    // Construct the URL for the OpenWeatherMap API request.&lt;br /&gt;
    String serverPath = &amp;quot;http://api.openweathermap.org/data/2.5/weather?q=&amp;quot; + city + &amp;quot;,&amp;quot; + countryCode + &amp;quot;&amp;amp;APPID=&amp;quot; + openWeatherMapApiKey + &amp;quot;&amp;amp;units=metric&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    // Keep trying until a successful response (status code 200) is received.&lt;br /&gt;
    while (httpResponseCode != 200) {&lt;br /&gt;
      // Make an HTTP GET request to the API and store the response in jsonBuffer.&lt;br /&gt;
      jsonBuffer = httpGETRequest(serverPath.c_str());&lt;br /&gt;
      Serial.println(jsonBuffer);&lt;br /&gt;
      myObject = JSON.parse(jsonBuffer);&lt;br /&gt;
&lt;br /&gt;
      // Check if the JSON parsing was successful.&lt;br /&gt;
      if (JSON.typeof(myObject) == &amp;quot;undefined&amp;quot;) {&lt;br /&gt;
        Serial.println(&amp;quot;Parsing input failed!&amp;quot;);&lt;br /&gt;
        return;&lt;br /&gt;
      }&lt;br /&gt;
      delay(2000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Extract weather information from the parsed JSON data.&lt;br /&gt;
    weather = JSON.stringify(myObject[&amp;quot;weather&amp;quot;][0][&amp;quot;main&amp;quot;]);&lt;br /&gt;
    temperature = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;temp&amp;quot;]);&lt;br /&gt;
    humidity = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;humidity&amp;quot;]);&lt;br /&gt;
    sea_level = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;sea_level&amp;quot;]);&lt;br /&gt;
    wind_speed = JSON.stringify(myObject[&amp;quot;wind&amp;quot;][&amp;quot;speed&amp;quot;]);&lt;br /&gt;
    city_js = JSON.stringify(myObject[&amp;quot;name&amp;quot;]);&lt;br /&gt;
&lt;br /&gt;
    // Print the extracted weather information for debugging purposes.&lt;br /&gt;
    Serial.print(&amp;quot;String weather: &amp;quot;);&lt;br /&gt;
    Serial.println(weather);&lt;br /&gt;
    Serial.print(&amp;quot;String Temperature: &amp;quot;);&lt;br /&gt;
    Serial.println(temperature);&lt;br /&gt;
    Serial.print(&amp;quot;String humidity: &amp;quot;);&lt;br /&gt;
    Serial.println(humidity);&lt;br /&gt;
    Serial.print(&amp;quot;String sea_level: &amp;quot;);&lt;br /&gt;
    Serial.println(sea_level);&lt;br /&gt;
    Serial.print(&amp;quot;String wind_speed: &amp;quot;);&lt;br /&gt;
    Serial.println(wind_speed);&lt;br /&gt;
    Serial.print(&amp;quot;String city_js: &amp;quot;);&lt;br /&gt;
    Serial.println(city_js);&lt;br /&gt;
&lt;br /&gt;
    // Determine the weather icon based on the weather description.&lt;br /&gt;
    if (weather.indexOf(&amp;quot;clouds&amp;quot;) != -1 || weather.indexOf(&amp;quot;Clouds&amp;quot;) != -1 ) {&lt;br /&gt;
      weather_flag = 1;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;clear sky&amp;quot;) != -1 || weather.indexOf(&amp;quot;Clear sky&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 3;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;rain&amp;quot;) != -1 || weather.indexOf(&amp;quot;Rain&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 5;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;thunderstorm&amp;quot;) != -1 || weather.indexOf(&amp;quot;Thunderstorm&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 2;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;snow&amp;quot;) != -1 || weather.indexOf(&amp;quot;Snow&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 4;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;mist&amp;quot;) != -1 || weather.indexOf(&amp;quot;Mist&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 0;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
    // Print a message if the device is not connected to the WiFi network.&lt;br /&gt;
    Serial.println(&amp;quot;WiFi Disconnected&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Function to make an HTTP GET request and return the response.&lt;br /&gt;
String httpGETRequest(const char* serverName) {&lt;br /&gt;
  WiFiClient client;&lt;br /&gt;
  HTTPClient http;&lt;br /&gt;
&lt;br /&gt;
  // Initialize the HTTP client with the server name.&lt;br /&gt;
  http.begin(client, serverName);&lt;br /&gt;
&lt;br /&gt;
  // Send an HTTP GET request.&lt;br /&gt;
  httpResponseCode = http.GET();&lt;br /&gt;
&lt;br /&gt;
  // Initialize the response payload as an empty JSON object.&lt;br /&gt;
  String payload = &amp;quot;{}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  // Check if the response code is positive (indicating a successful request).&lt;br /&gt;
  if (httpResponseCode &amp;gt; 0) {&lt;br /&gt;
    Serial.print(&amp;quot;HTTP Response code: &amp;quot;);&lt;br /&gt;
    Serial.println(httpResponseCode);&lt;br /&gt;
    payload = http.getString();&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
    Serial.print(&amp;quot;Error code: &amp;quot;);&lt;br /&gt;
    Serial.println(httpResponseCode);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Close the HTTP connection.&lt;br /&gt;
  http.end();&lt;br /&gt;
&lt;br /&gt;
  return payload;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 Explications : Partie à modifier avec vos données, ssid, password, openWeatherMapApiKey, city, countryCode&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// WiFi network name // WiFi password&lt;br /&gt;
&lt;br /&gt;
const char* ssid = &amp;quot;yanfa_software&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;yanfa-123456&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// OpenWeatherMap API key. This key is used to access weather data from the OpenWeatherMap API.&lt;br /&gt;
String openWeatherMapApiKey = &amp;quot;3c03d1f4e2dd3e14474a9a3a2f2299ff&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// City and country code for which weather data will be fetched.&lt;br /&gt;
String city = &amp;quot;London&amp;quot;;&lt;br /&gt;
String countryCode = &amp;quot;2643743&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Code HelloWord ===&lt;br /&gt;
&lt;br /&gt;
 Basé sur le code https://github.com/HalfSweetStudio/EPaperDrive/blob/main/examples/HelloWorld/HelloWorld.ino&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
	* @file HelloWorld.ino&lt;br /&gt;
	* @author HalfSweet (Email:HalfSweet@HalfSweet.cn or QQ:2522182733)&lt;br /&gt;
	* @brief Ce fichier est un exemple de programme permettant d&amp;#039;afficher «Hello World» sur un écran à encre électronique. &lt;br /&gt;
        * Il illustre uniquement la méthode la plus simple pour allumer l&amp;#039;écran. &lt;br /&gt;
        * Veuillez consulter la documentation pour connaître l&amp;#039;utilisation des différentes fonctions.&lt;br /&gt;
	* @version 0.1&lt;br /&gt;
	* @date 2022-01-30&lt;br /&gt;
	*&lt;br /&gt;
	* @copyright Copyright (c) 2022&lt;br /&gt;
	*&lt;br /&gt;
*/ &lt;br /&gt;
#include &amp;lt;Arduino.h&amp;gt;&lt;br /&gt;
#include &amp;lt;EPaperDrive.h&amp;gt;&lt;br /&gt;
// Inclure le système de fichiers à utiliser, par exemple:&lt;br /&gt;
#include &amp;lt;LittleFS.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define BAUD_SPEED 74880 // Débit en bauds pour le débogage du port série, modifiable selon les besoins&lt;br /&gt;
&lt;br /&gt;
#define CS 15&lt;br /&gt;
#define RST 2&lt;br /&gt;
#define DC 0&lt;br /&gt;
#define BUSY 4&lt;br /&gt;
#define CLK 14&lt;br /&gt;
#define DIN 13&lt;br /&gt;
&lt;br /&gt;
EPaperDrive EPD(0, CS, RST, DC, BUSY, CLK, DIN); //Instanciation de la bibliothèque de pilotes, utilisant ici le protocole SPI logiciel&lt;br /&gt;
&lt;br /&gt;
const uint8_t city_icon[24] = {&lt;br /&gt;
	/* 0X01,0X01,0X0C,0X00,0X0C,0X00, */&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X1C,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X77,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X41,&lt;br /&gt;
	0X80,&lt;br /&gt;
	0X9C,&lt;br /&gt;
	0X60,&lt;br /&gt;
	0XA2,&lt;br /&gt;
	0X30,&lt;br /&gt;
	0XA2,&lt;br /&gt;
	0X30,&lt;br /&gt;
	0X9C,&lt;br /&gt;
	0XC0,&lt;br /&gt;
	0X41,&lt;br /&gt;
	0X80,&lt;br /&gt;
	0X77,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X1C,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
	void setup()&lt;br /&gt;
	{&lt;br /&gt;
	Serial.begin(BAUD_SPEED);&lt;br /&gt;
	LittleFS.begin(); 			  // Veuillez initialiser manuellement le système de fichiers avant de passer le pointeur.&lt;br /&gt;
&lt;br /&gt;
	EPD.SetFS(&amp;amp;LittleFS); 			 // Définit le système de fichiers pour le stockage des polices. La valeur passée est le pointeur d&amp;#039;opération pour ce système de fichiers. &lt;br /&gt;
                                                 //Vous pouvez la modifier.&lt;br /&gt;
	EPD.EPD_Set_Model(HINKE0266A15A0); 	 // Définit le type d&amp;#039;écran. Consultez la documentation pour les modèles spécifiques.&lt;br /&gt;
	EPD.EPD_init_Full(); 			// Initialisation du rafraîchissement complet, en utilisant la forme d&amp;#039;onde de rafraîchissement complet.&lt;br /&gt;
	EPD.clearbuffer(); 		        // Efface le tampon (écran blanc).&lt;br /&gt;
	EPD.fontscale = 2; 			// Facteur d&amp;#039;échelle des polices (1 et 2 pris en charge, également applicable aux images. &lt;br /&gt;
                                                // N&amp;#039;oubliez pas de le remettre à 1 après utilisation).&lt;br /&gt;
	EPD.SetFont(FONT12); 		       // Sélectionne la police. Consultez la documentation pour connaître les polices prises en charge.&lt;br /&gt;
	EPD.DrawUTF(0, 0, &amp;quot;Hello&amp;quot;);            // Dessiner la chaîne&lt;br /&gt;
	EPD.DrawUTF(26, 0, &amp;quot;J&amp;#039;aime les écrans à encre électronique&amp;quot;); 	&lt;br /&gt;
                                               // Dessiner la chaîne&lt;br /&gt;
	EPD.fontscale = 1; 		       // Rétablir le facteur d&amp;#039;échelle de la police à 1&lt;br /&gt;
	EPD.DrawXbm_P(60, 0, 12, 12, (uint8_t *)city_icon); 			 // Dessiner l&amp;#039;image&lt;br /&gt;
&lt;br /&gt;
	Serial.printf(&amp;quot;Image tamponnée dessinée, prête pour un rafraîchissement complet\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_Dis_Full((uint8_t *)EPD.EPDbuffer, 1); // Transmettre l&amp;#039;image tamponnée à la puce de contrôle de l&amp;#039;écran pour un rafraîchissement complet&lt;br /&gt;
	EPD.deepsleep(); // Mettre l&amp;#039;écran en veille&lt;br /&gt;
	Serial.println(&amp;quot;Rafraîchissement complet terminé&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	delay(5000);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_init_Part(); // Initialiser la partie Actualisation&lt;br /&gt;
	EPD.clearbuffer();&lt;br /&gt;
	EPD.fontscale = 2;&lt;br /&gt;
	EPD.SetFont(FONT12); EPD.DrawUTF(0, 0, &amp;quot;Actualisation locale activée&amp;quot;);&lt;br /&gt;
	Serial.printf(&amp;quot;Actualisation locale en cours\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_Dis_Part(0, 23, 0, 199, (uint8_t *)EPD.EPDbuffer, 1); // Transfert de l&amp;#039;image du tampon vers la puce de contrôle d&amp;#039;écran pour l&amp;#039;actualisation locale sur le nouvel écran&lt;br /&gt;
	Serial.printf(&amp;quot;Actualisation locale terminée\n&amp;quot;);&lt;br /&gt;
	EPD.deepsleep();&lt;br /&gt;
&lt;br /&gt;
} void loop()&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
	delay(1); // Empêcher le chien de garde de s&amp;#039;interrompre&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>144.2.107.134</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1949</id>
		<title>CrowPanel-ESP32-E-Paper-HMI-1.54</title>
		<link rel="alternate" type="text/html" href="https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1949"/>
		<updated>2025-12-01T23:13:28Z</updated>

		<summary type="html">&lt;p&gt;144.2.107.134: /* Code Exemples */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== E-Paper-HMI-1.54 (Elecrow) ==&lt;br /&gt;
&lt;br /&gt;
=== Liens externes ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_HMI_1.54-inch_Display.html Wiki&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_1.54-inch_Arduino_Tutorial.html Arduino Setup&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/crowpanel-esp32-1-54-e-paper-hmi-display-with-152-152-resolution-black-white-color-driven-by-spi-interface.html Shop&lt;br /&gt;
&lt;br /&gt;
 BLE debugging assistant&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/1-54-inch-152-152-e-paper-display-black-white-e-ink-display-with-spi-communication.html&lt;br /&gt;
&lt;br /&gt;
=== Caractéristiques ===&lt;br /&gt;
&lt;br /&gt;
Model: DIE09154S&amp;lt;br&amp;gt;&lt;br /&gt;
Driver Chip : &amp;lt;b&amp;gt;SSD1680&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Résolution 152*152&amp;lt;br&amp;gt;&lt;br /&gt;
Couleur noir et blanc&amp;lt;br&amp;gt;&lt;br /&gt;
Pilote ESP32-S3 comme contrôleur principal&amp;lt;br&amp;gt;&lt;br /&gt;
PSRAM : 8MB&amp;lt;br&amp;gt;&lt;br /&gt;
Flash :	8MB&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Images ===&lt;br /&gt;
[[File:E-Paper-HMI-1.54-1.png|300px]]&lt;br /&gt;
&lt;br /&gt;
[[File:E-Paper-HMI-1.54-2.png|300px]]&lt;br /&gt;
[[File:E-Paper-HMI-1.54-3.png|300px]]&lt;br /&gt;
&lt;br /&gt;
=== Ressources ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/download/product/CrowPanel/E-paper/Image2Lcd_v2.9.zip Image2Lcd_v2.9&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152 GitHub&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152/archive/refs/heads/master.zip GitHub ZIP&lt;br /&gt;
&lt;br /&gt;
=== Arduine Mise en route (Setup) ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. Téléchargez les fichiers de bibliothèque utilisés par ce produit dans le dossier « bibliothèques ».&lt;br /&gt;
&lt;br /&gt;
C:\Users\Documents\Arduino\libraries\&lt;br /&gt;
&lt;br /&gt;
[[File:CrowPanel-ESP32-Setup-Arduino-1.png|600px]]&lt;br /&gt;
&lt;br /&gt;
CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152-master/example/arduino/libraries/ &amp;lt;b&amp;gt;Voir sur GitHub&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Ouvrez l&amp;#039;IDE Arduino&amp;lt;br&amp;gt;&lt;br /&gt;
chercher &amp;lt;b&amp;gt;ESP32&amp;lt;/b&amp;gt; dans Boards Manager, installez si cela n&amp;#039;est pas déjà fait &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;by Espressif Systems&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:CrowPanel-ESP32-Setup-Arduino-2.jpg|400px]]&lt;br /&gt;
&lt;br /&gt;
3. Click &amp;quot;Tools&amp;quot;-&amp;gt;&amp;quot;Board&amp;quot;-&amp;gt;&amp;quot;esp32&amp;quot;-&amp;gt;&amp;quot;&amp;lt;b&amp;gt;ESP32S3 Dev Module&amp;lt;/b&amp;gt;&amp;quot;, &lt;br /&gt;
&lt;br /&gt;
and the &amp;quot;Partition Scheme&amp;quot; select &lt;br /&gt;
&amp;quot;Huge APP (3MB No OTA/1MB SPIFFS)&amp;quot;, &lt;br /&gt;
&amp;quot;PSRAM&amp;quot; select &amp;quot;OPI PSRAM&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[File:Setup-Arduino-1.png|300px]]&lt;br /&gt;
&lt;br /&gt;
=== Librairies ===&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;Arduino.h&amp;gt;   // Inclure la bibliothèque principale Arduino&lt;br /&gt;
 #include &amp;quot;EPD_GUI.h&amp;quot;   // Inclure la bibliothèque pour l&amp;#039;écran à encre électronique&lt;br /&gt;
 #include &amp;quot;Pic.h&amp;quot;       // Inclure la bibliothèque de fonctions personnalisées&lt;br /&gt;
 #include &amp;quot;FS.h&amp;quot;        // Bibliothèque du système de fichiers pour les opérations sur les fichiers&lt;br /&gt;
 #include &amp;quot;SPIFFS.h&amp;quot;    // Bibliothèque du système de fichiers SPIFFS pour la lecture et l&amp;#039;écriture de fichiers&lt;br /&gt;
 #include &amp;lt;WiFi.h&amp;gt;      // Bibliothèque WiFi pour la création et la gestion des connexions WiFi&lt;br /&gt;
 #include &amp;lt;Ticker.h&amp;gt;    // Bibliothèque de chronométrage&lt;br /&gt;
 #include &amp;lt;WebServer.h&amp;gt; // Bibliothèque de serveur Web pour la création d&amp;#039;un serveur HTTP&lt;br /&gt;
&lt;br /&gt;
=== Code Exemples ===&lt;br /&gt;
&lt;br /&gt;
Arduino Code for demos&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_WIFI_refresh.ino &amp;lt;b&amp;gt;Update via WiFi&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_ble_refresh.ino  &amp;lt;b&amp;gt;Update via Bluetooth&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_wifi_http_openweather.ino&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arduino Code for examples&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_PWR.ino&amp;lt;br&amp;gt;&lt;br /&gt;
[[1.54_wifi.ino| 1.54_wifi.ino]]&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_BLE.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_key.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_Global_refresh.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_partial_refresh.ino&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[epd1in54bV2-demo.ino| epd1in54bV2-demo.ino]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=smDFHRxDYdw&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=-9DeXQIjOc0&amp;lt;br&amp;gt;&lt;br /&gt;
Get Started with Crowpanel E-Paper Screen: Lesson 02 - Display Images&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
https://www.youtube.com/watch?v=7PN9q9b3nKk&amp;lt;br&amp;gt;&lt;br /&gt;
Get Started with Crowpanel E-Paper Screen: Lesson 03 - Display Text&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
https://www.youtube.com/watch?v=x70f8aAUQBk&amp;lt;br&amp;gt;&lt;br /&gt;
Get Started with Crowpanel E-Paper Screen: Lesson 04 - Transmit Images via Bluetooth&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
https://www.youtube.com/watch?v=vzq8-aMmTOQ&amp;lt;br&amp;gt;&lt;br /&gt;
Get Started with Crowpanel E-Paper Screen: Lesson 05 - Transmit Images via WiFi&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
https://www.youtube.com/watch?v=Nb-hP7yaf7Q&amp;lt;br&amp;gt;&lt;br /&gt;
Get Started with Crowpanel E-Paper Screen: Lesson 06 - Setting Up the Calendar Desktop&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Code wifi_http_openweather ===&lt;br /&gt;
&lt;br /&gt;
https://openweathermap.org/ Veuillez vous enregistrer afin de vous procurer votre OpenWeatherMap API key&lt;br /&gt;
&lt;br /&gt;
http://bulk.openweathermap.org/sample/ on trouve ici : &amp;lt;b&amp;gt;city.list.json.gz&amp;lt;/b&amp;gt;, le countryCode de votre ville (variable city)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;lt;HTTPClient.h&amp;gt;&lt;br /&gt;
#include &amp;lt;Arduino_JSON.h&amp;gt;&lt;br /&gt;
#include &amp;quot;EPD_GUI.h&amp;quot;&lt;br /&gt;
#include &amp;quot;Pic.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
// Define an array for black and white image data, which serves as the buffer for the e-paper display.&lt;br /&gt;
// The size of the buffer is determined according to the resolution of the e-paper display.&lt;br /&gt;
uint8_t ImageBW[2888];&lt;br /&gt;
&lt;br /&gt;
// WiFi network name // WiFi password&lt;br /&gt;
const char* ssid = &amp;quot;yanfa_software&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;yanfa-123456&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// OpenWeatherMap API key. This key is used to access weather data from the OpenWeatherMap API.&lt;br /&gt;
String openWeatherMapApiKey = &amp;quot;3c03d1f4e2dd3e14474a9a3a2f2299ff&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// City and country code for which weather data will be fetched.&lt;br /&gt;
String city = &amp;quot;London&amp;quot;;&lt;br /&gt;
String countryCode = &amp;quot;2643743&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Variables related to timing and API calls.&lt;br /&gt;
// lastTime keeps track of the last time the API was called.&lt;br /&gt;
unsigned long lastTime = 0;&lt;br /&gt;
// timerDelay determines the time interval between API calls. For testing, it&amp;#039;s set to 10 seconds (10000 milliseconds).&lt;br /&gt;
// In a final application, this should be set according to the API call limits per hour/minute.&lt;br /&gt;
unsigned long timerDelay = 10000;&lt;br /&gt;
&lt;br /&gt;
// Variables related to JSON data.&lt;br /&gt;
// jsonBuffer stores the raw JSON data received from the API.&lt;br /&gt;
String jsonBuffer;&lt;br /&gt;
// httpResponseCode holds the response code from the HTTP request.&lt;br /&gt;
int httpResponseCode;&lt;br /&gt;
// myObject is a JSON variable that will hold the parsed JSON data.&lt;br /&gt;
JSONVar myObject;&lt;br /&gt;
&lt;br /&gt;
// Variables related to weather information.&lt;br /&gt;
// weather stores the main weather description.&lt;br /&gt;
String weather;&lt;br /&gt;
// temperature stores the temperature value.&lt;br /&gt;
String temperature;&lt;br /&gt;
// humidity stores the humidity value.&lt;br /&gt;
String humidity;&lt;br /&gt;
// sea_level stores the sea level value.&lt;br /&gt;
String sea_level;&lt;br /&gt;
// wind_speed stores the wind speed value.&lt;br /&gt;
String wind_speed;&lt;br /&gt;
// city_js stores the name of the city.&lt;br /&gt;
String city_js;&lt;br /&gt;
// weather_flag is a flag that determines which weather icon to display based on the weather description.&lt;br /&gt;
int weather_flag = 0;&lt;br /&gt;
&lt;br /&gt;
// Function to display weather forecast on the e-paper display.&lt;br /&gt;
void UI_weather_forecast()&lt;br /&gt;
{&lt;br /&gt;
  char buffer[40];&lt;br /&gt;
&lt;br /&gt;
  EPD_HW_RESET();&lt;br /&gt;
&lt;br /&gt;
  // Display a background picture on the e-paper.&lt;br /&gt;
  EPD_ShowPicture(0, 0, 152, 152, pic, BLACK);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  //If you need to replace the display options,&lt;br /&gt;
  //open the following options: temp, wind, visit, hum&lt;br /&gt;
  //The following uses the hum option as an example&lt;br /&gt;
&lt;br /&gt;
  //Visit&lt;br /&gt;
  //EPD_ShowPicture(76, 92, 56, 72, gImage_visit, BLACK);&lt;br /&gt;
  //Wind&lt;br /&gt;
  //EPD_ShowPicture(76, 92, 56, 72, gImage_wind, BLACK);&lt;br /&gt;
  //Temp&lt;br /&gt;
  //  EPD_ShowPicture(92, 0, 56, 72, gImage_temp, BLACK);&lt;br /&gt;
  //Hum&lt;br /&gt;
&lt;br /&gt;
  EPD_Display(ImageBW);&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_DeepSleep();&lt;br /&gt;
&lt;br /&gt;
  EPD_GPIOInit();&lt;br /&gt;
  Paint_NewImage(ImageBW, EPD_W, EPD_H, 270, WHITE);&lt;br /&gt;
  // Paint_Clear(WHITE);&lt;br /&gt;
  EPD_FastMode1Init();&lt;br /&gt;
  // EPD_Display_Clear();&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_Clear_R26H();&lt;br /&gt;
&lt;br /&gt;
  // Display the update time (it seems to be mislabeled as city_js here, might need to be corrected depending on the actual intention).&lt;br /&gt;
  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, city_js);&lt;br /&gt;
  EPD_ShowString(20, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //If you need to replace the display options,&lt;br /&gt;
  //open the following options: temp, wind, visit, hum&lt;br /&gt;
  //The following uses the hum option as an example&lt;br /&gt;
&lt;br /&gt;
  //Hum&lt;br /&gt;
  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, humidity);&lt;br /&gt;
  EPD_ShowString(105, 140, buffer,  12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //Temp&lt;br /&gt;
  //       memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  //       snprintf(buffer, sizeof(buffer), &amp;quot;%s C&amp;quot;, temperature);&lt;br /&gt;
  //       EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //Wind&lt;br /&gt;
  // memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  // snprintf(buffer, sizeof(buffer), &amp;quot;%s m/s&amp;quot;, wind_speed);&lt;br /&gt;
  // EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //visit&lt;br /&gt;
  //  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  //  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, sea_level);&lt;br /&gt;
  //  EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  // Update the e-paper display with the new content.&lt;br /&gt;
  EPD_Display(ImageBW);&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_DeepSleep();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200); // Initialize the serial communication.&lt;br /&gt;
&lt;br /&gt;
  // Connect to the WiFi network.&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  Serial.println(&amp;quot;Connecting&amp;quot;);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot;&amp;quot;);&lt;br /&gt;
  Serial.print(&amp;quot;Connected to WiFi network with IP Address: &amp;quot;);&lt;br /&gt;
  Serial.println(WiFi.localIP()); // Print the IP address of the device after successful connection.&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Timer set to 10 seconds (timerDelay variable), it will take 10 seconds before publishing the first reading.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Set pin 7 as an output pin to control the power of the e-paper display.&lt;br /&gt;
  pinMode(7, OUTPUT);&lt;br /&gt;
  digitalWrite(7, HIGH);&lt;br /&gt;
&lt;br /&gt;
  EPD_GPIOInit();&lt;br /&gt;
  Paint_NewImage(ImageBW, EPD_W, EPD_H, 0, WHITE);&lt;br /&gt;
  Paint_Clear(WHITE);&lt;br /&gt;
  EPD_FastMode1Init();&lt;br /&gt;
  EPD_Display_Clear();&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_Clear_R26H();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  js_analysis();&lt;br /&gt;
  UI_weather_forecast();&lt;br /&gt;
  delay(1000 * 60 * 60);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void js_analysis()&lt;br /&gt;
{&lt;br /&gt;
  // Check if the device is connected to the WiFi network.&lt;br /&gt;
  if (WiFi.status() == WL_CONNECTED) {&lt;br /&gt;
    // Construct the URL for the OpenWeatherMap API request.&lt;br /&gt;
    String serverPath = &amp;quot;http://api.openweathermap.org/data/2.5/weather?q=&amp;quot; + city + &amp;quot;,&amp;quot; + countryCode + &amp;quot;&amp;amp;APPID=&amp;quot; + openWeatherMapApiKey + &amp;quot;&amp;amp;units=metric&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    // Keep trying until a successful response (status code 200) is received.&lt;br /&gt;
    while (httpResponseCode != 200) {&lt;br /&gt;
      // Make an HTTP GET request to the API and store the response in jsonBuffer.&lt;br /&gt;
      jsonBuffer = httpGETRequest(serverPath.c_str());&lt;br /&gt;
      Serial.println(jsonBuffer);&lt;br /&gt;
      myObject = JSON.parse(jsonBuffer);&lt;br /&gt;
&lt;br /&gt;
      // Check if the JSON parsing was successful.&lt;br /&gt;
      if (JSON.typeof(myObject) == &amp;quot;undefined&amp;quot;) {&lt;br /&gt;
        Serial.println(&amp;quot;Parsing input failed!&amp;quot;);&lt;br /&gt;
        return;&lt;br /&gt;
      }&lt;br /&gt;
      delay(2000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Extract weather information from the parsed JSON data.&lt;br /&gt;
    weather = JSON.stringify(myObject[&amp;quot;weather&amp;quot;][0][&amp;quot;main&amp;quot;]);&lt;br /&gt;
    temperature = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;temp&amp;quot;]);&lt;br /&gt;
    humidity = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;humidity&amp;quot;]);&lt;br /&gt;
    sea_level = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;sea_level&amp;quot;]);&lt;br /&gt;
    wind_speed = JSON.stringify(myObject[&amp;quot;wind&amp;quot;][&amp;quot;speed&amp;quot;]);&lt;br /&gt;
    city_js = JSON.stringify(myObject[&amp;quot;name&amp;quot;]);&lt;br /&gt;
&lt;br /&gt;
    // Print the extracted weather information for debugging purposes.&lt;br /&gt;
    Serial.print(&amp;quot;String weather: &amp;quot;);&lt;br /&gt;
    Serial.println(weather);&lt;br /&gt;
    Serial.print(&amp;quot;String Temperature: &amp;quot;);&lt;br /&gt;
    Serial.println(temperature);&lt;br /&gt;
    Serial.print(&amp;quot;String humidity: &amp;quot;);&lt;br /&gt;
    Serial.println(humidity);&lt;br /&gt;
    Serial.print(&amp;quot;String sea_level: &amp;quot;);&lt;br /&gt;
    Serial.println(sea_level);&lt;br /&gt;
    Serial.print(&amp;quot;String wind_speed: &amp;quot;);&lt;br /&gt;
    Serial.println(wind_speed);&lt;br /&gt;
    Serial.print(&amp;quot;String city_js: &amp;quot;);&lt;br /&gt;
    Serial.println(city_js);&lt;br /&gt;
&lt;br /&gt;
    // Determine the weather icon based on the weather description.&lt;br /&gt;
    if (weather.indexOf(&amp;quot;clouds&amp;quot;) != -1 || weather.indexOf(&amp;quot;Clouds&amp;quot;) != -1 ) {&lt;br /&gt;
      weather_flag = 1;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;clear sky&amp;quot;) != -1 || weather.indexOf(&amp;quot;Clear sky&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 3;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;rain&amp;quot;) != -1 || weather.indexOf(&amp;quot;Rain&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 5;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;thunderstorm&amp;quot;) != -1 || weather.indexOf(&amp;quot;Thunderstorm&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 2;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;snow&amp;quot;) != -1 || weather.indexOf(&amp;quot;Snow&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 4;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;mist&amp;quot;) != -1 || weather.indexOf(&amp;quot;Mist&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 0;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
    // Print a message if the device is not connected to the WiFi network.&lt;br /&gt;
    Serial.println(&amp;quot;WiFi Disconnected&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Function to make an HTTP GET request and return the response.&lt;br /&gt;
String httpGETRequest(const char* serverName) {&lt;br /&gt;
  WiFiClient client;&lt;br /&gt;
  HTTPClient http;&lt;br /&gt;
&lt;br /&gt;
  // Initialize the HTTP client with the server name.&lt;br /&gt;
  http.begin(client, serverName);&lt;br /&gt;
&lt;br /&gt;
  // Send an HTTP GET request.&lt;br /&gt;
  httpResponseCode = http.GET();&lt;br /&gt;
&lt;br /&gt;
  // Initialize the response payload as an empty JSON object.&lt;br /&gt;
  String payload = &amp;quot;{}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  // Check if the response code is positive (indicating a successful request).&lt;br /&gt;
  if (httpResponseCode &amp;gt; 0) {&lt;br /&gt;
    Serial.print(&amp;quot;HTTP Response code: &amp;quot;);&lt;br /&gt;
    Serial.println(httpResponseCode);&lt;br /&gt;
    payload = http.getString();&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
    Serial.print(&amp;quot;Error code: &amp;quot;);&lt;br /&gt;
    Serial.println(httpResponseCode);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Close the HTTP connection.&lt;br /&gt;
  http.end();&lt;br /&gt;
&lt;br /&gt;
  return payload;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 Explications : Partie à modifier avec vos données, ssid, password, openWeatherMapApiKey, city, countryCode&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// WiFi network name // WiFi password&lt;br /&gt;
&lt;br /&gt;
const char* ssid = &amp;quot;yanfa_software&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;yanfa-123456&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// OpenWeatherMap API key. This key is used to access weather data from the OpenWeatherMap API.&lt;br /&gt;
String openWeatherMapApiKey = &amp;quot;3c03d1f4e2dd3e14474a9a3a2f2299ff&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// City and country code for which weather data will be fetched.&lt;br /&gt;
String city = &amp;quot;London&amp;quot;;&lt;br /&gt;
String countryCode = &amp;quot;2643743&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Code HelloWord ===&lt;br /&gt;
&lt;br /&gt;
 Basé sur le code https://github.com/HalfSweetStudio/EPaperDrive/blob/main/examples/HelloWorld/HelloWorld.ino&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
	* @file HelloWorld.ino&lt;br /&gt;
	* @author HalfSweet (Email:HalfSweet@HalfSweet.cn or QQ:2522182733)&lt;br /&gt;
	* @brief Ce fichier est un exemple de programme permettant d&amp;#039;afficher «Hello World» sur un écran à encre électronique. &lt;br /&gt;
        * Il illustre uniquement la méthode la plus simple pour allumer l&amp;#039;écran. &lt;br /&gt;
        * Veuillez consulter la documentation pour connaître l&amp;#039;utilisation des différentes fonctions.&lt;br /&gt;
	* @version 0.1&lt;br /&gt;
	* @date 2022-01-30&lt;br /&gt;
	*&lt;br /&gt;
	* @copyright Copyright (c) 2022&lt;br /&gt;
	*&lt;br /&gt;
*/ &lt;br /&gt;
#include &amp;lt;Arduino.h&amp;gt;&lt;br /&gt;
#include &amp;lt;EPaperDrive.h&amp;gt;&lt;br /&gt;
// Inclure le système de fichiers à utiliser, par exemple:&lt;br /&gt;
#include &amp;lt;LittleFS.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define BAUD_SPEED 74880 // Débit en bauds pour le débogage du port série, modifiable selon les besoins&lt;br /&gt;
&lt;br /&gt;
#define CS 15&lt;br /&gt;
#define RST 2&lt;br /&gt;
#define DC 0&lt;br /&gt;
#define BUSY 4&lt;br /&gt;
#define CLK 14&lt;br /&gt;
#define DIN 13&lt;br /&gt;
&lt;br /&gt;
EPaperDrive EPD(0, CS, RST, DC, BUSY, CLK, DIN); //Instanciation de la bibliothèque de pilotes, utilisant ici le protocole SPI logiciel&lt;br /&gt;
&lt;br /&gt;
const uint8_t city_icon[24] = {&lt;br /&gt;
	/* 0X01,0X01,0X0C,0X00,0X0C,0X00, */&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X1C,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X77,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X41,&lt;br /&gt;
	0X80,&lt;br /&gt;
	0X9C,&lt;br /&gt;
	0X60,&lt;br /&gt;
	0XA2,&lt;br /&gt;
	0X30,&lt;br /&gt;
	0XA2,&lt;br /&gt;
	0X30,&lt;br /&gt;
	0X9C,&lt;br /&gt;
	0XC0,&lt;br /&gt;
	0X41,&lt;br /&gt;
	0X80,&lt;br /&gt;
	0X77,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X1C,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
	void setup()&lt;br /&gt;
	{&lt;br /&gt;
	Serial.begin(BAUD_SPEED);&lt;br /&gt;
	LittleFS.begin(); 			  // Veuillez initialiser manuellement le système de fichiers avant de passer le pointeur.&lt;br /&gt;
&lt;br /&gt;
	EPD.SetFS(&amp;amp;LittleFS); 			 // Définit le système de fichiers pour le stockage des polices. La valeur passée est le pointeur d&amp;#039;opération pour ce système de fichiers. &lt;br /&gt;
                                                 //Vous pouvez la modifier.&lt;br /&gt;
	EPD.EPD_Set_Model(HINKE0266A15A0); 	 // Définit le type d&amp;#039;écran. Consultez la documentation pour les modèles spécifiques.&lt;br /&gt;
	EPD.EPD_init_Full(); 			// Initialisation du rafraîchissement complet, en utilisant la forme d&amp;#039;onde de rafraîchissement complet.&lt;br /&gt;
	EPD.clearbuffer(); 		        // Efface le tampon (écran blanc).&lt;br /&gt;
	EPD.fontscale = 2; 			// Facteur d&amp;#039;échelle des polices (1 et 2 pris en charge, également applicable aux images. &lt;br /&gt;
                                                // N&amp;#039;oubliez pas de le remettre à 1 après utilisation).&lt;br /&gt;
	EPD.SetFont(FONT12); 		       // Sélectionne la police. Consultez la documentation pour connaître les polices prises en charge.&lt;br /&gt;
	EPD.DrawUTF(0, 0, &amp;quot;Hello&amp;quot;);            // Dessiner la chaîne&lt;br /&gt;
	EPD.DrawUTF(26, 0, &amp;quot;J&amp;#039;aime les écrans à encre électronique&amp;quot;); 	&lt;br /&gt;
                                               // Dessiner la chaîne&lt;br /&gt;
	EPD.fontscale = 1; 		       // Rétablir le facteur d&amp;#039;échelle de la police à 1&lt;br /&gt;
	EPD.DrawXbm_P(60, 0, 12, 12, (uint8_t *)city_icon); 			 // Dessiner l&amp;#039;image&lt;br /&gt;
&lt;br /&gt;
	Serial.printf(&amp;quot;Image tamponnée dessinée, prête pour un rafraîchissement complet\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_Dis_Full((uint8_t *)EPD.EPDbuffer, 1); // Transmettre l&amp;#039;image tamponnée à la puce de contrôle de l&amp;#039;écran pour un rafraîchissement complet&lt;br /&gt;
	EPD.deepsleep(); // Mettre l&amp;#039;écran en veille&lt;br /&gt;
	Serial.println(&amp;quot;Rafraîchissement complet terminé&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	delay(5000);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_init_Part(); // Initialiser la partie Actualisation&lt;br /&gt;
	EPD.clearbuffer();&lt;br /&gt;
	EPD.fontscale = 2;&lt;br /&gt;
	EPD.SetFont(FONT12); EPD.DrawUTF(0, 0, &amp;quot;Actualisation locale activée&amp;quot;);&lt;br /&gt;
	Serial.printf(&amp;quot;Actualisation locale en cours\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_Dis_Part(0, 23, 0, 199, (uint8_t *)EPD.EPDbuffer, 1); // Transfert de l&amp;#039;image du tampon vers la puce de contrôle d&amp;#039;écran pour l&amp;#039;actualisation locale sur le nouvel écran&lt;br /&gt;
	Serial.printf(&amp;quot;Actualisation locale terminée\n&amp;quot;);&lt;br /&gt;
	EPD.deepsleep();&lt;br /&gt;
&lt;br /&gt;
} void loop()&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
	delay(1); // Empêcher le chien de garde de s&amp;#039;interrompre&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>144.2.107.134</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1916</id>
		<title>CrowPanel-ESP32-E-Paper-HMI-1.54</title>
		<link rel="alternate" type="text/html" href="https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1916"/>
		<updated>2025-11-26T23:38:55Z</updated>

		<summary type="html">&lt;p&gt;144.2.107.134: /* Arduine Mise en route (Setup) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== E-Paper-HMI-1.54 (Elecrow) ==&lt;br /&gt;
&lt;br /&gt;
=== Liens externes ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_HMI_1.54-inch_Display.html Wiki&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_1.54-inch_Arduino_Tutorial.html Arduino Setup&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/crowpanel-esp32-1-54-e-paper-hmi-display-with-152-152-resolution-black-white-color-driven-by-spi-interface.html Shop&lt;br /&gt;
&lt;br /&gt;
 BLE debugging assistant&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/1-54-inch-152-152-e-paper-display-black-white-e-ink-display-with-spi-communication.html&lt;br /&gt;
&lt;br /&gt;
=== Caractéristiques ===&lt;br /&gt;
&lt;br /&gt;
Driver Chip : &amp;lt;b&amp;gt;SSD1680&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Résolution 152 x 152&amp;lt;br&amp;gt;&lt;br /&gt;
Couleur noir et blanc&amp;lt;br&amp;gt;&lt;br /&gt;
Pilote ESP32-S3 comme contrôleur principal&amp;lt;br&amp;gt;&lt;br /&gt;
PSRAM : 8MB&amp;lt;br&amp;gt;&lt;br /&gt;
Flash :	8MB&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Images ===&lt;br /&gt;
[[File:E-Paper-HMI-1.54-1.png|300px]]&lt;br /&gt;
&lt;br /&gt;
[[File:E-Paper-HMI-1.54-2.png|300px]]&lt;br /&gt;
[[File:E-Paper-HMI-1.54-3.png|300px]]&lt;br /&gt;
&lt;br /&gt;
=== Ressources ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/download/product/CrowPanel/E-paper/Image2Lcd_v2.9.zip Image2Lcd_v2.9&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152 GitHub&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152/archive/refs/heads/master.zip GitHub ZIP&lt;br /&gt;
&lt;br /&gt;
=== Arduine Mise en route (Setup) ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. Téléchargez les fichiers de bibliothèque utilisés par ce produit dans le dossier « bibliothèques ».&lt;br /&gt;
&lt;br /&gt;
C:\Users\Documents\Arduino\libraries\&lt;br /&gt;
&lt;br /&gt;
CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152-master/example/arduino/libraries/ &amp;lt;b&amp;gt;Voir sur GitHub&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Ouvrez l&amp;#039;IDE Arduino&amp;lt;br&amp;gt;&lt;br /&gt;
chercher &amp;lt;b&amp;gt;ESP32&amp;lt;/b&amp;gt; dans Boards Manager, installez si cela n&amp;#039;est pas déjà fait &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;by Espressif Systems&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. Click &amp;quot;Tools&amp;quot;-&amp;gt;&amp;quot;Board&amp;quot;-&amp;gt;&amp;quot;esp32&amp;quot;-&amp;gt;&amp;quot;&amp;lt;b&amp;gt;ESP32S3 Dev Module&amp;lt;/b&amp;gt;&amp;quot;, &lt;br /&gt;
&lt;br /&gt;
and the &amp;quot;Partition Scheme&amp;quot; select &lt;br /&gt;
&amp;quot;Huge APP (3MB No OTA/1MB SPIFFS)&amp;quot;, &lt;br /&gt;
&amp;quot;PSRAM&amp;quot; select &amp;quot;OPI PSRAM&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[File:Setup-Arduino-1.png|300px]]&lt;br /&gt;
&lt;br /&gt;
=== Librairies ===&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;Arduino.h&amp;gt;   // Inclure la bibliothèque principale Arduino&lt;br /&gt;
 #include &amp;quot;EPD_GUI.h&amp;quot;   // Inclure la bibliothèque pour l&amp;#039;écran à encre électronique&lt;br /&gt;
 #include &amp;quot;Pic.h&amp;quot;       // Inclure la bibliothèque de fonctions personnalisées&lt;br /&gt;
 #include &amp;quot;FS.h&amp;quot;        // Bibliothèque du système de fichiers pour les opérations sur les fichiers&lt;br /&gt;
 #include &amp;quot;SPIFFS.h&amp;quot;    // Bibliothèque du système de fichiers SPIFFS pour la lecture et l&amp;#039;écriture de fichiers&lt;br /&gt;
 #include &amp;lt;WiFi.h&amp;gt;      // Bibliothèque WiFi pour la création et la gestion des connexions WiFi&lt;br /&gt;
 #include &amp;lt;Ticker.h&amp;gt;    // Bibliothèque de chronométrage&lt;br /&gt;
 #include &amp;lt;WebServer.h&amp;gt; // Bibliothèque de serveur Web pour la création d&amp;#039;un serveur HTTP&lt;br /&gt;
&lt;br /&gt;
=== Code Exemples ===&lt;br /&gt;
&lt;br /&gt;
Arduino Code for demos&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_WIFI_refresh.ino &amp;lt;b&amp;gt;Update via WiFi&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_ble_refresh.ino  &amp;lt;b&amp;gt;Update via Bluetooth&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_wifi_http_openweather.ino&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arduino Code for examples&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_PWR.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_wifi.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_BLE.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_key.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_Global_refresh.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_partial_refresh.ino&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=smDFHRxDYdw&lt;br /&gt;
&lt;br /&gt;
=== Code wifi_http_openweather ===&lt;br /&gt;
&lt;br /&gt;
https://openweathermap.org/ Veuillez vous enregistrer afin de vous procurer votre OpenWeatherMap API key&lt;br /&gt;
&lt;br /&gt;
http://bulk.openweathermap.org/sample/ on trouve ici : city.list.json.gz, le countryCode de votre ville (variable city)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;lt;HTTPClient.h&amp;gt;&lt;br /&gt;
#include &amp;lt;Arduino_JSON.h&amp;gt;&lt;br /&gt;
#include &amp;quot;EPD_GUI.h&amp;quot;&lt;br /&gt;
#include &amp;quot;Pic.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
// Define an array for black and white image data, which serves as the buffer for the e-paper display.&lt;br /&gt;
// The size of the buffer is determined according to the resolution of the e-paper display.&lt;br /&gt;
uint8_t ImageBW[2888];&lt;br /&gt;
&lt;br /&gt;
// WiFi network name // WiFi password&lt;br /&gt;
const char* ssid = &amp;quot;yanfa_software&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;yanfa-123456&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// OpenWeatherMap API key. This key is used to access weather data from the OpenWeatherMap API.&lt;br /&gt;
String openWeatherMapApiKey = &amp;quot;3c03d1f4e2dd3e14474a9a3a2f2299ff&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// City and country code for which weather data will be fetched.&lt;br /&gt;
String city = &amp;quot;London&amp;quot;;&lt;br /&gt;
String countryCode = &amp;quot;2643743&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Variables related to timing and API calls.&lt;br /&gt;
// lastTime keeps track of the last time the API was called.&lt;br /&gt;
unsigned long lastTime = 0;&lt;br /&gt;
// timerDelay determines the time interval between API calls. For testing, it&amp;#039;s set to 10 seconds (10000 milliseconds).&lt;br /&gt;
// In a final application, this should be set according to the API call limits per hour/minute.&lt;br /&gt;
unsigned long timerDelay = 10000;&lt;br /&gt;
&lt;br /&gt;
// Variables related to JSON data.&lt;br /&gt;
// jsonBuffer stores the raw JSON data received from the API.&lt;br /&gt;
String jsonBuffer;&lt;br /&gt;
// httpResponseCode holds the response code from the HTTP request.&lt;br /&gt;
int httpResponseCode;&lt;br /&gt;
// myObject is a JSON variable that will hold the parsed JSON data.&lt;br /&gt;
JSONVar myObject;&lt;br /&gt;
&lt;br /&gt;
// Variables related to weather information.&lt;br /&gt;
// weather stores the main weather description.&lt;br /&gt;
String weather;&lt;br /&gt;
// temperature stores the temperature value.&lt;br /&gt;
String temperature;&lt;br /&gt;
// humidity stores the humidity value.&lt;br /&gt;
String humidity;&lt;br /&gt;
// sea_level stores the sea level value.&lt;br /&gt;
String sea_level;&lt;br /&gt;
// wind_speed stores the wind speed value.&lt;br /&gt;
String wind_speed;&lt;br /&gt;
// city_js stores the name of the city.&lt;br /&gt;
String city_js;&lt;br /&gt;
// weather_flag is a flag that determines which weather icon to display based on the weather description.&lt;br /&gt;
int weather_flag = 0;&lt;br /&gt;
&lt;br /&gt;
// Function to display weather forecast on the e-paper display.&lt;br /&gt;
void UI_weather_forecast()&lt;br /&gt;
{&lt;br /&gt;
  char buffer[40];&lt;br /&gt;
&lt;br /&gt;
  EPD_HW_RESET();&lt;br /&gt;
&lt;br /&gt;
  // Display a background picture on the e-paper.&lt;br /&gt;
  EPD_ShowPicture(0, 0, 152, 152, pic, BLACK);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  //If you need to replace the display options,&lt;br /&gt;
  //open the following options: temp, wind, visit, hum&lt;br /&gt;
  //The following uses the hum option as an example&lt;br /&gt;
&lt;br /&gt;
  //Visit&lt;br /&gt;
  //EPD_ShowPicture(76, 92, 56, 72, gImage_visit, BLACK);&lt;br /&gt;
  //Wind&lt;br /&gt;
  //EPD_ShowPicture(76, 92, 56, 72, gImage_wind, BLACK);&lt;br /&gt;
  //Temp&lt;br /&gt;
  //  EPD_ShowPicture(92, 0, 56, 72, gImage_temp, BLACK);&lt;br /&gt;
  //Hum&lt;br /&gt;
&lt;br /&gt;
  EPD_Display(ImageBW);&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_DeepSleep();&lt;br /&gt;
&lt;br /&gt;
  EPD_GPIOInit();&lt;br /&gt;
  Paint_NewImage(ImageBW, EPD_W, EPD_H, 270, WHITE);&lt;br /&gt;
  // Paint_Clear(WHITE);&lt;br /&gt;
  EPD_FastMode1Init();&lt;br /&gt;
  // EPD_Display_Clear();&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_Clear_R26H();&lt;br /&gt;
&lt;br /&gt;
  // Display the update time (it seems to be mislabeled as city_js here, might need to be corrected depending on the actual intention).&lt;br /&gt;
  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, city_js);&lt;br /&gt;
  EPD_ShowString(20, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //If you need to replace the display options,&lt;br /&gt;
  //open the following options: temp, wind, visit, hum&lt;br /&gt;
  //The following uses the hum option as an example&lt;br /&gt;
&lt;br /&gt;
  //Hum&lt;br /&gt;
  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, humidity);&lt;br /&gt;
  EPD_ShowString(105, 140, buffer,  12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //Temp&lt;br /&gt;
  //       memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  //       snprintf(buffer, sizeof(buffer), &amp;quot;%s C&amp;quot;, temperature);&lt;br /&gt;
  //       EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //Wind&lt;br /&gt;
  // memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  // snprintf(buffer, sizeof(buffer), &amp;quot;%s m/s&amp;quot;, wind_speed);&lt;br /&gt;
  // EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //visit&lt;br /&gt;
  //  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  //  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, sea_level);&lt;br /&gt;
  //  EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  // Update the e-paper display with the new content.&lt;br /&gt;
  EPD_Display(ImageBW);&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_DeepSleep();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200); // Initialize the serial communication.&lt;br /&gt;
&lt;br /&gt;
  // Connect to the WiFi network.&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  Serial.println(&amp;quot;Connecting&amp;quot;);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot;&amp;quot;);&lt;br /&gt;
  Serial.print(&amp;quot;Connected to WiFi network with IP Address: &amp;quot;);&lt;br /&gt;
  Serial.println(WiFi.localIP()); // Print the IP address of the device after successful connection.&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Timer set to 10 seconds (timerDelay variable), it will take 10 seconds before publishing the first reading.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Set pin 7 as an output pin to control the power of the e-paper display.&lt;br /&gt;
  pinMode(7, OUTPUT);&lt;br /&gt;
  digitalWrite(7, HIGH);&lt;br /&gt;
&lt;br /&gt;
  EPD_GPIOInit();&lt;br /&gt;
  Paint_NewImage(ImageBW, EPD_W, EPD_H, 0, WHITE);&lt;br /&gt;
  Paint_Clear(WHITE);&lt;br /&gt;
  EPD_FastMode1Init();&lt;br /&gt;
  EPD_Display_Clear();&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_Clear_R26H();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  js_analysis();&lt;br /&gt;
  UI_weather_forecast();&lt;br /&gt;
  delay(1000 * 60 * 60);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void js_analysis()&lt;br /&gt;
{&lt;br /&gt;
  // Check if the device is connected to the WiFi network.&lt;br /&gt;
  if (WiFi.status() == WL_CONNECTED) {&lt;br /&gt;
    // Construct the URL for the OpenWeatherMap API request.&lt;br /&gt;
    String serverPath = &amp;quot;http://api.openweathermap.org/data/2.5/weather?q=&amp;quot; + city + &amp;quot;,&amp;quot; + countryCode + &amp;quot;&amp;amp;APPID=&amp;quot; + openWeatherMapApiKey + &amp;quot;&amp;amp;units=metric&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    // Keep trying until a successful response (status code 200) is received.&lt;br /&gt;
    while (httpResponseCode != 200) {&lt;br /&gt;
      // Make an HTTP GET request to the API and store the response in jsonBuffer.&lt;br /&gt;
      jsonBuffer = httpGETRequest(serverPath.c_str());&lt;br /&gt;
      Serial.println(jsonBuffer);&lt;br /&gt;
      myObject = JSON.parse(jsonBuffer);&lt;br /&gt;
&lt;br /&gt;
      // Check if the JSON parsing was successful.&lt;br /&gt;
      if (JSON.typeof(myObject) == &amp;quot;undefined&amp;quot;) {&lt;br /&gt;
        Serial.println(&amp;quot;Parsing input failed!&amp;quot;);&lt;br /&gt;
        return;&lt;br /&gt;
      }&lt;br /&gt;
      delay(2000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Extract weather information from the parsed JSON data.&lt;br /&gt;
    weather = JSON.stringify(myObject[&amp;quot;weather&amp;quot;][0][&amp;quot;main&amp;quot;]);&lt;br /&gt;
    temperature = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;temp&amp;quot;]);&lt;br /&gt;
    humidity = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;humidity&amp;quot;]);&lt;br /&gt;
    sea_level = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;sea_level&amp;quot;]);&lt;br /&gt;
    wind_speed = JSON.stringify(myObject[&amp;quot;wind&amp;quot;][&amp;quot;speed&amp;quot;]);&lt;br /&gt;
    city_js = JSON.stringify(myObject[&amp;quot;name&amp;quot;]);&lt;br /&gt;
&lt;br /&gt;
    // Print the extracted weather information for debugging purposes.&lt;br /&gt;
    Serial.print(&amp;quot;String weather: &amp;quot;);&lt;br /&gt;
    Serial.println(weather);&lt;br /&gt;
    Serial.print(&amp;quot;String Temperature: &amp;quot;);&lt;br /&gt;
    Serial.println(temperature);&lt;br /&gt;
    Serial.print(&amp;quot;String humidity: &amp;quot;);&lt;br /&gt;
    Serial.println(humidity);&lt;br /&gt;
    Serial.print(&amp;quot;String sea_level: &amp;quot;);&lt;br /&gt;
    Serial.println(sea_level);&lt;br /&gt;
    Serial.print(&amp;quot;String wind_speed: &amp;quot;);&lt;br /&gt;
    Serial.println(wind_speed);&lt;br /&gt;
    Serial.print(&amp;quot;String city_js: &amp;quot;);&lt;br /&gt;
    Serial.println(city_js);&lt;br /&gt;
&lt;br /&gt;
    // Determine the weather icon based on the weather description.&lt;br /&gt;
    if (weather.indexOf(&amp;quot;clouds&amp;quot;) != -1 || weather.indexOf(&amp;quot;Clouds&amp;quot;) != -1 ) {&lt;br /&gt;
      weather_flag = 1;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;clear sky&amp;quot;) != -1 || weather.indexOf(&amp;quot;Clear sky&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 3;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;rain&amp;quot;) != -1 || weather.indexOf(&amp;quot;Rain&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 5;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;thunderstorm&amp;quot;) != -1 || weather.indexOf(&amp;quot;Thunderstorm&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 2;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;snow&amp;quot;) != -1 || weather.indexOf(&amp;quot;Snow&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 4;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;mist&amp;quot;) != -1 || weather.indexOf(&amp;quot;Mist&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 0;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
    // Print a message if the device is not connected to the WiFi network.&lt;br /&gt;
    Serial.println(&amp;quot;WiFi Disconnected&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Function to make an HTTP GET request and return the response.&lt;br /&gt;
String httpGETRequest(const char* serverName) {&lt;br /&gt;
  WiFiClient client;&lt;br /&gt;
  HTTPClient http;&lt;br /&gt;
&lt;br /&gt;
  // Initialize the HTTP client with the server name.&lt;br /&gt;
  http.begin(client, serverName);&lt;br /&gt;
&lt;br /&gt;
  // Send an HTTP GET request.&lt;br /&gt;
  httpResponseCode = http.GET();&lt;br /&gt;
&lt;br /&gt;
  // Initialize the response payload as an empty JSON object.&lt;br /&gt;
  String payload = &amp;quot;{}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  // Check if the response code is positive (indicating a successful request).&lt;br /&gt;
  if (httpResponseCode &amp;gt; 0) {&lt;br /&gt;
    Serial.print(&amp;quot;HTTP Response code: &amp;quot;);&lt;br /&gt;
    Serial.println(httpResponseCode);&lt;br /&gt;
    payload = http.getString();&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
    Serial.print(&amp;quot;Error code: &amp;quot;);&lt;br /&gt;
    Serial.println(httpResponseCode);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Close the HTTP connection.&lt;br /&gt;
  http.end();&lt;br /&gt;
&lt;br /&gt;
  return payload;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 Explications : Partie à modifier avec vos données, ssid, password, openWeatherMapApiKey, city, countryCode&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// WiFi network name // WiFi password&lt;br /&gt;
&lt;br /&gt;
const char* ssid = &amp;quot;yanfa_software&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;yanfa-123456&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// OpenWeatherMap API key. This key is used to access weather data from the OpenWeatherMap API.&lt;br /&gt;
String openWeatherMapApiKey = &amp;quot;3c03d1f4e2dd3e14474a9a3a2f2299ff&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// City and country code for which weather data will be fetched.&lt;br /&gt;
String city = &amp;quot;London&amp;quot;;&lt;br /&gt;
String countryCode = &amp;quot;2643743&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Code HelloWord ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
	* @file HelloWorld.ino&lt;br /&gt;
	* @author HalfSweet (Email:HalfSweet@HalfSweet.cn or QQ:2522182733)&lt;br /&gt;
	* @brief Ce fichier est un exemple de programme permettant d&amp;#039;afficher «Hello World» sur un écran à encre électronique. Il illustre uniquement la méthode la plus simple pour allumer l&amp;#039;écran. &lt;br /&gt;
        * Veuillez consulter la documentation pour connaître l&amp;#039;utilisation des différentes fonctions.&lt;br /&gt;
	* @version 0.1&lt;br /&gt;
	* @date 2022-01-30&lt;br /&gt;
	*&lt;br /&gt;
	* @copyright Copyright (c) 2022&lt;br /&gt;
	*&lt;br /&gt;
*/ &lt;br /&gt;
#include &amp;lt;Arduino.h&amp;gt;&lt;br /&gt;
#include &amp;lt;EPaperDrive.h&amp;gt;&lt;br /&gt;
// Inclure le système de fichiers à utiliser, par exemple:&lt;br /&gt;
#include &amp;lt;LittleFS.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define BAUD_SPEED 74880 // Débit en bauds pour le débogage du port série, modifiable selon les besoins&lt;br /&gt;
&lt;br /&gt;
#define CS 15&lt;br /&gt;
#define RST 2&lt;br /&gt;
#define DC 0&lt;br /&gt;
#define BUSY 4&lt;br /&gt;
#define CLK 14&lt;br /&gt;
#define DIN 13&lt;br /&gt;
&lt;br /&gt;
EPaperDrive EPD(0, CS, RST, DC, BUSY, CLK, DIN); //Instanciation de la bibliothèque de pilotes, utilisant ici le protocole SPI logiciel&lt;br /&gt;
&lt;br /&gt;
const uint8_t city_icon[24] = {&lt;br /&gt;
	/* 0X01,0X01,0X0C,0X00,0X0C,0X00, */&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X1C,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X77,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X41,&lt;br /&gt;
	0X80,&lt;br /&gt;
	0X9C,&lt;br /&gt;
	0X60,&lt;br /&gt;
	0XA2,&lt;br /&gt;
	0X30,&lt;br /&gt;
	0XA2,&lt;br /&gt;
	0X30,&lt;br /&gt;
	0X9C,&lt;br /&gt;
	0XC0,&lt;br /&gt;
	0X41,&lt;br /&gt;
	0X80,&lt;br /&gt;
	0X77,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X1C,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
	void setup()&lt;br /&gt;
	{&lt;br /&gt;
	Serial.begin(BAUD_SPEED);&lt;br /&gt;
	LittleFS.begin(); 			  // Veuillez initialiser manuellement le système de fichiers avant de passer le pointeur.&lt;br /&gt;
&lt;br /&gt;
	EPD.SetFS(&amp;amp;LittleFS); 			 // Définit le système de fichiers pour le stockage des polices. La valeur passée est le pointeur d&amp;#039;opération pour ce système de fichiers. &lt;br /&gt;
                                                 //Vous pouvez la modifier.&lt;br /&gt;
	EPD.EPD_Set_Model(HINKE0266A15A0); 	 // Définit le type d&amp;#039;écran. Consultez la documentation pour les modèles spécifiques.&lt;br /&gt;
	EPD.EPD_init_Full(); 			// Initialisation du rafraîchissement complet, en utilisant la forme d&amp;#039;onde de rafraîchissement complet.&lt;br /&gt;
	EPD.clearbuffer(); 		        // Efface le tampon (écran blanc).&lt;br /&gt;
	EPD.fontscale = 2; 			// Facteur d&amp;#039;échelle des polices (1 et 2 pris en charge, également applicable aux images. &lt;br /&gt;
                                                // N&amp;#039;oubliez pas de le remettre à 1 après utilisation).&lt;br /&gt;
	EPD.SetFont(FONT12); 		       // Sélectionne la police. Consultez la documentation pour connaître les polices prises en charge.&lt;br /&gt;
	EPD.DrawUTF(0, 0, &amp;quot;Hello&amp;quot;); &amp;quot;World&amp;quot;);  // Dessiner la chaîne&lt;br /&gt;
	EPD.DrawUTF(26, 0, &amp;quot;J&amp;#039;aime les écrans à encre électronique&amp;quot;); 	&lt;br /&gt;
                                               // Dessiner la chaîne&lt;br /&gt;
	EPD.fontscale = 1; 		       // Rétablir le facteur d&amp;#039;échelle de la police à 1&lt;br /&gt;
	EPD.DrawXbm_P(60, 0, 12, 12, (uint8_t *)city_icon); 			 // Dessiner l&amp;#039;image&lt;br /&gt;
&lt;br /&gt;
	Serial.printf(&amp;quot;Image tamponnée dessinée, prête pour un rafraîchissement complet\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_Dis_Full((uint8_t *)EPD.EPDbuffer, 1); // Transmettre l&amp;#039;image tamponnée à la puce de contrôle de l&amp;#039;écran pour un rafraîchissement complet&lt;br /&gt;
	EPD.deepsleep(); // Mettre l&amp;#039;écran en veille&lt;br /&gt;
	Serial.println(&amp;quot;Rafraîchissement complet terminé&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	delay(5000);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_init_Part(); // Initialiser la partie Actualisation&lt;br /&gt;
	EPD.clearbuffer();&lt;br /&gt;
	EPD.fontscale = 2;&lt;br /&gt;
	EPD.SetFont(FONT12); EPD.DrawUTF(0, 0, &amp;quot;Actualisation locale activée&amp;quot;);&lt;br /&gt;
	Serial.printf(&amp;quot;Actualisation locale en cours\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_Dis_Part(0, 23, 0, 199, (uint8_t *)EPD.EPDbuffer, 1); // Transfert de l&amp;#039;image du tampon vers la puce de contrôle d&amp;#039;écran pour l&amp;#039;actualisation locale sur le nouvel écran&lt;br /&gt;
	Serial.printf(&amp;quot;Actualisation locale terminée\n&amp;quot;);&lt;br /&gt;
	EPD.deepsleep();&lt;br /&gt;
&lt;br /&gt;
} void loop()&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
	delay(1); // Empêcher le chien de garde de s&amp;#039;interrompre&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>144.2.107.134</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1915</id>
		<title>CrowPanel-ESP32-E-Paper-HMI-1.54</title>
		<link rel="alternate" type="text/html" href="https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1915"/>
		<updated>2025-11-26T23:38:12Z</updated>

		<summary type="html">&lt;p&gt;144.2.107.134: /* Arduine Mise en route (Setup) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== E-Paper-HMI-1.54 (Elecrow) ==&lt;br /&gt;
&lt;br /&gt;
=== Liens externes ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_HMI_1.54-inch_Display.html Wiki&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_1.54-inch_Arduino_Tutorial.html Arduino Setup&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/crowpanel-esp32-1-54-e-paper-hmi-display-with-152-152-resolution-black-white-color-driven-by-spi-interface.html Shop&lt;br /&gt;
&lt;br /&gt;
 BLE debugging assistant&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/1-54-inch-152-152-e-paper-display-black-white-e-ink-display-with-spi-communication.html&lt;br /&gt;
&lt;br /&gt;
=== Caractéristiques ===&lt;br /&gt;
&lt;br /&gt;
Driver Chip : &amp;lt;b&amp;gt;SSD1680&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Résolution 152 x 152&amp;lt;br&amp;gt;&lt;br /&gt;
Couleur noir et blanc&amp;lt;br&amp;gt;&lt;br /&gt;
Pilote ESP32-S3 comme contrôleur principal&amp;lt;br&amp;gt;&lt;br /&gt;
PSRAM : 8MB&amp;lt;br&amp;gt;&lt;br /&gt;
Flash :	8MB&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Images ===&lt;br /&gt;
[[File:E-Paper-HMI-1.54-1.png|300px]]&lt;br /&gt;
&lt;br /&gt;
[[File:E-Paper-HMI-1.54-2.png|300px]]&lt;br /&gt;
[[File:E-Paper-HMI-1.54-3.png|300px]]&lt;br /&gt;
&lt;br /&gt;
=== Ressources ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/download/product/CrowPanel/E-paper/Image2Lcd_v2.9.zip Image2Lcd_v2.9&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152 GitHub&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152/archive/refs/heads/master.zip GitHub ZIP&lt;br /&gt;
&lt;br /&gt;
=== Arduine Mise en route (Setup) ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. Téléchargez les fichiers de bibliothèque utilisés par ce produit dans le dossier « bibliothèques ».&lt;br /&gt;
&lt;br /&gt;
C:\Users\Documents\Arduino\libraries\&lt;br /&gt;
&lt;br /&gt;
CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152-master/example/arduino/libraries/ &amp;lt;b&amp;gt;Voir sur GitHub&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Ouvrez l&amp;#039;IDE Arduino&amp;lt;br&amp;gt;&lt;br /&gt;
chercher ESP32 dans Boards Manager, installez si cela n&amp;#039;est pas déjà fait &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;by Espressif Systems&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. Click &amp;quot;Tools&amp;quot;-&amp;gt;&amp;quot;Board&amp;quot;-&amp;gt;&amp;quot;esp32&amp;quot;-&amp;gt;&amp;quot;&amp;lt;b&amp;gt;ESP32S3 Dev Module&amp;lt;/b&amp;gt;&amp;quot;, &lt;br /&gt;
&lt;br /&gt;
and the &amp;quot;Partition Scheme&amp;quot; select &lt;br /&gt;
&amp;quot;Huge APP (3MB No OTA/1MB SPIFFS)&amp;quot;, &lt;br /&gt;
&amp;quot;PSRAM&amp;quot; select &amp;quot;OPI PSRAM&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[File:Setup-Arduino-1.png|300px]]&lt;br /&gt;
&lt;br /&gt;
=== Librairies ===&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;Arduino.h&amp;gt;   // Inclure la bibliothèque principale Arduino&lt;br /&gt;
 #include &amp;quot;EPD_GUI.h&amp;quot;   // Inclure la bibliothèque pour l&amp;#039;écran à encre électronique&lt;br /&gt;
 #include &amp;quot;Pic.h&amp;quot;       // Inclure la bibliothèque de fonctions personnalisées&lt;br /&gt;
 #include &amp;quot;FS.h&amp;quot;        // Bibliothèque du système de fichiers pour les opérations sur les fichiers&lt;br /&gt;
 #include &amp;quot;SPIFFS.h&amp;quot;    // Bibliothèque du système de fichiers SPIFFS pour la lecture et l&amp;#039;écriture de fichiers&lt;br /&gt;
 #include &amp;lt;WiFi.h&amp;gt;      // Bibliothèque WiFi pour la création et la gestion des connexions WiFi&lt;br /&gt;
 #include &amp;lt;Ticker.h&amp;gt;    // Bibliothèque de chronométrage&lt;br /&gt;
 #include &amp;lt;WebServer.h&amp;gt; // Bibliothèque de serveur Web pour la création d&amp;#039;un serveur HTTP&lt;br /&gt;
&lt;br /&gt;
=== Code Exemples ===&lt;br /&gt;
&lt;br /&gt;
Arduino Code for demos&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_WIFI_refresh.ino &amp;lt;b&amp;gt;Update via WiFi&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_ble_refresh.ino  &amp;lt;b&amp;gt;Update via Bluetooth&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_wifi_http_openweather.ino&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arduino Code for examples&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_PWR.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_wifi.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_BLE.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_key.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_Global_refresh.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_partial_refresh.ino&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=smDFHRxDYdw&lt;br /&gt;
&lt;br /&gt;
=== Code wifi_http_openweather ===&lt;br /&gt;
&lt;br /&gt;
https://openweathermap.org/ Veuillez vous enregistrer afin de vous procurer votre OpenWeatherMap API key&lt;br /&gt;
&lt;br /&gt;
http://bulk.openweathermap.org/sample/ on trouve ici : city.list.json.gz, le countryCode de votre ville (variable city)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;lt;HTTPClient.h&amp;gt;&lt;br /&gt;
#include &amp;lt;Arduino_JSON.h&amp;gt;&lt;br /&gt;
#include &amp;quot;EPD_GUI.h&amp;quot;&lt;br /&gt;
#include &amp;quot;Pic.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
// Define an array for black and white image data, which serves as the buffer for the e-paper display.&lt;br /&gt;
// The size of the buffer is determined according to the resolution of the e-paper display.&lt;br /&gt;
uint8_t ImageBW[2888];&lt;br /&gt;
&lt;br /&gt;
// WiFi network name // WiFi password&lt;br /&gt;
const char* ssid = &amp;quot;yanfa_software&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;yanfa-123456&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// OpenWeatherMap API key. This key is used to access weather data from the OpenWeatherMap API.&lt;br /&gt;
String openWeatherMapApiKey = &amp;quot;3c03d1f4e2dd3e14474a9a3a2f2299ff&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// City and country code for which weather data will be fetched.&lt;br /&gt;
String city = &amp;quot;London&amp;quot;;&lt;br /&gt;
String countryCode = &amp;quot;2643743&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Variables related to timing and API calls.&lt;br /&gt;
// lastTime keeps track of the last time the API was called.&lt;br /&gt;
unsigned long lastTime = 0;&lt;br /&gt;
// timerDelay determines the time interval between API calls. For testing, it&amp;#039;s set to 10 seconds (10000 milliseconds).&lt;br /&gt;
// In a final application, this should be set according to the API call limits per hour/minute.&lt;br /&gt;
unsigned long timerDelay = 10000;&lt;br /&gt;
&lt;br /&gt;
// Variables related to JSON data.&lt;br /&gt;
// jsonBuffer stores the raw JSON data received from the API.&lt;br /&gt;
String jsonBuffer;&lt;br /&gt;
// httpResponseCode holds the response code from the HTTP request.&lt;br /&gt;
int httpResponseCode;&lt;br /&gt;
// myObject is a JSON variable that will hold the parsed JSON data.&lt;br /&gt;
JSONVar myObject;&lt;br /&gt;
&lt;br /&gt;
// Variables related to weather information.&lt;br /&gt;
// weather stores the main weather description.&lt;br /&gt;
String weather;&lt;br /&gt;
// temperature stores the temperature value.&lt;br /&gt;
String temperature;&lt;br /&gt;
// humidity stores the humidity value.&lt;br /&gt;
String humidity;&lt;br /&gt;
// sea_level stores the sea level value.&lt;br /&gt;
String sea_level;&lt;br /&gt;
// wind_speed stores the wind speed value.&lt;br /&gt;
String wind_speed;&lt;br /&gt;
// city_js stores the name of the city.&lt;br /&gt;
String city_js;&lt;br /&gt;
// weather_flag is a flag that determines which weather icon to display based on the weather description.&lt;br /&gt;
int weather_flag = 0;&lt;br /&gt;
&lt;br /&gt;
// Function to display weather forecast on the e-paper display.&lt;br /&gt;
void UI_weather_forecast()&lt;br /&gt;
{&lt;br /&gt;
  char buffer[40];&lt;br /&gt;
&lt;br /&gt;
  EPD_HW_RESET();&lt;br /&gt;
&lt;br /&gt;
  // Display a background picture on the e-paper.&lt;br /&gt;
  EPD_ShowPicture(0, 0, 152, 152, pic, BLACK);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  //If you need to replace the display options,&lt;br /&gt;
  //open the following options: temp, wind, visit, hum&lt;br /&gt;
  //The following uses the hum option as an example&lt;br /&gt;
&lt;br /&gt;
  //Visit&lt;br /&gt;
  //EPD_ShowPicture(76, 92, 56, 72, gImage_visit, BLACK);&lt;br /&gt;
  //Wind&lt;br /&gt;
  //EPD_ShowPicture(76, 92, 56, 72, gImage_wind, BLACK);&lt;br /&gt;
  //Temp&lt;br /&gt;
  //  EPD_ShowPicture(92, 0, 56, 72, gImage_temp, BLACK);&lt;br /&gt;
  //Hum&lt;br /&gt;
&lt;br /&gt;
  EPD_Display(ImageBW);&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_DeepSleep();&lt;br /&gt;
&lt;br /&gt;
  EPD_GPIOInit();&lt;br /&gt;
  Paint_NewImage(ImageBW, EPD_W, EPD_H, 270, WHITE);&lt;br /&gt;
  // Paint_Clear(WHITE);&lt;br /&gt;
  EPD_FastMode1Init();&lt;br /&gt;
  // EPD_Display_Clear();&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_Clear_R26H();&lt;br /&gt;
&lt;br /&gt;
  // Display the update time (it seems to be mislabeled as city_js here, might need to be corrected depending on the actual intention).&lt;br /&gt;
  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, city_js);&lt;br /&gt;
  EPD_ShowString(20, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //If you need to replace the display options,&lt;br /&gt;
  //open the following options: temp, wind, visit, hum&lt;br /&gt;
  //The following uses the hum option as an example&lt;br /&gt;
&lt;br /&gt;
  //Hum&lt;br /&gt;
  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, humidity);&lt;br /&gt;
  EPD_ShowString(105, 140, buffer,  12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //Temp&lt;br /&gt;
  //       memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  //       snprintf(buffer, sizeof(buffer), &amp;quot;%s C&amp;quot;, temperature);&lt;br /&gt;
  //       EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //Wind&lt;br /&gt;
  // memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  // snprintf(buffer, sizeof(buffer), &amp;quot;%s m/s&amp;quot;, wind_speed);&lt;br /&gt;
  // EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //visit&lt;br /&gt;
  //  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  //  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, sea_level);&lt;br /&gt;
  //  EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  // Update the e-paper display with the new content.&lt;br /&gt;
  EPD_Display(ImageBW);&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_DeepSleep();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200); // Initialize the serial communication.&lt;br /&gt;
&lt;br /&gt;
  // Connect to the WiFi network.&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  Serial.println(&amp;quot;Connecting&amp;quot;);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot;&amp;quot;);&lt;br /&gt;
  Serial.print(&amp;quot;Connected to WiFi network with IP Address: &amp;quot;);&lt;br /&gt;
  Serial.println(WiFi.localIP()); // Print the IP address of the device after successful connection.&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Timer set to 10 seconds (timerDelay variable), it will take 10 seconds before publishing the first reading.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Set pin 7 as an output pin to control the power of the e-paper display.&lt;br /&gt;
  pinMode(7, OUTPUT);&lt;br /&gt;
  digitalWrite(7, HIGH);&lt;br /&gt;
&lt;br /&gt;
  EPD_GPIOInit();&lt;br /&gt;
  Paint_NewImage(ImageBW, EPD_W, EPD_H, 0, WHITE);&lt;br /&gt;
  Paint_Clear(WHITE);&lt;br /&gt;
  EPD_FastMode1Init();&lt;br /&gt;
  EPD_Display_Clear();&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_Clear_R26H();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  js_analysis();&lt;br /&gt;
  UI_weather_forecast();&lt;br /&gt;
  delay(1000 * 60 * 60);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void js_analysis()&lt;br /&gt;
{&lt;br /&gt;
  // Check if the device is connected to the WiFi network.&lt;br /&gt;
  if (WiFi.status() == WL_CONNECTED) {&lt;br /&gt;
    // Construct the URL for the OpenWeatherMap API request.&lt;br /&gt;
    String serverPath = &amp;quot;http://api.openweathermap.org/data/2.5/weather?q=&amp;quot; + city + &amp;quot;,&amp;quot; + countryCode + &amp;quot;&amp;amp;APPID=&amp;quot; + openWeatherMapApiKey + &amp;quot;&amp;amp;units=metric&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    // Keep trying until a successful response (status code 200) is received.&lt;br /&gt;
    while (httpResponseCode != 200) {&lt;br /&gt;
      // Make an HTTP GET request to the API and store the response in jsonBuffer.&lt;br /&gt;
      jsonBuffer = httpGETRequest(serverPath.c_str());&lt;br /&gt;
      Serial.println(jsonBuffer);&lt;br /&gt;
      myObject = JSON.parse(jsonBuffer);&lt;br /&gt;
&lt;br /&gt;
      // Check if the JSON parsing was successful.&lt;br /&gt;
      if (JSON.typeof(myObject) == &amp;quot;undefined&amp;quot;) {&lt;br /&gt;
        Serial.println(&amp;quot;Parsing input failed!&amp;quot;);&lt;br /&gt;
        return;&lt;br /&gt;
      }&lt;br /&gt;
      delay(2000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Extract weather information from the parsed JSON data.&lt;br /&gt;
    weather = JSON.stringify(myObject[&amp;quot;weather&amp;quot;][0][&amp;quot;main&amp;quot;]);&lt;br /&gt;
    temperature = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;temp&amp;quot;]);&lt;br /&gt;
    humidity = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;humidity&amp;quot;]);&lt;br /&gt;
    sea_level = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;sea_level&amp;quot;]);&lt;br /&gt;
    wind_speed = JSON.stringify(myObject[&amp;quot;wind&amp;quot;][&amp;quot;speed&amp;quot;]);&lt;br /&gt;
    city_js = JSON.stringify(myObject[&amp;quot;name&amp;quot;]);&lt;br /&gt;
&lt;br /&gt;
    // Print the extracted weather information for debugging purposes.&lt;br /&gt;
    Serial.print(&amp;quot;String weather: &amp;quot;);&lt;br /&gt;
    Serial.println(weather);&lt;br /&gt;
    Serial.print(&amp;quot;String Temperature: &amp;quot;);&lt;br /&gt;
    Serial.println(temperature);&lt;br /&gt;
    Serial.print(&amp;quot;String humidity: &amp;quot;);&lt;br /&gt;
    Serial.println(humidity);&lt;br /&gt;
    Serial.print(&amp;quot;String sea_level: &amp;quot;);&lt;br /&gt;
    Serial.println(sea_level);&lt;br /&gt;
    Serial.print(&amp;quot;String wind_speed: &amp;quot;);&lt;br /&gt;
    Serial.println(wind_speed);&lt;br /&gt;
    Serial.print(&amp;quot;String city_js: &amp;quot;);&lt;br /&gt;
    Serial.println(city_js);&lt;br /&gt;
&lt;br /&gt;
    // Determine the weather icon based on the weather description.&lt;br /&gt;
    if (weather.indexOf(&amp;quot;clouds&amp;quot;) != -1 || weather.indexOf(&amp;quot;Clouds&amp;quot;) != -1 ) {&lt;br /&gt;
      weather_flag = 1;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;clear sky&amp;quot;) != -1 || weather.indexOf(&amp;quot;Clear sky&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 3;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;rain&amp;quot;) != -1 || weather.indexOf(&amp;quot;Rain&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 5;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;thunderstorm&amp;quot;) != -1 || weather.indexOf(&amp;quot;Thunderstorm&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 2;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;snow&amp;quot;) != -1 || weather.indexOf(&amp;quot;Snow&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 4;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;mist&amp;quot;) != -1 || weather.indexOf(&amp;quot;Mist&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 0;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
    // Print a message if the device is not connected to the WiFi network.&lt;br /&gt;
    Serial.println(&amp;quot;WiFi Disconnected&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Function to make an HTTP GET request and return the response.&lt;br /&gt;
String httpGETRequest(const char* serverName) {&lt;br /&gt;
  WiFiClient client;&lt;br /&gt;
  HTTPClient http;&lt;br /&gt;
&lt;br /&gt;
  // Initialize the HTTP client with the server name.&lt;br /&gt;
  http.begin(client, serverName);&lt;br /&gt;
&lt;br /&gt;
  // Send an HTTP GET request.&lt;br /&gt;
  httpResponseCode = http.GET();&lt;br /&gt;
&lt;br /&gt;
  // Initialize the response payload as an empty JSON object.&lt;br /&gt;
  String payload = &amp;quot;{}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  // Check if the response code is positive (indicating a successful request).&lt;br /&gt;
  if (httpResponseCode &amp;gt; 0) {&lt;br /&gt;
    Serial.print(&amp;quot;HTTP Response code: &amp;quot;);&lt;br /&gt;
    Serial.println(httpResponseCode);&lt;br /&gt;
    payload = http.getString();&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
    Serial.print(&amp;quot;Error code: &amp;quot;);&lt;br /&gt;
    Serial.println(httpResponseCode);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Close the HTTP connection.&lt;br /&gt;
  http.end();&lt;br /&gt;
&lt;br /&gt;
  return payload;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 Explications : Partie à modifier avec vos données, ssid, password, openWeatherMapApiKey, city, countryCode&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// WiFi network name // WiFi password&lt;br /&gt;
&lt;br /&gt;
const char* ssid = &amp;quot;yanfa_software&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;yanfa-123456&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// OpenWeatherMap API key. This key is used to access weather data from the OpenWeatherMap API.&lt;br /&gt;
String openWeatherMapApiKey = &amp;quot;3c03d1f4e2dd3e14474a9a3a2f2299ff&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// City and country code for which weather data will be fetched.&lt;br /&gt;
String city = &amp;quot;London&amp;quot;;&lt;br /&gt;
String countryCode = &amp;quot;2643743&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Code HelloWord ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
	* @file HelloWorld.ino&lt;br /&gt;
	* @author HalfSweet (Email:HalfSweet@HalfSweet.cn or QQ:2522182733)&lt;br /&gt;
	* @brief Ce fichier est un exemple de programme permettant d&amp;#039;afficher «Hello World» sur un écran à encre électronique. Il illustre uniquement la méthode la plus simple pour allumer l&amp;#039;écran. &lt;br /&gt;
        * Veuillez consulter la documentation pour connaître l&amp;#039;utilisation des différentes fonctions.&lt;br /&gt;
	* @version 0.1&lt;br /&gt;
	* @date 2022-01-30&lt;br /&gt;
	*&lt;br /&gt;
	* @copyright Copyright (c) 2022&lt;br /&gt;
	*&lt;br /&gt;
*/ &lt;br /&gt;
#include &amp;lt;Arduino.h&amp;gt;&lt;br /&gt;
#include &amp;lt;EPaperDrive.h&amp;gt;&lt;br /&gt;
// Inclure le système de fichiers à utiliser, par exemple:&lt;br /&gt;
#include &amp;lt;LittleFS.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define BAUD_SPEED 74880 // Débit en bauds pour le débogage du port série, modifiable selon les besoins&lt;br /&gt;
&lt;br /&gt;
#define CS 15&lt;br /&gt;
#define RST 2&lt;br /&gt;
#define DC 0&lt;br /&gt;
#define BUSY 4&lt;br /&gt;
#define CLK 14&lt;br /&gt;
#define DIN 13&lt;br /&gt;
&lt;br /&gt;
EPaperDrive EPD(0, CS, RST, DC, BUSY, CLK, DIN); //Instanciation de la bibliothèque de pilotes, utilisant ici le protocole SPI logiciel&lt;br /&gt;
&lt;br /&gt;
const uint8_t city_icon[24] = {&lt;br /&gt;
	/* 0X01,0X01,0X0C,0X00,0X0C,0X00, */&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X1C,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X77,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X41,&lt;br /&gt;
	0X80,&lt;br /&gt;
	0X9C,&lt;br /&gt;
	0X60,&lt;br /&gt;
	0XA2,&lt;br /&gt;
	0X30,&lt;br /&gt;
	0XA2,&lt;br /&gt;
	0X30,&lt;br /&gt;
	0X9C,&lt;br /&gt;
	0XC0,&lt;br /&gt;
	0X41,&lt;br /&gt;
	0X80,&lt;br /&gt;
	0X77,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X1C,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
	void setup()&lt;br /&gt;
	{&lt;br /&gt;
	Serial.begin(BAUD_SPEED);&lt;br /&gt;
	LittleFS.begin(); 			  // Veuillez initialiser manuellement le système de fichiers avant de passer le pointeur.&lt;br /&gt;
&lt;br /&gt;
	EPD.SetFS(&amp;amp;LittleFS); 			 // Définit le système de fichiers pour le stockage des polices. La valeur passée est le pointeur d&amp;#039;opération pour ce système de fichiers. &lt;br /&gt;
                                                 //Vous pouvez la modifier.&lt;br /&gt;
	EPD.EPD_Set_Model(HINKE0266A15A0); 	 // Définit le type d&amp;#039;écran. Consultez la documentation pour les modèles spécifiques.&lt;br /&gt;
	EPD.EPD_init_Full(); 			// Initialisation du rafraîchissement complet, en utilisant la forme d&amp;#039;onde de rafraîchissement complet.&lt;br /&gt;
	EPD.clearbuffer(); 		        // Efface le tampon (écran blanc).&lt;br /&gt;
	EPD.fontscale = 2; 			// Facteur d&amp;#039;échelle des polices (1 et 2 pris en charge, également applicable aux images. &lt;br /&gt;
                                                // N&amp;#039;oubliez pas de le remettre à 1 après utilisation).&lt;br /&gt;
	EPD.SetFont(FONT12); 		       // Sélectionne la police. Consultez la documentation pour connaître les polices prises en charge.&lt;br /&gt;
	EPD.DrawUTF(0, 0, &amp;quot;Hello&amp;quot;); &amp;quot;World&amp;quot;);  // Dessiner la chaîne&lt;br /&gt;
	EPD.DrawUTF(26, 0, &amp;quot;J&amp;#039;aime les écrans à encre électronique&amp;quot;); 	&lt;br /&gt;
                                               // Dessiner la chaîne&lt;br /&gt;
	EPD.fontscale = 1; 		       // Rétablir le facteur d&amp;#039;échelle de la police à 1&lt;br /&gt;
	EPD.DrawXbm_P(60, 0, 12, 12, (uint8_t *)city_icon); 			 // Dessiner l&amp;#039;image&lt;br /&gt;
&lt;br /&gt;
	Serial.printf(&amp;quot;Image tamponnée dessinée, prête pour un rafraîchissement complet\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_Dis_Full((uint8_t *)EPD.EPDbuffer, 1); // Transmettre l&amp;#039;image tamponnée à la puce de contrôle de l&amp;#039;écran pour un rafraîchissement complet&lt;br /&gt;
	EPD.deepsleep(); // Mettre l&amp;#039;écran en veille&lt;br /&gt;
	Serial.println(&amp;quot;Rafraîchissement complet terminé&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	delay(5000);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_init_Part(); // Initialiser la partie Actualisation&lt;br /&gt;
	EPD.clearbuffer();&lt;br /&gt;
	EPD.fontscale = 2;&lt;br /&gt;
	EPD.SetFont(FONT12); EPD.DrawUTF(0, 0, &amp;quot;Actualisation locale activée&amp;quot;);&lt;br /&gt;
	Serial.printf(&amp;quot;Actualisation locale en cours\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_Dis_Part(0, 23, 0, 199, (uint8_t *)EPD.EPDbuffer, 1); // Transfert de l&amp;#039;image du tampon vers la puce de contrôle d&amp;#039;écran pour l&amp;#039;actualisation locale sur le nouvel écran&lt;br /&gt;
	Serial.printf(&amp;quot;Actualisation locale terminée\n&amp;quot;);&lt;br /&gt;
	EPD.deepsleep();&lt;br /&gt;
&lt;br /&gt;
} void loop()&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
	delay(1); // Empêcher le chien de garde de s&amp;#039;interrompre&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>144.2.107.134</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1914</id>
		<title>CrowPanel-ESP32-E-Paper-HMI-1.54</title>
		<link rel="alternate" type="text/html" href="https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1914"/>
		<updated>2025-11-26T23:36:44Z</updated>

		<summary type="html">&lt;p&gt;144.2.107.134: /* Arduine Mise en route (Setup) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== E-Paper-HMI-1.54 (Elecrow) ==&lt;br /&gt;
&lt;br /&gt;
=== Liens externes ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_HMI_1.54-inch_Display.html Wiki&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_1.54-inch_Arduino_Tutorial.html Arduino Setup&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/crowpanel-esp32-1-54-e-paper-hmi-display-with-152-152-resolution-black-white-color-driven-by-spi-interface.html Shop&lt;br /&gt;
&lt;br /&gt;
 BLE debugging assistant&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/1-54-inch-152-152-e-paper-display-black-white-e-ink-display-with-spi-communication.html&lt;br /&gt;
&lt;br /&gt;
=== Caractéristiques ===&lt;br /&gt;
&lt;br /&gt;
Driver Chip : &amp;lt;b&amp;gt;SSD1680&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Résolution 152 x 152&amp;lt;br&amp;gt;&lt;br /&gt;
Couleur noir et blanc&amp;lt;br&amp;gt;&lt;br /&gt;
Pilote ESP32-S3 comme contrôleur principal&amp;lt;br&amp;gt;&lt;br /&gt;
PSRAM : 8MB&amp;lt;br&amp;gt;&lt;br /&gt;
Flash :	8MB&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Images ===&lt;br /&gt;
[[File:E-Paper-HMI-1.54-1.png|300px]]&lt;br /&gt;
&lt;br /&gt;
[[File:E-Paper-HMI-1.54-2.png|300px]]&lt;br /&gt;
[[File:E-Paper-HMI-1.54-3.png|300px]]&lt;br /&gt;
&lt;br /&gt;
=== Ressources ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/download/product/CrowPanel/E-paper/Image2Lcd_v2.9.zip Image2Lcd_v2.9&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152 GitHub&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152/archive/refs/heads/master.zip GitHub ZIP&lt;br /&gt;
&lt;br /&gt;
=== Arduine Mise en route (Setup) ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. Téléchargez les fichiers de bibliothèque utilisés par ce produit dans le dossier « bibliothèques ».&lt;br /&gt;
&lt;br /&gt;
C:\Users\Documents\Arduino\libraries\&lt;br /&gt;
&lt;br /&gt;
CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152-master/example/arduino/libraries/ &amp;lt;b&amp;gt;voir sur GitHub&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Ouvrez l&amp;#039;IDE Arduino&amp;lt;br&amp;gt;&lt;br /&gt;
chercher ESP32 dans Boards Manager, installez si cela n&amp;#039;est pas déjà fait &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;by Espressif Systems&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. Click &amp;quot;Tools&amp;quot;-&amp;gt;&amp;quot;Board&amp;quot;-&amp;gt;&amp;quot;esp32&amp;quot;-&amp;gt;&amp;quot;&amp;lt;b&amp;gt;ESP32S3 Dev Module&amp;lt;/b&amp;gt;&amp;quot;, &lt;br /&gt;
&lt;br /&gt;
and the &amp;quot;Partition Scheme&amp;quot; select &lt;br /&gt;
&amp;quot;Huge APP (3MB No OTA/1MB SPIFFS)&amp;quot;, &lt;br /&gt;
&amp;quot;PSRAM&amp;quot; select &amp;quot;OPI PSRAM&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[File:Setup-Arduino-1.png|300px]]&lt;br /&gt;
&lt;br /&gt;
=== Librairies ===&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;Arduino.h&amp;gt;   // Inclure la bibliothèque principale Arduino&lt;br /&gt;
 #include &amp;quot;EPD_GUI.h&amp;quot;   // Inclure la bibliothèque pour l&amp;#039;écran à encre électronique&lt;br /&gt;
 #include &amp;quot;Pic.h&amp;quot;       // Inclure la bibliothèque de fonctions personnalisées&lt;br /&gt;
 #include &amp;quot;FS.h&amp;quot;        // Bibliothèque du système de fichiers pour les opérations sur les fichiers&lt;br /&gt;
 #include &amp;quot;SPIFFS.h&amp;quot;    // Bibliothèque du système de fichiers SPIFFS pour la lecture et l&amp;#039;écriture de fichiers&lt;br /&gt;
 #include &amp;lt;WiFi.h&amp;gt;      // Bibliothèque WiFi pour la création et la gestion des connexions WiFi&lt;br /&gt;
 #include &amp;lt;Ticker.h&amp;gt;    // Bibliothèque de chronométrage&lt;br /&gt;
 #include &amp;lt;WebServer.h&amp;gt; // Bibliothèque de serveur Web pour la création d&amp;#039;un serveur HTTP&lt;br /&gt;
&lt;br /&gt;
=== Code Exemples ===&lt;br /&gt;
&lt;br /&gt;
Arduino Code for demos&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_WIFI_refresh.ino &amp;lt;b&amp;gt;Update via WiFi&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_ble_refresh.ino  &amp;lt;b&amp;gt;Update via Bluetooth&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_wifi_http_openweather.ino&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arduino Code for examples&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_PWR.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_wifi.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_BLE.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_key.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_Global_refresh.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_partial_refresh.ino&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=smDFHRxDYdw&lt;br /&gt;
&lt;br /&gt;
=== Code wifi_http_openweather ===&lt;br /&gt;
&lt;br /&gt;
https://openweathermap.org/ Veuillez vous enregistrer afin de vous procurer votre OpenWeatherMap API key&lt;br /&gt;
&lt;br /&gt;
http://bulk.openweathermap.org/sample/ on trouve ici : city.list.json.gz, le countryCode de votre ville (variable city)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;lt;HTTPClient.h&amp;gt;&lt;br /&gt;
#include &amp;lt;Arduino_JSON.h&amp;gt;&lt;br /&gt;
#include &amp;quot;EPD_GUI.h&amp;quot;&lt;br /&gt;
#include &amp;quot;Pic.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
// Define an array for black and white image data, which serves as the buffer for the e-paper display.&lt;br /&gt;
// The size of the buffer is determined according to the resolution of the e-paper display.&lt;br /&gt;
uint8_t ImageBW[2888];&lt;br /&gt;
&lt;br /&gt;
// WiFi network name // WiFi password&lt;br /&gt;
const char* ssid = &amp;quot;yanfa_software&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;yanfa-123456&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// OpenWeatherMap API key. This key is used to access weather data from the OpenWeatherMap API.&lt;br /&gt;
String openWeatherMapApiKey = &amp;quot;3c03d1f4e2dd3e14474a9a3a2f2299ff&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// City and country code for which weather data will be fetched.&lt;br /&gt;
String city = &amp;quot;London&amp;quot;;&lt;br /&gt;
String countryCode = &amp;quot;2643743&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Variables related to timing and API calls.&lt;br /&gt;
// lastTime keeps track of the last time the API was called.&lt;br /&gt;
unsigned long lastTime = 0;&lt;br /&gt;
// timerDelay determines the time interval between API calls. For testing, it&amp;#039;s set to 10 seconds (10000 milliseconds).&lt;br /&gt;
// In a final application, this should be set according to the API call limits per hour/minute.&lt;br /&gt;
unsigned long timerDelay = 10000;&lt;br /&gt;
&lt;br /&gt;
// Variables related to JSON data.&lt;br /&gt;
// jsonBuffer stores the raw JSON data received from the API.&lt;br /&gt;
String jsonBuffer;&lt;br /&gt;
// httpResponseCode holds the response code from the HTTP request.&lt;br /&gt;
int httpResponseCode;&lt;br /&gt;
// myObject is a JSON variable that will hold the parsed JSON data.&lt;br /&gt;
JSONVar myObject;&lt;br /&gt;
&lt;br /&gt;
// Variables related to weather information.&lt;br /&gt;
// weather stores the main weather description.&lt;br /&gt;
String weather;&lt;br /&gt;
// temperature stores the temperature value.&lt;br /&gt;
String temperature;&lt;br /&gt;
// humidity stores the humidity value.&lt;br /&gt;
String humidity;&lt;br /&gt;
// sea_level stores the sea level value.&lt;br /&gt;
String sea_level;&lt;br /&gt;
// wind_speed stores the wind speed value.&lt;br /&gt;
String wind_speed;&lt;br /&gt;
// city_js stores the name of the city.&lt;br /&gt;
String city_js;&lt;br /&gt;
// weather_flag is a flag that determines which weather icon to display based on the weather description.&lt;br /&gt;
int weather_flag = 0;&lt;br /&gt;
&lt;br /&gt;
// Function to display weather forecast on the e-paper display.&lt;br /&gt;
void UI_weather_forecast()&lt;br /&gt;
{&lt;br /&gt;
  char buffer[40];&lt;br /&gt;
&lt;br /&gt;
  EPD_HW_RESET();&lt;br /&gt;
&lt;br /&gt;
  // Display a background picture on the e-paper.&lt;br /&gt;
  EPD_ShowPicture(0, 0, 152, 152, pic, BLACK);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  //If you need to replace the display options,&lt;br /&gt;
  //open the following options: temp, wind, visit, hum&lt;br /&gt;
  //The following uses the hum option as an example&lt;br /&gt;
&lt;br /&gt;
  //Visit&lt;br /&gt;
  //EPD_ShowPicture(76, 92, 56, 72, gImage_visit, BLACK);&lt;br /&gt;
  //Wind&lt;br /&gt;
  //EPD_ShowPicture(76, 92, 56, 72, gImage_wind, BLACK);&lt;br /&gt;
  //Temp&lt;br /&gt;
  //  EPD_ShowPicture(92, 0, 56, 72, gImage_temp, BLACK);&lt;br /&gt;
  //Hum&lt;br /&gt;
&lt;br /&gt;
  EPD_Display(ImageBW);&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_DeepSleep();&lt;br /&gt;
&lt;br /&gt;
  EPD_GPIOInit();&lt;br /&gt;
  Paint_NewImage(ImageBW, EPD_W, EPD_H, 270, WHITE);&lt;br /&gt;
  // Paint_Clear(WHITE);&lt;br /&gt;
  EPD_FastMode1Init();&lt;br /&gt;
  // EPD_Display_Clear();&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_Clear_R26H();&lt;br /&gt;
&lt;br /&gt;
  // Display the update time (it seems to be mislabeled as city_js here, might need to be corrected depending on the actual intention).&lt;br /&gt;
  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, city_js);&lt;br /&gt;
  EPD_ShowString(20, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //If you need to replace the display options,&lt;br /&gt;
  //open the following options: temp, wind, visit, hum&lt;br /&gt;
  //The following uses the hum option as an example&lt;br /&gt;
&lt;br /&gt;
  //Hum&lt;br /&gt;
  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, humidity);&lt;br /&gt;
  EPD_ShowString(105, 140, buffer,  12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //Temp&lt;br /&gt;
  //       memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  //       snprintf(buffer, sizeof(buffer), &amp;quot;%s C&amp;quot;, temperature);&lt;br /&gt;
  //       EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //Wind&lt;br /&gt;
  // memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  // snprintf(buffer, sizeof(buffer), &amp;quot;%s m/s&amp;quot;, wind_speed);&lt;br /&gt;
  // EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //visit&lt;br /&gt;
  //  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  //  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, sea_level);&lt;br /&gt;
  //  EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  // Update the e-paper display with the new content.&lt;br /&gt;
  EPD_Display(ImageBW);&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_DeepSleep();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200); // Initialize the serial communication.&lt;br /&gt;
&lt;br /&gt;
  // Connect to the WiFi network.&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  Serial.println(&amp;quot;Connecting&amp;quot;);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot;&amp;quot;);&lt;br /&gt;
  Serial.print(&amp;quot;Connected to WiFi network with IP Address: &amp;quot;);&lt;br /&gt;
  Serial.println(WiFi.localIP()); // Print the IP address of the device after successful connection.&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Timer set to 10 seconds (timerDelay variable), it will take 10 seconds before publishing the first reading.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Set pin 7 as an output pin to control the power of the e-paper display.&lt;br /&gt;
  pinMode(7, OUTPUT);&lt;br /&gt;
  digitalWrite(7, HIGH);&lt;br /&gt;
&lt;br /&gt;
  EPD_GPIOInit();&lt;br /&gt;
  Paint_NewImage(ImageBW, EPD_W, EPD_H, 0, WHITE);&lt;br /&gt;
  Paint_Clear(WHITE);&lt;br /&gt;
  EPD_FastMode1Init();&lt;br /&gt;
  EPD_Display_Clear();&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_Clear_R26H();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  js_analysis();&lt;br /&gt;
  UI_weather_forecast();&lt;br /&gt;
  delay(1000 * 60 * 60);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void js_analysis()&lt;br /&gt;
{&lt;br /&gt;
  // Check if the device is connected to the WiFi network.&lt;br /&gt;
  if (WiFi.status() == WL_CONNECTED) {&lt;br /&gt;
    // Construct the URL for the OpenWeatherMap API request.&lt;br /&gt;
    String serverPath = &amp;quot;http://api.openweathermap.org/data/2.5/weather?q=&amp;quot; + city + &amp;quot;,&amp;quot; + countryCode + &amp;quot;&amp;amp;APPID=&amp;quot; + openWeatherMapApiKey + &amp;quot;&amp;amp;units=metric&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    // Keep trying until a successful response (status code 200) is received.&lt;br /&gt;
    while (httpResponseCode != 200) {&lt;br /&gt;
      // Make an HTTP GET request to the API and store the response in jsonBuffer.&lt;br /&gt;
      jsonBuffer = httpGETRequest(serverPath.c_str());&lt;br /&gt;
      Serial.println(jsonBuffer);&lt;br /&gt;
      myObject = JSON.parse(jsonBuffer);&lt;br /&gt;
&lt;br /&gt;
      // Check if the JSON parsing was successful.&lt;br /&gt;
      if (JSON.typeof(myObject) == &amp;quot;undefined&amp;quot;) {&lt;br /&gt;
        Serial.println(&amp;quot;Parsing input failed!&amp;quot;);&lt;br /&gt;
        return;&lt;br /&gt;
      }&lt;br /&gt;
      delay(2000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Extract weather information from the parsed JSON data.&lt;br /&gt;
    weather = JSON.stringify(myObject[&amp;quot;weather&amp;quot;][0][&amp;quot;main&amp;quot;]);&lt;br /&gt;
    temperature = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;temp&amp;quot;]);&lt;br /&gt;
    humidity = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;humidity&amp;quot;]);&lt;br /&gt;
    sea_level = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;sea_level&amp;quot;]);&lt;br /&gt;
    wind_speed = JSON.stringify(myObject[&amp;quot;wind&amp;quot;][&amp;quot;speed&amp;quot;]);&lt;br /&gt;
    city_js = JSON.stringify(myObject[&amp;quot;name&amp;quot;]);&lt;br /&gt;
&lt;br /&gt;
    // Print the extracted weather information for debugging purposes.&lt;br /&gt;
    Serial.print(&amp;quot;String weather: &amp;quot;);&lt;br /&gt;
    Serial.println(weather);&lt;br /&gt;
    Serial.print(&amp;quot;String Temperature: &amp;quot;);&lt;br /&gt;
    Serial.println(temperature);&lt;br /&gt;
    Serial.print(&amp;quot;String humidity: &amp;quot;);&lt;br /&gt;
    Serial.println(humidity);&lt;br /&gt;
    Serial.print(&amp;quot;String sea_level: &amp;quot;);&lt;br /&gt;
    Serial.println(sea_level);&lt;br /&gt;
    Serial.print(&amp;quot;String wind_speed: &amp;quot;);&lt;br /&gt;
    Serial.println(wind_speed);&lt;br /&gt;
    Serial.print(&amp;quot;String city_js: &amp;quot;);&lt;br /&gt;
    Serial.println(city_js);&lt;br /&gt;
&lt;br /&gt;
    // Determine the weather icon based on the weather description.&lt;br /&gt;
    if (weather.indexOf(&amp;quot;clouds&amp;quot;) != -1 || weather.indexOf(&amp;quot;Clouds&amp;quot;) != -1 ) {&lt;br /&gt;
      weather_flag = 1;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;clear sky&amp;quot;) != -1 || weather.indexOf(&amp;quot;Clear sky&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 3;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;rain&amp;quot;) != -1 || weather.indexOf(&amp;quot;Rain&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 5;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;thunderstorm&amp;quot;) != -1 || weather.indexOf(&amp;quot;Thunderstorm&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 2;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;snow&amp;quot;) != -1 || weather.indexOf(&amp;quot;Snow&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 4;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;mist&amp;quot;) != -1 || weather.indexOf(&amp;quot;Mist&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 0;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
    // Print a message if the device is not connected to the WiFi network.&lt;br /&gt;
    Serial.println(&amp;quot;WiFi Disconnected&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Function to make an HTTP GET request and return the response.&lt;br /&gt;
String httpGETRequest(const char* serverName) {&lt;br /&gt;
  WiFiClient client;&lt;br /&gt;
  HTTPClient http;&lt;br /&gt;
&lt;br /&gt;
  // Initialize the HTTP client with the server name.&lt;br /&gt;
  http.begin(client, serverName);&lt;br /&gt;
&lt;br /&gt;
  // Send an HTTP GET request.&lt;br /&gt;
  httpResponseCode = http.GET();&lt;br /&gt;
&lt;br /&gt;
  // Initialize the response payload as an empty JSON object.&lt;br /&gt;
  String payload = &amp;quot;{}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  // Check if the response code is positive (indicating a successful request).&lt;br /&gt;
  if (httpResponseCode &amp;gt; 0) {&lt;br /&gt;
    Serial.print(&amp;quot;HTTP Response code: &amp;quot;);&lt;br /&gt;
    Serial.println(httpResponseCode);&lt;br /&gt;
    payload = http.getString();&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
    Serial.print(&amp;quot;Error code: &amp;quot;);&lt;br /&gt;
    Serial.println(httpResponseCode);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Close the HTTP connection.&lt;br /&gt;
  http.end();&lt;br /&gt;
&lt;br /&gt;
  return payload;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 Explications : Partie à modifier avec vos données, ssid, password, openWeatherMapApiKey, city, countryCode&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// WiFi network name // WiFi password&lt;br /&gt;
&lt;br /&gt;
const char* ssid = &amp;quot;yanfa_software&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;yanfa-123456&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// OpenWeatherMap API key. This key is used to access weather data from the OpenWeatherMap API.&lt;br /&gt;
String openWeatherMapApiKey = &amp;quot;3c03d1f4e2dd3e14474a9a3a2f2299ff&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// City and country code for which weather data will be fetched.&lt;br /&gt;
String city = &amp;quot;London&amp;quot;;&lt;br /&gt;
String countryCode = &amp;quot;2643743&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Code HelloWord ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
	* @file HelloWorld.ino&lt;br /&gt;
	* @author HalfSweet (Email:HalfSweet@HalfSweet.cn or QQ:2522182733)&lt;br /&gt;
	* @brief Ce fichier est un exemple de programme permettant d&amp;#039;afficher «Hello World» sur un écran à encre électronique. Il illustre uniquement la méthode la plus simple pour allumer l&amp;#039;écran. &lt;br /&gt;
        * Veuillez consulter la documentation pour connaître l&amp;#039;utilisation des différentes fonctions.&lt;br /&gt;
	* @version 0.1&lt;br /&gt;
	* @date 2022-01-30&lt;br /&gt;
	*&lt;br /&gt;
	* @copyright Copyright (c) 2022&lt;br /&gt;
	*&lt;br /&gt;
*/ &lt;br /&gt;
#include &amp;lt;Arduino.h&amp;gt;&lt;br /&gt;
#include &amp;lt;EPaperDrive.h&amp;gt;&lt;br /&gt;
// Inclure le système de fichiers à utiliser, par exemple:&lt;br /&gt;
#include &amp;lt;LittleFS.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define BAUD_SPEED 74880 // Débit en bauds pour le débogage du port série, modifiable selon les besoins&lt;br /&gt;
&lt;br /&gt;
#define CS 15&lt;br /&gt;
#define RST 2&lt;br /&gt;
#define DC 0&lt;br /&gt;
#define BUSY 4&lt;br /&gt;
#define CLK 14&lt;br /&gt;
#define DIN 13&lt;br /&gt;
&lt;br /&gt;
EPaperDrive EPD(0, CS, RST, DC, BUSY, CLK, DIN); //Instanciation de la bibliothèque de pilotes, utilisant ici le protocole SPI logiciel&lt;br /&gt;
&lt;br /&gt;
const uint8_t city_icon[24] = {&lt;br /&gt;
	/* 0X01,0X01,0X0C,0X00,0X0C,0X00, */&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X1C,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X77,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X41,&lt;br /&gt;
	0X80,&lt;br /&gt;
	0X9C,&lt;br /&gt;
	0X60,&lt;br /&gt;
	0XA2,&lt;br /&gt;
	0X30,&lt;br /&gt;
	0XA2,&lt;br /&gt;
	0X30,&lt;br /&gt;
	0X9C,&lt;br /&gt;
	0XC0,&lt;br /&gt;
	0X41,&lt;br /&gt;
	0X80,&lt;br /&gt;
	0X77,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X1C,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
	void setup()&lt;br /&gt;
	{&lt;br /&gt;
	Serial.begin(BAUD_SPEED);&lt;br /&gt;
	LittleFS.begin(); 			  // Veuillez initialiser manuellement le système de fichiers avant de passer le pointeur.&lt;br /&gt;
&lt;br /&gt;
	EPD.SetFS(&amp;amp;LittleFS); 			 // Définit le système de fichiers pour le stockage des polices. La valeur passée est le pointeur d&amp;#039;opération pour ce système de fichiers. &lt;br /&gt;
                                                 //Vous pouvez la modifier.&lt;br /&gt;
	EPD.EPD_Set_Model(HINKE0266A15A0); 	 // Définit le type d&amp;#039;écran. Consultez la documentation pour les modèles spécifiques.&lt;br /&gt;
	EPD.EPD_init_Full(); 			// Initialisation du rafraîchissement complet, en utilisant la forme d&amp;#039;onde de rafraîchissement complet.&lt;br /&gt;
	EPD.clearbuffer(); 		        // Efface le tampon (écran blanc).&lt;br /&gt;
	EPD.fontscale = 2; 			// Facteur d&amp;#039;échelle des polices (1 et 2 pris en charge, également applicable aux images. &lt;br /&gt;
                                                // N&amp;#039;oubliez pas de le remettre à 1 après utilisation).&lt;br /&gt;
	EPD.SetFont(FONT12); 		       // Sélectionne la police. Consultez la documentation pour connaître les polices prises en charge.&lt;br /&gt;
	EPD.DrawUTF(0, 0, &amp;quot;Hello&amp;quot;); &amp;quot;World&amp;quot;);  // Dessiner la chaîne&lt;br /&gt;
	EPD.DrawUTF(26, 0, &amp;quot;J&amp;#039;aime les écrans à encre électronique&amp;quot;); 	&lt;br /&gt;
                                               // Dessiner la chaîne&lt;br /&gt;
	EPD.fontscale = 1; 		       // Rétablir le facteur d&amp;#039;échelle de la police à 1&lt;br /&gt;
	EPD.DrawXbm_P(60, 0, 12, 12, (uint8_t *)city_icon); 			 // Dessiner l&amp;#039;image&lt;br /&gt;
&lt;br /&gt;
	Serial.printf(&amp;quot;Image tamponnée dessinée, prête pour un rafraîchissement complet\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_Dis_Full((uint8_t *)EPD.EPDbuffer, 1); // Transmettre l&amp;#039;image tamponnée à la puce de contrôle de l&amp;#039;écran pour un rafraîchissement complet&lt;br /&gt;
	EPD.deepsleep(); // Mettre l&amp;#039;écran en veille&lt;br /&gt;
	Serial.println(&amp;quot;Rafraîchissement complet terminé&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	delay(5000);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_init_Part(); // Initialiser la partie Actualisation&lt;br /&gt;
	EPD.clearbuffer();&lt;br /&gt;
	EPD.fontscale = 2;&lt;br /&gt;
	EPD.SetFont(FONT12); EPD.DrawUTF(0, 0, &amp;quot;Actualisation locale activée&amp;quot;);&lt;br /&gt;
	Serial.printf(&amp;quot;Actualisation locale en cours\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_Dis_Part(0, 23, 0, 199, (uint8_t *)EPD.EPDbuffer, 1); // Transfert de l&amp;#039;image du tampon vers la puce de contrôle d&amp;#039;écran pour l&amp;#039;actualisation locale sur le nouvel écran&lt;br /&gt;
	Serial.printf(&amp;quot;Actualisation locale terminée\n&amp;quot;);&lt;br /&gt;
	EPD.deepsleep();&lt;br /&gt;
&lt;br /&gt;
} void loop()&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
	delay(1); // Empêcher le chien de garde de s&amp;#039;interrompre&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>144.2.107.134</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1913</id>
		<title>CrowPanel-ESP32-E-Paper-HMI-1.54</title>
		<link rel="alternate" type="text/html" href="https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1913"/>
		<updated>2025-11-26T23:36:15Z</updated>

		<summary type="html">&lt;p&gt;144.2.107.134: /* Arduine Mise en route (Setup) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== E-Paper-HMI-1.54 (Elecrow) ==&lt;br /&gt;
&lt;br /&gt;
=== Liens externes ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_HMI_1.54-inch_Display.html Wiki&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_1.54-inch_Arduino_Tutorial.html Arduino Setup&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/crowpanel-esp32-1-54-e-paper-hmi-display-with-152-152-resolution-black-white-color-driven-by-spi-interface.html Shop&lt;br /&gt;
&lt;br /&gt;
 BLE debugging assistant&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/1-54-inch-152-152-e-paper-display-black-white-e-ink-display-with-spi-communication.html&lt;br /&gt;
&lt;br /&gt;
=== Caractéristiques ===&lt;br /&gt;
&lt;br /&gt;
Driver Chip : &amp;lt;b&amp;gt;SSD1680&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Résolution 152 x 152&amp;lt;br&amp;gt;&lt;br /&gt;
Couleur noir et blanc&amp;lt;br&amp;gt;&lt;br /&gt;
Pilote ESP32-S3 comme contrôleur principal&amp;lt;br&amp;gt;&lt;br /&gt;
PSRAM : 8MB&amp;lt;br&amp;gt;&lt;br /&gt;
Flash :	8MB&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Images ===&lt;br /&gt;
[[File:E-Paper-HMI-1.54-1.png|300px]]&lt;br /&gt;
&lt;br /&gt;
[[File:E-Paper-HMI-1.54-2.png|300px]]&lt;br /&gt;
[[File:E-Paper-HMI-1.54-3.png|300px]]&lt;br /&gt;
&lt;br /&gt;
=== Ressources ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/download/product/CrowPanel/E-paper/Image2Lcd_v2.9.zip Image2Lcd_v2.9&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152 GitHub&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152/archive/refs/heads/master.zip GitHub ZIP&lt;br /&gt;
&lt;br /&gt;
=== Arduine Mise en route (Setup) ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. Téléchargez les fichiers de bibliothèque utilisés par ce produit dans le dossier « bibliothèques ».&lt;br /&gt;
&lt;br /&gt;
C:\Users\Documents\Arduino\libraries\&lt;br /&gt;
&lt;br /&gt;
CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152-master/example/arduino/libraries/ voir sur GitHub&lt;br /&gt;
&lt;br /&gt;
2. Ouvrez l&amp;#039;IDE Arduino&amp;lt;br&amp;gt;&lt;br /&gt;
chercher ESP32 dans Boards Manager, installez si cela n&amp;#039;est pas déjà fait &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;by Espressif Systems&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. Click &amp;quot;Tools&amp;quot;-&amp;gt;&amp;quot;Board&amp;quot;-&amp;gt;&amp;quot;esp32&amp;quot;-&amp;gt;&amp;quot;&amp;lt;b&amp;gt;ESP32S3 Dev Module&amp;lt;/b&amp;gt;&amp;quot;, &lt;br /&gt;
&lt;br /&gt;
and the &amp;quot;Partition Scheme&amp;quot; select &lt;br /&gt;
&amp;quot;Huge APP (3MB No OTA/1MB SPIFFS)&amp;quot;, &lt;br /&gt;
&amp;quot;PSRAM&amp;quot; select &amp;quot;OPI PSRAM&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[File:Setup-Arduino-1.png|300px]]&lt;br /&gt;
&lt;br /&gt;
=== Librairies ===&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;Arduino.h&amp;gt;   // Inclure la bibliothèque principale Arduino&lt;br /&gt;
 #include &amp;quot;EPD_GUI.h&amp;quot;   // Inclure la bibliothèque pour l&amp;#039;écran à encre électronique&lt;br /&gt;
 #include &amp;quot;Pic.h&amp;quot;       // Inclure la bibliothèque de fonctions personnalisées&lt;br /&gt;
 #include &amp;quot;FS.h&amp;quot;        // Bibliothèque du système de fichiers pour les opérations sur les fichiers&lt;br /&gt;
 #include &amp;quot;SPIFFS.h&amp;quot;    // Bibliothèque du système de fichiers SPIFFS pour la lecture et l&amp;#039;écriture de fichiers&lt;br /&gt;
 #include &amp;lt;WiFi.h&amp;gt;      // Bibliothèque WiFi pour la création et la gestion des connexions WiFi&lt;br /&gt;
 #include &amp;lt;Ticker.h&amp;gt;    // Bibliothèque de chronométrage&lt;br /&gt;
 #include &amp;lt;WebServer.h&amp;gt; // Bibliothèque de serveur Web pour la création d&amp;#039;un serveur HTTP&lt;br /&gt;
&lt;br /&gt;
=== Code Exemples ===&lt;br /&gt;
&lt;br /&gt;
Arduino Code for demos&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_WIFI_refresh.ino &amp;lt;b&amp;gt;Update via WiFi&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_ble_refresh.ino  &amp;lt;b&amp;gt;Update via Bluetooth&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_wifi_http_openweather.ino&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arduino Code for examples&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_PWR.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_wifi.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_BLE.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_key.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_Global_refresh.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_partial_refresh.ino&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=smDFHRxDYdw&lt;br /&gt;
&lt;br /&gt;
=== Code wifi_http_openweather ===&lt;br /&gt;
&lt;br /&gt;
https://openweathermap.org/ Veuillez vous enregistrer afin de vous procurer votre OpenWeatherMap API key&lt;br /&gt;
&lt;br /&gt;
http://bulk.openweathermap.org/sample/ on trouve ici : city.list.json.gz, le countryCode de votre ville (variable city)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;lt;HTTPClient.h&amp;gt;&lt;br /&gt;
#include &amp;lt;Arduino_JSON.h&amp;gt;&lt;br /&gt;
#include &amp;quot;EPD_GUI.h&amp;quot;&lt;br /&gt;
#include &amp;quot;Pic.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
// Define an array for black and white image data, which serves as the buffer for the e-paper display.&lt;br /&gt;
// The size of the buffer is determined according to the resolution of the e-paper display.&lt;br /&gt;
uint8_t ImageBW[2888];&lt;br /&gt;
&lt;br /&gt;
// WiFi network name // WiFi password&lt;br /&gt;
const char* ssid = &amp;quot;yanfa_software&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;yanfa-123456&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// OpenWeatherMap API key. This key is used to access weather data from the OpenWeatherMap API.&lt;br /&gt;
String openWeatherMapApiKey = &amp;quot;3c03d1f4e2dd3e14474a9a3a2f2299ff&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// City and country code for which weather data will be fetched.&lt;br /&gt;
String city = &amp;quot;London&amp;quot;;&lt;br /&gt;
String countryCode = &amp;quot;2643743&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Variables related to timing and API calls.&lt;br /&gt;
// lastTime keeps track of the last time the API was called.&lt;br /&gt;
unsigned long lastTime = 0;&lt;br /&gt;
// timerDelay determines the time interval between API calls. For testing, it&amp;#039;s set to 10 seconds (10000 milliseconds).&lt;br /&gt;
// In a final application, this should be set according to the API call limits per hour/minute.&lt;br /&gt;
unsigned long timerDelay = 10000;&lt;br /&gt;
&lt;br /&gt;
// Variables related to JSON data.&lt;br /&gt;
// jsonBuffer stores the raw JSON data received from the API.&lt;br /&gt;
String jsonBuffer;&lt;br /&gt;
// httpResponseCode holds the response code from the HTTP request.&lt;br /&gt;
int httpResponseCode;&lt;br /&gt;
// myObject is a JSON variable that will hold the parsed JSON data.&lt;br /&gt;
JSONVar myObject;&lt;br /&gt;
&lt;br /&gt;
// Variables related to weather information.&lt;br /&gt;
// weather stores the main weather description.&lt;br /&gt;
String weather;&lt;br /&gt;
// temperature stores the temperature value.&lt;br /&gt;
String temperature;&lt;br /&gt;
// humidity stores the humidity value.&lt;br /&gt;
String humidity;&lt;br /&gt;
// sea_level stores the sea level value.&lt;br /&gt;
String sea_level;&lt;br /&gt;
// wind_speed stores the wind speed value.&lt;br /&gt;
String wind_speed;&lt;br /&gt;
// city_js stores the name of the city.&lt;br /&gt;
String city_js;&lt;br /&gt;
// weather_flag is a flag that determines which weather icon to display based on the weather description.&lt;br /&gt;
int weather_flag = 0;&lt;br /&gt;
&lt;br /&gt;
// Function to display weather forecast on the e-paper display.&lt;br /&gt;
void UI_weather_forecast()&lt;br /&gt;
{&lt;br /&gt;
  char buffer[40];&lt;br /&gt;
&lt;br /&gt;
  EPD_HW_RESET();&lt;br /&gt;
&lt;br /&gt;
  // Display a background picture on the e-paper.&lt;br /&gt;
  EPD_ShowPicture(0, 0, 152, 152, pic, BLACK);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  //If you need to replace the display options,&lt;br /&gt;
  //open the following options: temp, wind, visit, hum&lt;br /&gt;
  //The following uses the hum option as an example&lt;br /&gt;
&lt;br /&gt;
  //Visit&lt;br /&gt;
  //EPD_ShowPicture(76, 92, 56, 72, gImage_visit, BLACK);&lt;br /&gt;
  //Wind&lt;br /&gt;
  //EPD_ShowPicture(76, 92, 56, 72, gImage_wind, BLACK);&lt;br /&gt;
  //Temp&lt;br /&gt;
  //  EPD_ShowPicture(92, 0, 56, 72, gImage_temp, BLACK);&lt;br /&gt;
  //Hum&lt;br /&gt;
&lt;br /&gt;
  EPD_Display(ImageBW);&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_DeepSleep();&lt;br /&gt;
&lt;br /&gt;
  EPD_GPIOInit();&lt;br /&gt;
  Paint_NewImage(ImageBW, EPD_W, EPD_H, 270, WHITE);&lt;br /&gt;
  // Paint_Clear(WHITE);&lt;br /&gt;
  EPD_FastMode1Init();&lt;br /&gt;
  // EPD_Display_Clear();&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_Clear_R26H();&lt;br /&gt;
&lt;br /&gt;
  // Display the update time (it seems to be mislabeled as city_js here, might need to be corrected depending on the actual intention).&lt;br /&gt;
  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, city_js);&lt;br /&gt;
  EPD_ShowString(20, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //If you need to replace the display options,&lt;br /&gt;
  //open the following options: temp, wind, visit, hum&lt;br /&gt;
  //The following uses the hum option as an example&lt;br /&gt;
&lt;br /&gt;
  //Hum&lt;br /&gt;
  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, humidity);&lt;br /&gt;
  EPD_ShowString(105, 140, buffer,  12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //Temp&lt;br /&gt;
  //       memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  //       snprintf(buffer, sizeof(buffer), &amp;quot;%s C&amp;quot;, temperature);&lt;br /&gt;
  //       EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //Wind&lt;br /&gt;
  // memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  // snprintf(buffer, sizeof(buffer), &amp;quot;%s m/s&amp;quot;, wind_speed);&lt;br /&gt;
  // EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //visit&lt;br /&gt;
  //  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  //  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, sea_level);&lt;br /&gt;
  //  EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  // Update the e-paper display with the new content.&lt;br /&gt;
  EPD_Display(ImageBW);&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_DeepSleep();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200); // Initialize the serial communication.&lt;br /&gt;
&lt;br /&gt;
  // Connect to the WiFi network.&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  Serial.println(&amp;quot;Connecting&amp;quot;);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot;&amp;quot;);&lt;br /&gt;
  Serial.print(&amp;quot;Connected to WiFi network with IP Address: &amp;quot;);&lt;br /&gt;
  Serial.println(WiFi.localIP()); // Print the IP address of the device after successful connection.&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Timer set to 10 seconds (timerDelay variable), it will take 10 seconds before publishing the first reading.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Set pin 7 as an output pin to control the power of the e-paper display.&lt;br /&gt;
  pinMode(7, OUTPUT);&lt;br /&gt;
  digitalWrite(7, HIGH);&lt;br /&gt;
&lt;br /&gt;
  EPD_GPIOInit();&lt;br /&gt;
  Paint_NewImage(ImageBW, EPD_W, EPD_H, 0, WHITE);&lt;br /&gt;
  Paint_Clear(WHITE);&lt;br /&gt;
  EPD_FastMode1Init();&lt;br /&gt;
  EPD_Display_Clear();&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_Clear_R26H();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  js_analysis();&lt;br /&gt;
  UI_weather_forecast();&lt;br /&gt;
  delay(1000 * 60 * 60);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void js_analysis()&lt;br /&gt;
{&lt;br /&gt;
  // Check if the device is connected to the WiFi network.&lt;br /&gt;
  if (WiFi.status() == WL_CONNECTED) {&lt;br /&gt;
    // Construct the URL for the OpenWeatherMap API request.&lt;br /&gt;
    String serverPath = &amp;quot;http://api.openweathermap.org/data/2.5/weather?q=&amp;quot; + city + &amp;quot;,&amp;quot; + countryCode + &amp;quot;&amp;amp;APPID=&amp;quot; + openWeatherMapApiKey + &amp;quot;&amp;amp;units=metric&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    // Keep trying until a successful response (status code 200) is received.&lt;br /&gt;
    while (httpResponseCode != 200) {&lt;br /&gt;
      // Make an HTTP GET request to the API and store the response in jsonBuffer.&lt;br /&gt;
      jsonBuffer = httpGETRequest(serverPath.c_str());&lt;br /&gt;
      Serial.println(jsonBuffer);&lt;br /&gt;
      myObject = JSON.parse(jsonBuffer);&lt;br /&gt;
&lt;br /&gt;
      // Check if the JSON parsing was successful.&lt;br /&gt;
      if (JSON.typeof(myObject) == &amp;quot;undefined&amp;quot;) {&lt;br /&gt;
        Serial.println(&amp;quot;Parsing input failed!&amp;quot;);&lt;br /&gt;
        return;&lt;br /&gt;
      }&lt;br /&gt;
      delay(2000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Extract weather information from the parsed JSON data.&lt;br /&gt;
    weather = JSON.stringify(myObject[&amp;quot;weather&amp;quot;][0][&amp;quot;main&amp;quot;]);&lt;br /&gt;
    temperature = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;temp&amp;quot;]);&lt;br /&gt;
    humidity = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;humidity&amp;quot;]);&lt;br /&gt;
    sea_level = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;sea_level&amp;quot;]);&lt;br /&gt;
    wind_speed = JSON.stringify(myObject[&amp;quot;wind&amp;quot;][&amp;quot;speed&amp;quot;]);&lt;br /&gt;
    city_js = JSON.stringify(myObject[&amp;quot;name&amp;quot;]);&lt;br /&gt;
&lt;br /&gt;
    // Print the extracted weather information for debugging purposes.&lt;br /&gt;
    Serial.print(&amp;quot;String weather: &amp;quot;);&lt;br /&gt;
    Serial.println(weather);&lt;br /&gt;
    Serial.print(&amp;quot;String Temperature: &amp;quot;);&lt;br /&gt;
    Serial.println(temperature);&lt;br /&gt;
    Serial.print(&amp;quot;String humidity: &amp;quot;);&lt;br /&gt;
    Serial.println(humidity);&lt;br /&gt;
    Serial.print(&amp;quot;String sea_level: &amp;quot;);&lt;br /&gt;
    Serial.println(sea_level);&lt;br /&gt;
    Serial.print(&amp;quot;String wind_speed: &amp;quot;);&lt;br /&gt;
    Serial.println(wind_speed);&lt;br /&gt;
    Serial.print(&amp;quot;String city_js: &amp;quot;);&lt;br /&gt;
    Serial.println(city_js);&lt;br /&gt;
&lt;br /&gt;
    // Determine the weather icon based on the weather description.&lt;br /&gt;
    if (weather.indexOf(&amp;quot;clouds&amp;quot;) != -1 || weather.indexOf(&amp;quot;Clouds&amp;quot;) != -1 ) {&lt;br /&gt;
      weather_flag = 1;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;clear sky&amp;quot;) != -1 || weather.indexOf(&amp;quot;Clear sky&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 3;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;rain&amp;quot;) != -1 || weather.indexOf(&amp;quot;Rain&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 5;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;thunderstorm&amp;quot;) != -1 || weather.indexOf(&amp;quot;Thunderstorm&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 2;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;snow&amp;quot;) != -1 || weather.indexOf(&amp;quot;Snow&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 4;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;mist&amp;quot;) != -1 || weather.indexOf(&amp;quot;Mist&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 0;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
    // Print a message if the device is not connected to the WiFi network.&lt;br /&gt;
    Serial.println(&amp;quot;WiFi Disconnected&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Function to make an HTTP GET request and return the response.&lt;br /&gt;
String httpGETRequest(const char* serverName) {&lt;br /&gt;
  WiFiClient client;&lt;br /&gt;
  HTTPClient http;&lt;br /&gt;
&lt;br /&gt;
  // Initialize the HTTP client with the server name.&lt;br /&gt;
  http.begin(client, serverName);&lt;br /&gt;
&lt;br /&gt;
  // Send an HTTP GET request.&lt;br /&gt;
  httpResponseCode = http.GET();&lt;br /&gt;
&lt;br /&gt;
  // Initialize the response payload as an empty JSON object.&lt;br /&gt;
  String payload = &amp;quot;{}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  // Check if the response code is positive (indicating a successful request).&lt;br /&gt;
  if (httpResponseCode &amp;gt; 0) {&lt;br /&gt;
    Serial.print(&amp;quot;HTTP Response code: &amp;quot;);&lt;br /&gt;
    Serial.println(httpResponseCode);&lt;br /&gt;
    payload = http.getString();&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
    Serial.print(&amp;quot;Error code: &amp;quot;);&lt;br /&gt;
    Serial.println(httpResponseCode);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Close the HTTP connection.&lt;br /&gt;
  http.end();&lt;br /&gt;
&lt;br /&gt;
  return payload;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 Explications : Partie à modifier avec vos données, ssid, password, openWeatherMapApiKey, city, countryCode&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// WiFi network name // WiFi password&lt;br /&gt;
&lt;br /&gt;
const char* ssid = &amp;quot;yanfa_software&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;yanfa-123456&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// OpenWeatherMap API key. This key is used to access weather data from the OpenWeatherMap API.&lt;br /&gt;
String openWeatherMapApiKey = &amp;quot;3c03d1f4e2dd3e14474a9a3a2f2299ff&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// City and country code for which weather data will be fetched.&lt;br /&gt;
String city = &amp;quot;London&amp;quot;;&lt;br /&gt;
String countryCode = &amp;quot;2643743&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Code HelloWord ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
	* @file HelloWorld.ino&lt;br /&gt;
	* @author HalfSweet (Email:HalfSweet@HalfSweet.cn or QQ:2522182733)&lt;br /&gt;
	* @brief Ce fichier est un exemple de programme permettant d&amp;#039;afficher «Hello World» sur un écran à encre électronique. Il illustre uniquement la méthode la plus simple pour allumer l&amp;#039;écran. &lt;br /&gt;
        * Veuillez consulter la documentation pour connaître l&amp;#039;utilisation des différentes fonctions.&lt;br /&gt;
	* @version 0.1&lt;br /&gt;
	* @date 2022-01-30&lt;br /&gt;
	*&lt;br /&gt;
	* @copyright Copyright (c) 2022&lt;br /&gt;
	*&lt;br /&gt;
*/ &lt;br /&gt;
#include &amp;lt;Arduino.h&amp;gt;&lt;br /&gt;
#include &amp;lt;EPaperDrive.h&amp;gt;&lt;br /&gt;
// Inclure le système de fichiers à utiliser, par exemple:&lt;br /&gt;
#include &amp;lt;LittleFS.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define BAUD_SPEED 74880 // Débit en bauds pour le débogage du port série, modifiable selon les besoins&lt;br /&gt;
&lt;br /&gt;
#define CS 15&lt;br /&gt;
#define RST 2&lt;br /&gt;
#define DC 0&lt;br /&gt;
#define BUSY 4&lt;br /&gt;
#define CLK 14&lt;br /&gt;
#define DIN 13&lt;br /&gt;
&lt;br /&gt;
EPaperDrive EPD(0, CS, RST, DC, BUSY, CLK, DIN); //Instanciation de la bibliothèque de pilotes, utilisant ici le protocole SPI logiciel&lt;br /&gt;
&lt;br /&gt;
const uint8_t city_icon[24] = {&lt;br /&gt;
	/* 0X01,0X01,0X0C,0X00,0X0C,0X00, */&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X1C,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X77,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X41,&lt;br /&gt;
	0X80,&lt;br /&gt;
	0X9C,&lt;br /&gt;
	0X60,&lt;br /&gt;
	0XA2,&lt;br /&gt;
	0X30,&lt;br /&gt;
	0XA2,&lt;br /&gt;
	0X30,&lt;br /&gt;
	0X9C,&lt;br /&gt;
	0XC0,&lt;br /&gt;
	0X41,&lt;br /&gt;
	0X80,&lt;br /&gt;
	0X77,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X1C,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
	void setup()&lt;br /&gt;
	{&lt;br /&gt;
	Serial.begin(BAUD_SPEED);&lt;br /&gt;
	LittleFS.begin(); 			  // Veuillez initialiser manuellement le système de fichiers avant de passer le pointeur.&lt;br /&gt;
&lt;br /&gt;
	EPD.SetFS(&amp;amp;LittleFS); 			 // Définit le système de fichiers pour le stockage des polices. La valeur passée est le pointeur d&amp;#039;opération pour ce système de fichiers. &lt;br /&gt;
                                                 //Vous pouvez la modifier.&lt;br /&gt;
	EPD.EPD_Set_Model(HINKE0266A15A0); 	 // Définit le type d&amp;#039;écran. Consultez la documentation pour les modèles spécifiques.&lt;br /&gt;
	EPD.EPD_init_Full(); 			// Initialisation du rafraîchissement complet, en utilisant la forme d&amp;#039;onde de rafraîchissement complet.&lt;br /&gt;
	EPD.clearbuffer(); 		        // Efface le tampon (écran blanc).&lt;br /&gt;
	EPD.fontscale = 2; 			// Facteur d&amp;#039;échelle des polices (1 et 2 pris en charge, également applicable aux images. &lt;br /&gt;
                                                // N&amp;#039;oubliez pas de le remettre à 1 après utilisation).&lt;br /&gt;
	EPD.SetFont(FONT12); 		       // Sélectionne la police. Consultez la documentation pour connaître les polices prises en charge.&lt;br /&gt;
	EPD.DrawUTF(0, 0, &amp;quot;Hello&amp;quot;); &amp;quot;World&amp;quot;);  // Dessiner la chaîne&lt;br /&gt;
	EPD.DrawUTF(26, 0, &amp;quot;J&amp;#039;aime les écrans à encre électronique&amp;quot;); 	&lt;br /&gt;
                                               // Dessiner la chaîne&lt;br /&gt;
	EPD.fontscale = 1; 		       // Rétablir le facteur d&amp;#039;échelle de la police à 1&lt;br /&gt;
	EPD.DrawXbm_P(60, 0, 12, 12, (uint8_t *)city_icon); 			 // Dessiner l&amp;#039;image&lt;br /&gt;
&lt;br /&gt;
	Serial.printf(&amp;quot;Image tamponnée dessinée, prête pour un rafraîchissement complet\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_Dis_Full((uint8_t *)EPD.EPDbuffer, 1); // Transmettre l&amp;#039;image tamponnée à la puce de contrôle de l&amp;#039;écran pour un rafraîchissement complet&lt;br /&gt;
	EPD.deepsleep(); // Mettre l&amp;#039;écran en veille&lt;br /&gt;
	Serial.println(&amp;quot;Rafraîchissement complet terminé&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	delay(5000);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_init_Part(); // Initialiser la partie Actualisation&lt;br /&gt;
	EPD.clearbuffer();&lt;br /&gt;
	EPD.fontscale = 2;&lt;br /&gt;
	EPD.SetFont(FONT12); EPD.DrawUTF(0, 0, &amp;quot;Actualisation locale activée&amp;quot;);&lt;br /&gt;
	Serial.printf(&amp;quot;Actualisation locale en cours\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_Dis_Part(0, 23, 0, 199, (uint8_t *)EPD.EPDbuffer, 1); // Transfert de l&amp;#039;image du tampon vers la puce de contrôle d&amp;#039;écran pour l&amp;#039;actualisation locale sur le nouvel écran&lt;br /&gt;
	Serial.printf(&amp;quot;Actualisation locale terminée\n&amp;quot;);&lt;br /&gt;
	EPD.deepsleep();&lt;br /&gt;
&lt;br /&gt;
} void loop()&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
	delay(1); // Empêcher le chien de garde de s&amp;#039;interrompre&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>144.2.107.134</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1912</id>
		<title>CrowPanel-ESP32-E-Paper-HMI-1.54</title>
		<link rel="alternate" type="text/html" href="https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1912"/>
		<updated>2025-11-26T23:31:58Z</updated>

		<summary type="html">&lt;p&gt;144.2.107.134: /* Arduine Mise en route (Setup) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== E-Paper-HMI-1.54 (Elecrow) ==&lt;br /&gt;
&lt;br /&gt;
=== Liens externes ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_HMI_1.54-inch_Display.html Wiki&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_1.54-inch_Arduino_Tutorial.html Arduino Setup&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/crowpanel-esp32-1-54-e-paper-hmi-display-with-152-152-resolution-black-white-color-driven-by-spi-interface.html Shop&lt;br /&gt;
&lt;br /&gt;
 BLE debugging assistant&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/1-54-inch-152-152-e-paper-display-black-white-e-ink-display-with-spi-communication.html&lt;br /&gt;
&lt;br /&gt;
=== Caractéristiques ===&lt;br /&gt;
&lt;br /&gt;
Driver Chip : &amp;lt;b&amp;gt;SSD1680&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Résolution 152 x 152&amp;lt;br&amp;gt;&lt;br /&gt;
Couleur noir et blanc&amp;lt;br&amp;gt;&lt;br /&gt;
Pilote ESP32-S3 comme contrôleur principal&amp;lt;br&amp;gt;&lt;br /&gt;
PSRAM : 8MB&amp;lt;br&amp;gt;&lt;br /&gt;
Flash :	8MB&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Images ===&lt;br /&gt;
[[File:E-Paper-HMI-1.54-1.png|300px]]&lt;br /&gt;
&lt;br /&gt;
[[File:E-Paper-HMI-1.54-2.png|300px]]&lt;br /&gt;
[[File:E-Paper-HMI-1.54-3.png|300px]]&lt;br /&gt;
&lt;br /&gt;
=== Ressources ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/download/product/CrowPanel/E-paper/Image2Lcd_v2.9.zip Image2Lcd_v2.9&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152 GitHub&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152/archive/refs/heads/master.zip GitHub ZIP&lt;br /&gt;
&lt;br /&gt;
=== Arduine Mise en route (Setup) ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. Téléchargez les fichiers de bibliothèque utilisés par ce produit dans le dossier « bibliothèques ».&lt;br /&gt;
&lt;br /&gt;
C:\Users\Documents\Arduino\libraries\&lt;br /&gt;
&lt;br /&gt;
CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152-master/example/arduino/libraries/&lt;br /&gt;
&lt;br /&gt;
2. Ouvrez l&amp;#039;IDE Arduino&amp;lt;br&amp;gt;&lt;br /&gt;
chercher ESP32 dans Boards Manager, installez si cela n&amp;#039;est pas déjà fait &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;by Espressif Systems&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. Click &amp;quot;Tools&amp;quot;-&amp;gt;&amp;quot;Board&amp;quot;-&amp;gt;&amp;quot;esp32&amp;quot;-&amp;gt;&amp;quot;&amp;lt;b&amp;gt;ESP32S3 Dev Module&amp;lt;/b&amp;gt;&amp;quot;, &lt;br /&gt;
&lt;br /&gt;
and the &amp;quot;Partition Scheme&amp;quot; select &lt;br /&gt;
&amp;quot;Huge APP (3MB No OTA/1MB SPIFFS)&amp;quot;, &lt;br /&gt;
&amp;quot;PSRAM&amp;quot; select &amp;quot;OPI PSRAM&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[File:Setup-Arduino-1.png|300px]]&lt;br /&gt;
&lt;br /&gt;
=== Librairies ===&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;Arduino.h&amp;gt;   // Inclure la bibliothèque principale Arduino&lt;br /&gt;
 #include &amp;quot;EPD_GUI.h&amp;quot;   // Inclure la bibliothèque pour l&amp;#039;écran à encre électronique&lt;br /&gt;
 #include &amp;quot;Pic.h&amp;quot;       // Inclure la bibliothèque de fonctions personnalisées&lt;br /&gt;
 #include &amp;quot;FS.h&amp;quot;        // Bibliothèque du système de fichiers pour les opérations sur les fichiers&lt;br /&gt;
 #include &amp;quot;SPIFFS.h&amp;quot;    // Bibliothèque du système de fichiers SPIFFS pour la lecture et l&amp;#039;écriture de fichiers&lt;br /&gt;
 #include &amp;lt;WiFi.h&amp;gt;      // Bibliothèque WiFi pour la création et la gestion des connexions WiFi&lt;br /&gt;
 #include &amp;lt;Ticker.h&amp;gt;    // Bibliothèque de chronométrage&lt;br /&gt;
 #include &amp;lt;WebServer.h&amp;gt; // Bibliothèque de serveur Web pour la création d&amp;#039;un serveur HTTP&lt;br /&gt;
&lt;br /&gt;
=== Code Exemples ===&lt;br /&gt;
&lt;br /&gt;
Arduino Code for demos&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_WIFI_refresh.ino &amp;lt;b&amp;gt;Update via WiFi&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_ble_refresh.ino  &amp;lt;b&amp;gt;Update via Bluetooth&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_wifi_http_openweather.ino&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arduino Code for examples&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_PWR.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_wifi.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_BLE.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_key.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_Global_refresh.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_partial_refresh.ino&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=smDFHRxDYdw&lt;br /&gt;
&lt;br /&gt;
=== Code wifi_http_openweather ===&lt;br /&gt;
&lt;br /&gt;
https://openweathermap.org/ Veuillez vous enregistrer afin de vous procurer votre OpenWeatherMap API key&lt;br /&gt;
&lt;br /&gt;
http://bulk.openweathermap.org/sample/ on trouve ici : city.list.json.gz, le countryCode de votre ville (variable city)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;lt;HTTPClient.h&amp;gt;&lt;br /&gt;
#include &amp;lt;Arduino_JSON.h&amp;gt;&lt;br /&gt;
#include &amp;quot;EPD_GUI.h&amp;quot;&lt;br /&gt;
#include &amp;quot;Pic.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
// Define an array for black and white image data, which serves as the buffer for the e-paper display.&lt;br /&gt;
// The size of the buffer is determined according to the resolution of the e-paper display.&lt;br /&gt;
uint8_t ImageBW[2888];&lt;br /&gt;
&lt;br /&gt;
// WiFi network name // WiFi password&lt;br /&gt;
const char* ssid = &amp;quot;yanfa_software&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;yanfa-123456&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// OpenWeatherMap API key. This key is used to access weather data from the OpenWeatherMap API.&lt;br /&gt;
String openWeatherMapApiKey = &amp;quot;3c03d1f4e2dd3e14474a9a3a2f2299ff&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// City and country code for which weather data will be fetched.&lt;br /&gt;
String city = &amp;quot;London&amp;quot;;&lt;br /&gt;
String countryCode = &amp;quot;2643743&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Variables related to timing and API calls.&lt;br /&gt;
// lastTime keeps track of the last time the API was called.&lt;br /&gt;
unsigned long lastTime = 0;&lt;br /&gt;
// timerDelay determines the time interval between API calls. For testing, it&amp;#039;s set to 10 seconds (10000 milliseconds).&lt;br /&gt;
// In a final application, this should be set according to the API call limits per hour/minute.&lt;br /&gt;
unsigned long timerDelay = 10000;&lt;br /&gt;
&lt;br /&gt;
// Variables related to JSON data.&lt;br /&gt;
// jsonBuffer stores the raw JSON data received from the API.&lt;br /&gt;
String jsonBuffer;&lt;br /&gt;
// httpResponseCode holds the response code from the HTTP request.&lt;br /&gt;
int httpResponseCode;&lt;br /&gt;
// myObject is a JSON variable that will hold the parsed JSON data.&lt;br /&gt;
JSONVar myObject;&lt;br /&gt;
&lt;br /&gt;
// Variables related to weather information.&lt;br /&gt;
// weather stores the main weather description.&lt;br /&gt;
String weather;&lt;br /&gt;
// temperature stores the temperature value.&lt;br /&gt;
String temperature;&lt;br /&gt;
// humidity stores the humidity value.&lt;br /&gt;
String humidity;&lt;br /&gt;
// sea_level stores the sea level value.&lt;br /&gt;
String sea_level;&lt;br /&gt;
// wind_speed stores the wind speed value.&lt;br /&gt;
String wind_speed;&lt;br /&gt;
// city_js stores the name of the city.&lt;br /&gt;
String city_js;&lt;br /&gt;
// weather_flag is a flag that determines which weather icon to display based on the weather description.&lt;br /&gt;
int weather_flag = 0;&lt;br /&gt;
&lt;br /&gt;
// Function to display weather forecast on the e-paper display.&lt;br /&gt;
void UI_weather_forecast()&lt;br /&gt;
{&lt;br /&gt;
  char buffer[40];&lt;br /&gt;
&lt;br /&gt;
  EPD_HW_RESET();&lt;br /&gt;
&lt;br /&gt;
  // Display a background picture on the e-paper.&lt;br /&gt;
  EPD_ShowPicture(0, 0, 152, 152, pic, BLACK);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  //If you need to replace the display options,&lt;br /&gt;
  //open the following options: temp, wind, visit, hum&lt;br /&gt;
  //The following uses the hum option as an example&lt;br /&gt;
&lt;br /&gt;
  //Visit&lt;br /&gt;
  //EPD_ShowPicture(76, 92, 56, 72, gImage_visit, BLACK);&lt;br /&gt;
  //Wind&lt;br /&gt;
  //EPD_ShowPicture(76, 92, 56, 72, gImage_wind, BLACK);&lt;br /&gt;
  //Temp&lt;br /&gt;
  //  EPD_ShowPicture(92, 0, 56, 72, gImage_temp, BLACK);&lt;br /&gt;
  //Hum&lt;br /&gt;
&lt;br /&gt;
  EPD_Display(ImageBW);&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_DeepSleep();&lt;br /&gt;
&lt;br /&gt;
  EPD_GPIOInit();&lt;br /&gt;
  Paint_NewImage(ImageBW, EPD_W, EPD_H, 270, WHITE);&lt;br /&gt;
  // Paint_Clear(WHITE);&lt;br /&gt;
  EPD_FastMode1Init();&lt;br /&gt;
  // EPD_Display_Clear();&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_Clear_R26H();&lt;br /&gt;
&lt;br /&gt;
  // Display the update time (it seems to be mislabeled as city_js here, might need to be corrected depending on the actual intention).&lt;br /&gt;
  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, city_js);&lt;br /&gt;
  EPD_ShowString(20, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //If you need to replace the display options,&lt;br /&gt;
  //open the following options: temp, wind, visit, hum&lt;br /&gt;
  //The following uses the hum option as an example&lt;br /&gt;
&lt;br /&gt;
  //Hum&lt;br /&gt;
  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, humidity);&lt;br /&gt;
  EPD_ShowString(105, 140, buffer,  12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //Temp&lt;br /&gt;
  //       memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  //       snprintf(buffer, sizeof(buffer), &amp;quot;%s C&amp;quot;, temperature);&lt;br /&gt;
  //       EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //Wind&lt;br /&gt;
  // memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  // snprintf(buffer, sizeof(buffer), &amp;quot;%s m/s&amp;quot;, wind_speed);&lt;br /&gt;
  // EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //visit&lt;br /&gt;
  //  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  //  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, sea_level);&lt;br /&gt;
  //  EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  // Update the e-paper display with the new content.&lt;br /&gt;
  EPD_Display(ImageBW);&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_DeepSleep();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200); // Initialize the serial communication.&lt;br /&gt;
&lt;br /&gt;
  // Connect to the WiFi network.&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  Serial.println(&amp;quot;Connecting&amp;quot;);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot;&amp;quot;);&lt;br /&gt;
  Serial.print(&amp;quot;Connected to WiFi network with IP Address: &amp;quot;);&lt;br /&gt;
  Serial.println(WiFi.localIP()); // Print the IP address of the device after successful connection.&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Timer set to 10 seconds (timerDelay variable), it will take 10 seconds before publishing the first reading.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Set pin 7 as an output pin to control the power of the e-paper display.&lt;br /&gt;
  pinMode(7, OUTPUT);&lt;br /&gt;
  digitalWrite(7, HIGH);&lt;br /&gt;
&lt;br /&gt;
  EPD_GPIOInit();&lt;br /&gt;
  Paint_NewImage(ImageBW, EPD_W, EPD_H, 0, WHITE);&lt;br /&gt;
  Paint_Clear(WHITE);&lt;br /&gt;
  EPD_FastMode1Init();&lt;br /&gt;
  EPD_Display_Clear();&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_Clear_R26H();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  js_analysis();&lt;br /&gt;
  UI_weather_forecast();&lt;br /&gt;
  delay(1000 * 60 * 60);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void js_analysis()&lt;br /&gt;
{&lt;br /&gt;
  // Check if the device is connected to the WiFi network.&lt;br /&gt;
  if (WiFi.status() == WL_CONNECTED) {&lt;br /&gt;
    // Construct the URL for the OpenWeatherMap API request.&lt;br /&gt;
    String serverPath = &amp;quot;http://api.openweathermap.org/data/2.5/weather?q=&amp;quot; + city + &amp;quot;,&amp;quot; + countryCode + &amp;quot;&amp;amp;APPID=&amp;quot; + openWeatherMapApiKey + &amp;quot;&amp;amp;units=metric&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    // Keep trying until a successful response (status code 200) is received.&lt;br /&gt;
    while (httpResponseCode != 200) {&lt;br /&gt;
      // Make an HTTP GET request to the API and store the response in jsonBuffer.&lt;br /&gt;
      jsonBuffer = httpGETRequest(serverPath.c_str());&lt;br /&gt;
      Serial.println(jsonBuffer);&lt;br /&gt;
      myObject = JSON.parse(jsonBuffer);&lt;br /&gt;
&lt;br /&gt;
      // Check if the JSON parsing was successful.&lt;br /&gt;
      if (JSON.typeof(myObject) == &amp;quot;undefined&amp;quot;) {&lt;br /&gt;
        Serial.println(&amp;quot;Parsing input failed!&amp;quot;);&lt;br /&gt;
        return;&lt;br /&gt;
      }&lt;br /&gt;
      delay(2000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Extract weather information from the parsed JSON data.&lt;br /&gt;
    weather = JSON.stringify(myObject[&amp;quot;weather&amp;quot;][0][&amp;quot;main&amp;quot;]);&lt;br /&gt;
    temperature = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;temp&amp;quot;]);&lt;br /&gt;
    humidity = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;humidity&amp;quot;]);&lt;br /&gt;
    sea_level = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;sea_level&amp;quot;]);&lt;br /&gt;
    wind_speed = JSON.stringify(myObject[&amp;quot;wind&amp;quot;][&amp;quot;speed&amp;quot;]);&lt;br /&gt;
    city_js = JSON.stringify(myObject[&amp;quot;name&amp;quot;]);&lt;br /&gt;
&lt;br /&gt;
    // Print the extracted weather information for debugging purposes.&lt;br /&gt;
    Serial.print(&amp;quot;String weather: &amp;quot;);&lt;br /&gt;
    Serial.println(weather);&lt;br /&gt;
    Serial.print(&amp;quot;String Temperature: &amp;quot;);&lt;br /&gt;
    Serial.println(temperature);&lt;br /&gt;
    Serial.print(&amp;quot;String humidity: &amp;quot;);&lt;br /&gt;
    Serial.println(humidity);&lt;br /&gt;
    Serial.print(&amp;quot;String sea_level: &amp;quot;);&lt;br /&gt;
    Serial.println(sea_level);&lt;br /&gt;
    Serial.print(&amp;quot;String wind_speed: &amp;quot;);&lt;br /&gt;
    Serial.println(wind_speed);&lt;br /&gt;
    Serial.print(&amp;quot;String city_js: &amp;quot;);&lt;br /&gt;
    Serial.println(city_js);&lt;br /&gt;
&lt;br /&gt;
    // Determine the weather icon based on the weather description.&lt;br /&gt;
    if (weather.indexOf(&amp;quot;clouds&amp;quot;) != -1 || weather.indexOf(&amp;quot;Clouds&amp;quot;) != -1 ) {&lt;br /&gt;
      weather_flag = 1;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;clear sky&amp;quot;) != -1 || weather.indexOf(&amp;quot;Clear sky&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 3;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;rain&amp;quot;) != -1 || weather.indexOf(&amp;quot;Rain&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 5;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;thunderstorm&amp;quot;) != -1 || weather.indexOf(&amp;quot;Thunderstorm&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 2;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;snow&amp;quot;) != -1 || weather.indexOf(&amp;quot;Snow&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 4;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;mist&amp;quot;) != -1 || weather.indexOf(&amp;quot;Mist&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 0;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
    // Print a message if the device is not connected to the WiFi network.&lt;br /&gt;
    Serial.println(&amp;quot;WiFi Disconnected&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Function to make an HTTP GET request and return the response.&lt;br /&gt;
String httpGETRequest(const char* serverName) {&lt;br /&gt;
  WiFiClient client;&lt;br /&gt;
  HTTPClient http;&lt;br /&gt;
&lt;br /&gt;
  // Initialize the HTTP client with the server name.&lt;br /&gt;
  http.begin(client, serverName);&lt;br /&gt;
&lt;br /&gt;
  // Send an HTTP GET request.&lt;br /&gt;
  httpResponseCode = http.GET();&lt;br /&gt;
&lt;br /&gt;
  // Initialize the response payload as an empty JSON object.&lt;br /&gt;
  String payload = &amp;quot;{}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  // Check if the response code is positive (indicating a successful request).&lt;br /&gt;
  if (httpResponseCode &amp;gt; 0) {&lt;br /&gt;
    Serial.print(&amp;quot;HTTP Response code: &amp;quot;);&lt;br /&gt;
    Serial.println(httpResponseCode);&lt;br /&gt;
    payload = http.getString();&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
    Serial.print(&amp;quot;Error code: &amp;quot;);&lt;br /&gt;
    Serial.println(httpResponseCode);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Close the HTTP connection.&lt;br /&gt;
  http.end();&lt;br /&gt;
&lt;br /&gt;
  return payload;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 Explications : Partie à modifier avec vos données, ssid, password, openWeatherMapApiKey, city, countryCode&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// WiFi network name // WiFi password&lt;br /&gt;
&lt;br /&gt;
const char* ssid = &amp;quot;yanfa_software&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;yanfa-123456&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// OpenWeatherMap API key. This key is used to access weather data from the OpenWeatherMap API.&lt;br /&gt;
String openWeatherMapApiKey = &amp;quot;3c03d1f4e2dd3e14474a9a3a2f2299ff&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// City and country code for which weather data will be fetched.&lt;br /&gt;
String city = &amp;quot;London&amp;quot;;&lt;br /&gt;
String countryCode = &amp;quot;2643743&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Code HelloWord ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
	* @file HelloWorld.ino&lt;br /&gt;
	* @author HalfSweet (Email:HalfSweet@HalfSweet.cn or QQ:2522182733)&lt;br /&gt;
	* @brief Ce fichier est un exemple de programme permettant d&amp;#039;afficher «Hello World» sur un écran à encre électronique. Il illustre uniquement la méthode la plus simple pour allumer l&amp;#039;écran. &lt;br /&gt;
        * Veuillez consulter la documentation pour connaître l&amp;#039;utilisation des différentes fonctions.&lt;br /&gt;
	* @version 0.1&lt;br /&gt;
	* @date 2022-01-30&lt;br /&gt;
	*&lt;br /&gt;
	* @copyright Copyright (c) 2022&lt;br /&gt;
	*&lt;br /&gt;
*/ &lt;br /&gt;
#include &amp;lt;Arduino.h&amp;gt;&lt;br /&gt;
#include &amp;lt;EPaperDrive.h&amp;gt;&lt;br /&gt;
// Inclure le système de fichiers à utiliser, par exemple:&lt;br /&gt;
#include &amp;lt;LittleFS.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define BAUD_SPEED 74880 // Débit en bauds pour le débogage du port série, modifiable selon les besoins&lt;br /&gt;
&lt;br /&gt;
#define CS 15&lt;br /&gt;
#define RST 2&lt;br /&gt;
#define DC 0&lt;br /&gt;
#define BUSY 4&lt;br /&gt;
#define CLK 14&lt;br /&gt;
#define DIN 13&lt;br /&gt;
&lt;br /&gt;
EPaperDrive EPD(0, CS, RST, DC, BUSY, CLK, DIN); //Instanciation de la bibliothèque de pilotes, utilisant ici le protocole SPI logiciel&lt;br /&gt;
&lt;br /&gt;
const uint8_t city_icon[24] = {&lt;br /&gt;
	/* 0X01,0X01,0X0C,0X00,0X0C,0X00, */&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X1C,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X77,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X41,&lt;br /&gt;
	0X80,&lt;br /&gt;
	0X9C,&lt;br /&gt;
	0X60,&lt;br /&gt;
	0XA2,&lt;br /&gt;
	0X30,&lt;br /&gt;
	0XA2,&lt;br /&gt;
	0X30,&lt;br /&gt;
	0X9C,&lt;br /&gt;
	0XC0,&lt;br /&gt;
	0X41,&lt;br /&gt;
	0X80,&lt;br /&gt;
	0X77,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X1C,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
	void setup()&lt;br /&gt;
	{&lt;br /&gt;
	Serial.begin(BAUD_SPEED);&lt;br /&gt;
	LittleFS.begin(); 			  // Veuillez initialiser manuellement le système de fichiers avant de passer le pointeur.&lt;br /&gt;
&lt;br /&gt;
	EPD.SetFS(&amp;amp;LittleFS); 			 // Définit le système de fichiers pour le stockage des polices. La valeur passée est le pointeur d&amp;#039;opération pour ce système de fichiers. &lt;br /&gt;
                                                 //Vous pouvez la modifier.&lt;br /&gt;
	EPD.EPD_Set_Model(HINKE0266A15A0); 	 // Définit le type d&amp;#039;écran. Consultez la documentation pour les modèles spécifiques.&lt;br /&gt;
	EPD.EPD_init_Full(); 			// Initialisation du rafraîchissement complet, en utilisant la forme d&amp;#039;onde de rafraîchissement complet.&lt;br /&gt;
	EPD.clearbuffer(); 		        // Efface le tampon (écran blanc).&lt;br /&gt;
	EPD.fontscale = 2; 			// Facteur d&amp;#039;échelle des polices (1 et 2 pris en charge, également applicable aux images. &lt;br /&gt;
                                                // N&amp;#039;oubliez pas de le remettre à 1 après utilisation).&lt;br /&gt;
	EPD.SetFont(FONT12); 		       // Sélectionne la police. Consultez la documentation pour connaître les polices prises en charge.&lt;br /&gt;
	EPD.DrawUTF(0, 0, &amp;quot;Hello&amp;quot;); &amp;quot;World&amp;quot;);  // Dessiner la chaîne&lt;br /&gt;
	EPD.DrawUTF(26, 0, &amp;quot;J&amp;#039;aime les écrans à encre électronique&amp;quot;); 	&lt;br /&gt;
                                               // Dessiner la chaîne&lt;br /&gt;
	EPD.fontscale = 1; 		       // Rétablir le facteur d&amp;#039;échelle de la police à 1&lt;br /&gt;
	EPD.DrawXbm_P(60, 0, 12, 12, (uint8_t *)city_icon); 			 // Dessiner l&amp;#039;image&lt;br /&gt;
&lt;br /&gt;
	Serial.printf(&amp;quot;Image tamponnée dessinée, prête pour un rafraîchissement complet\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_Dis_Full((uint8_t *)EPD.EPDbuffer, 1); // Transmettre l&amp;#039;image tamponnée à la puce de contrôle de l&amp;#039;écran pour un rafraîchissement complet&lt;br /&gt;
	EPD.deepsleep(); // Mettre l&amp;#039;écran en veille&lt;br /&gt;
	Serial.println(&amp;quot;Rafraîchissement complet terminé&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	delay(5000);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_init_Part(); // Initialiser la partie Actualisation&lt;br /&gt;
	EPD.clearbuffer();&lt;br /&gt;
	EPD.fontscale = 2;&lt;br /&gt;
	EPD.SetFont(FONT12); EPD.DrawUTF(0, 0, &amp;quot;Actualisation locale activée&amp;quot;);&lt;br /&gt;
	Serial.printf(&amp;quot;Actualisation locale en cours\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_Dis_Part(0, 23, 0, 199, (uint8_t *)EPD.EPDbuffer, 1); // Transfert de l&amp;#039;image du tampon vers la puce de contrôle d&amp;#039;écran pour l&amp;#039;actualisation locale sur le nouvel écran&lt;br /&gt;
	Serial.printf(&amp;quot;Actualisation locale terminée\n&amp;quot;);&lt;br /&gt;
	EPD.deepsleep();&lt;br /&gt;
&lt;br /&gt;
} void loop()&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
	delay(1); // Empêcher le chien de garde de s&amp;#039;interrompre&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>144.2.107.134</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1911</id>
		<title>CrowPanel-ESP32-E-Paper-HMI-1.54</title>
		<link rel="alternate" type="text/html" href="https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1911"/>
		<updated>2025-11-26T23:29:34Z</updated>

		<summary type="html">&lt;p&gt;144.2.107.134: /* Arduine Mise en route (Setup) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== E-Paper-HMI-1.54 (Elecrow) ==&lt;br /&gt;
&lt;br /&gt;
=== Liens externes ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_HMI_1.54-inch_Display.html Wiki&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_1.54-inch_Arduino_Tutorial.html Arduino Setup&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/crowpanel-esp32-1-54-e-paper-hmi-display-with-152-152-resolution-black-white-color-driven-by-spi-interface.html Shop&lt;br /&gt;
&lt;br /&gt;
 BLE debugging assistant&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/1-54-inch-152-152-e-paper-display-black-white-e-ink-display-with-spi-communication.html&lt;br /&gt;
&lt;br /&gt;
=== Caractéristiques ===&lt;br /&gt;
&lt;br /&gt;
Driver Chip : &amp;lt;b&amp;gt;SSD1680&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Résolution 152 x 152&amp;lt;br&amp;gt;&lt;br /&gt;
Couleur noir et blanc&amp;lt;br&amp;gt;&lt;br /&gt;
Pilote ESP32-S3 comme contrôleur principal&amp;lt;br&amp;gt;&lt;br /&gt;
PSRAM : 8MB&amp;lt;br&amp;gt;&lt;br /&gt;
Flash :	8MB&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Images ===&lt;br /&gt;
[[File:E-Paper-HMI-1.54-1.png|300px]]&lt;br /&gt;
&lt;br /&gt;
[[File:E-Paper-HMI-1.54-2.png|300px]]&lt;br /&gt;
[[File:E-Paper-HMI-1.54-3.png|300px]]&lt;br /&gt;
&lt;br /&gt;
=== Ressources ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/download/product/CrowPanel/E-paper/Image2Lcd_v2.9.zip Image2Lcd_v2.9&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152 GitHub&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152/archive/refs/heads/master.zip GitHub ZIP&lt;br /&gt;
&lt;br /&gt;
=== Arduine Mise en route (Setup) ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. Téléchargez les fichiers de bibliothèque utilisés par ce produit dans le dossier « bibliothèques ».&lt;br /&gt;
&lt;br /&gt;
C:\Users\Documents\Arduino\libraries\&lt;br /&gt;
&lt;br /&gt;
2. Ouvrez l&amp;#039;IDE Arduino&amp;lt;br&amp;gt;&lt;br /&gt;
chercher ESP32 dans Boards Manager, installez si cela n&amp;#039;est pas déjà fait &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;by Espressif Systems&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. Click &amp;quot;Tools&amp;quot;-&amp;gt;&amp;quot;Board&amp;quot;-&amp;gt;&amp;quot;esp32&amp;quot;-&amp;gt;&amp;quot;&amp;lt;b&amp;gt;ESP32S3 Dev Module&amp;lt;/b&amp;gt;&amp;quot;, &lt;br /&gt;
&lt;br /&gt;
and the &amp;quot;Partition Scheme&amp;quot; select &lt;br /&gt;
&amp;quot;Huge APP (3MB No OTA/1MB SPIFFS)&amp;quot;, &lt;br /&gt;
&amp;quot;PSRAM&amp;quot; select &amp;quot;OPI PSRAM&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[File:Setup-Arduino-1.png|300px]]&lt;br /&gt;
&lt;br /&gt;
=== Librairies ===&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;Arduino.h&amp;gt;   // Inclure la bibliothèque principale Arduino&lt;br /&gt;
 #include &amp;quot;EPD_GUI.h&amp;quot;   // Inclure la bibliothèque pour l&amp;#039;écran à encre électronique&lt;br /&gt;
 #include &amp;quot;Pic.h&amp;quot;       // Inclure la bibliothèque de fonctions personnalisées&lt;br /&gt;
 #include &amp;quot;FS.h&amp;quot;        // Bibliothèque du système de fichiers pour les opérations sur les fichiers&lt;br /&gt;
 #include &amp;quot;SPIFFS.h&amp;quot;    // Bibliothèque du système de fichiers SPIFFS pour la lecture et l&amp;#039;écriture de fichiers&lt;br /&gt;
 #include &amp;lt;WiFi.h&amp;gt;      // Bibliothèque WiFi pour la création et la gestion des connexions WiFi&lt;br /&gt;
 #include &amp;lt;Ticker.h&amp;gt;    // Bibliothèque de chronométrage&lt;br /&gt;
 #include &amp;lt;WebServer.h&amp;gt; // Bibliothèque de serveur Web pour la création d&amp;#039;un serveur HTTP&lt;br /&gt;
&lt;br /&gt;
=== Code Exemples ===&lt;br /&gt;
&lt;br /&gt;
Arduino Code for demos&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_WIFI_refresh.ino &amp;lt;b&amp;gt;Update via WiFi&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_ble_refresh.ino  &amp;lt;b&amp;gt;Update via Bluetooth&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_wifi_http_openweather.ino&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arduino Code for examples&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_PWR.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_wifi.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_BLE.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_key.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_Global_refresh.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_partial_refresh.ino&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=smDFHRxDYdw&lt;br /&gt;
&lt;br /&gt;
=== Code wifi_http_openweather ===&lt;br /&gt;
&lt;br /&gt;
https://openweathermap.org/ Veuillez vous enregistrer afin de vous procurer votre OpenWeatherMap API key&lt;br /&gt;
&lt;br /&gt;
http://bulk.openweathermap.org/sample/ on trouve ici : city.list.json.gz, le countryCode de votre ville (variable city)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;lt;HTTPClient.h&amp;gt;&lt;br /&gt;
#include &amp;lt;Arduino_JSON.h&amp;gt;&lt;br /&gt;
#include &amp;quot;EPD_GUI.h&amp;quot;&lt;br /&gt;
#include &amp;quot;Pic.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
// Define an array for black and white image data, which serves as the buffer for the e-paper display.&lt;br /&gt;
// The size of the buffer is determined according to the resolution of the e-paper display.&lt;br /&gt;
uint8_t ImageBW[2888];&lt;br /&gt;
&lt;br /&gt;
// WiFi network name // WiFi password&lt;br /&gt;
const char* ssid = &amp;quot;yanfa_software&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;yanfa-123456&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// OpenWeatherMap API key. This key is used to access weather data from the OpenWeatherMap API.&lt;br /&gt;
String openWeatherMapApiKey = &amp;quot;3c03d1f4e2dd3e14474a9a3a2f2299ff&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// City and country code for which weather data will be fetched.&lt;br /&gt;
String city = &amp;quot;London&amp;quot;;&lt;br /&gt;
String countryCode = &amp;quot;2643743&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Variables related to timing and API calls.&lt;br /&gt;
// lastTime keeps track of the last time the API was called.&lt;br /&gt;
unsigned long lastTime = 0;&lt;br /&gt;
// timerDelay determines the time interval between API calls. For testing, it&amp;#039;s set to 10 seconds (10000 milliseconds).&lt;br /&gt;
// In a final application, this should be set according to the API call limits per hour/minute.&lt;br /&gt;
unsigned long timerDelay = 10000;&lt;br /&gt;
&lt;br /&gt;
// Variables related to JSON data.&lt;br /&gt;
// jsonBuffer stores the raw JSON data received from the API.&lt;br /&gt;
String jsonBuffer;&lt;br /&gt;
// httpResponseCode holds the response code from the HTTP request.&lt;br /&gt;
int httpResponseCode;&lt;br /&gt;
// myObject is a JSON variable that will hold the parsed JSON data.&lt;br /&gt;
JSONVar myObject;&lt;br /&gt;
&lt;br /&gt;
// Variables related to weather information.&lt;br /&gt;
// weather stores the main weather description.&lt;br /&gt;
String weather;&lt;br /&gt;
// temperature stores the temperature value.&lt;br /&gt;
String temperature;&lt;br /&gt;
// humidity stores the humidity value.&lt;br /&gt;
String humidity;&lt;br /&gt;
// sea_level stores the sea level value.&lt;br /&gt;
String sea_level;&lt;br /&gt;
// wind_speed stores the wind speed value.&lt;br /&gt;
String wind_speed;&lt;br /&gt;
// city_js stores the name of the city.&lt;br /&gt;
String city_js;&lt;br /&gt;
// weather_flag is a flag that determines which weather icon to display based on the weather description.&lt;br /&gt;
int weather_flag = 0;&lt;br /&gt;
&lt;br /&gt;
// Function to display weather forecast on the e-paper display.&lt;br /&gt;
void UI_weather_forecast()&lt;br /&gt;
{&lt;br /&gt;
  char buffer[40];&lt;br /&gt;
&lt;br /&gt;
  EPD_HW_RESET();&lt;br /&gt;
&lt;br /&gt;
  // Display a background picture on the e-paper.&lt;br /&gt;
  EPD_ShowPicture(0, 0, 152, 152, pic, BLACK);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  //If you need to replace the display options,&lt;br /&gt;
  //open the following options: temp, wind, visit, hum&lt;br /&gt;
  //The following uses the hum option as an example&lt;br /&gt;
&lt;br /&gt;
  //Visit&lt;br /&gt;
  //EPD_ShowPicture(76, 92, 56, 72, gImage_visit, BLACK);&lt;br /&gt;
  //Wind&lt;br /&gt;
  //EPD_ShowPicture(76, 92, 56, 72, gImage_wind, BLACK);&lt;br /&gt;
  //Temp&lt;br /&gt;
  //  EPD_ShowPicture(92, 0, 56, 72, gImage_temp, BLACK);&lt;br /&gt;
  //Hum&lt;br /&gt;
&lt;br /&gt;
  EPD_Display(ImageBW);&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_DeepSleep();&lt;br /&gt;
&lt;br /&gt;
  EPD_GPIOInit();&lt;br /&gt;
  Paint_NewImage(ImageBW, EPD_W, EPD_H, 270, WHITE);&lt;br /&gt;
  // Paint_Clear(WHITE);&lt;br /&gt;
  EPD_FastMode1Init();&lt;br /&gt;
  // EPD_Display_Clear();&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_Clear_R26H();&lt;br /&gt;
&lt;br /&gt;
  // Display the update time (it seems to be mislabeled as city_js here, might need to be corrected depending on the actual intention).&lt;br /&gt;
  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, city_js);&lt;br /&gt;
  EPD_ShowString(20, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //If you need to replace the display options,&lt;br /&gt;
  //open the following options: temp, wind, visit, hum&lt;br /&gt;
  //The following uses the hum option as an example&lt;br /&gt;
&lt;br /&gt;
  //Hum&lt;br /&gt;
  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, humidity);&lt;br /&gt;
  EPD_ShowString(105, 140, buffer,  12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //Temp&lt;br /&gt;
  //       memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  //       snprintf(buffer, sizeof(buffer), &amp;quot;%s C&amp;quot;, temperature);&lt;br /&gt;
  //       EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //Wind&lt;br /&gt;
  // memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  // snprintf(buffer, sizeof(buffer), &amp;quot;%s m/s&amp;quot;, wind_speed);&lt;br /&gt;
  // EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //visit&lt;br /&gt;
  //  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  //  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, sea_level);&lt;br /&gt;
  //  EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  // Update the e-paper display with the new content.&lt;br /&gt;
  EPD_Display(ImageBW);&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_DeepSleep();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200); // Initialize the serial communication.&lt;br /&gt;
&lt;br /&gt;
  // Connect to the WiFi network.&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  Serial.println(&amp;quot;Connecting&amp;quot;);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot;&amp;quot;);&lt;br /&gt;
  Serial.print(&amp;quot;Connected to WiFi network with IP Address: &amp;quot;);&lt;br /&gt;
  Serial.println(WiFi.localIP()); // Print the IP address of the device after successful connection.&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Timer set to 10 seconds (timerDelay variable), it will take 10 seconds before publishing the first reading.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Set pin 7 as an output pin to control the power of the e-paper display.&lt;br /&gt;
  pinMode(7, OUTPUT);&lt;br /&gt;
  digitalWrite(7, HIGH);&lt;br /&gt;
&lt;br /&gt;
  EPD_GPIOInit();&lt;br /&gt;
  Paint_NewImage(ImageBW, EPD_W, EPD_H, 0, WHITE);&lt;br /&gt;
  Paint_Clear(WHITE);&lt;br /&gt;
  EPD_FastMode1Init();&lt;br /&gt;
  EPD_Display_Clear();&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_Clear_R26H();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  js_analysis();&lt;br /&gt;
  UI_weather_forecast();&lt;br /&gt;
  delay(1000 * 60 * 60);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void js_analysis()&lt;br /&gt;
{&lt;br /&gt;
  // Check if the device is connected to the WiFi network.&lt;br /&gt;
  if (WiFi.status() == WL_CONNECTED) {&lt;br /&gt;
    // Construct the URL for the OpenWeatherMap API request.&lt;br /&gt;
    String serverPath = &amp;quot;http://api.openweathermap.org/data/2.5/weather?q=&amp;quot; + city + &amp;quot;,&amp;quot; + countryCode + &amp;quot;&amp;amp;APPID=&amp;quot; + openWeatherMapApiKey + &amp;quot;&amp;amp;units=metric&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    // Keep trying until a successful response (status code 200) is received.&lt;br /&gt;
    while (httpResponseCode != 200) {&lt;br /&gt;
      // Make an HTTP GET request to the API and store the response in jsonBuffer.&lt;br /&gt;
      jsonBuffer = httpGETRequest(serverPath.c_str());&lt;br /&gt;
      Serial.println(jsonBuffer);&lt;br /&gt;
      myObject = JSON.parse(jsonBuffer);&lt;br /&gt;
&lt;br /&gt;
      // Check if the JSON parsing was successful.&lt;br /&gt;
      if (JSON.typeof(myObject) == &amp;quot;undefined&amp;quot;) {&lt;br /&gt;
        Serial.println(&amp;quot;Parsing input failed!&amp;quot;);&lt;br /&gt;
        return;&lt;br /&gt;
      }&lt;br /&gt;
      delay(2000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Extract weather information from the parsed JSON data.&lt;br /&gt;
    weather = JSON.stringify(myObject[&amp;quot;weather&amp;quot;][0][&amp;quot;main&amp;quot;]);&lt;br /&gt;
    temperature = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;temp&amp;quot;]);&lt;br /&gt;
    humidity = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;humidity&amp;quot;]);&lt;br /&gt;
    sea_level = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;sea_level&amp;quot;]);&lt;br /&gt;
    wind_speed = JSON.stringify(myObject[&amp;quot;wind&amp;quot;][&amp;quot;speed&amp;quot;]);&lt;br /&gt;
    city_js = JSON.stringify(myObject[&amp;quot;name&amp;quot;]);&lt;br /&gt;
&lt;br /&gt;
    // Print the extracted weather information for debugging purposes.&lt;br /&gt;
    Serial.print(&amp;quot;String weather: &amp;quot;);&lt;br /&gt;
    Serial.println(weather);&lt;br /&gt;
    Serial.print(&amp;quot;String Temperature: &amp;quot;);&lt;br /&gt;
    Serial.println(temperature);&lt;br /&gt;
    Serial.print(&amp;quot;String humidity: &amp;quot;);&lt;br /&gt;
    Serial.println(humidity);&lt;br /&gt;
    Serial.print(&amp;quot;String sea_level: &amp;quot;);&lt;br /&gt;
    Serial.println(sea_level);&lt;br /&gt;
    Serial.print(&amp;quot;String wind_speed: &amp;quot;);&lt;br /&gt;
    Serial.println(wind_speed);&lt;br /&gt;
    Serial.print(&amp;quot;String city_js: &amp;quot;);&lt;br /&gt;
    Serial.println(city_js);&lt;br /&gt;
&lt;br /&gt;
    // Determine the weather icon based on the weather description.&lt;br /&gt;
    if (weather.indexOf(&amp;quot;clouds&amp;quot;) != -1 || weather.indexOf(&amp;quot;Clouds&amp;quot;) != -1 ) {&lt;br /&gt;
      weather_flag = 1;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;clear sky&amp;quot;) != -1 || weather.indexOf(&amp;quot;Clear sky&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 3;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;rain&amp;quot;) != -1 || weather.indexOf(&amp;quot;Rain&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 5;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;thunderstorm&amp;quot;) != -1 || weather.indexOf(&amp;quot;Thunderstorm&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 2;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;snow&amp;quot;) != -1 || weather.indexOf(&amp;quot;Snow&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 4;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;mist&amp;quot;) != -1 || weather.indexOf(&amp;quot;Mist&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 0;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
    // Print a message if the device is not connected to the WiFi network.&lt;br /&gt;
    Serial.println(&amp;quot;WiFi Disconnected&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Function to make an HTTP GET request and return the response.&lt;br /&gt;
String httpGETRequest(const char* serverName) {&lt;br /&gt;
  WiFiClient client;&lt;br /&gt;
  HTTPClient http;&lt;br /&gt;
&lt;br /&gt;
  // Initialize the HTTP client with the server name.&lt;br /&gt;
  http.begin(client, serverName);&lt;br /&gt;
&lt;br /&gt;
  // Send an HTTP GET request.&lt;br /&gt;
  httpResponseCode = http.GET();&lt;br /&gt;
&lt;br /&gt;
  // Initialize the response payload as an empty JSON object.&lt;br /&gt;
  String payload = &amp;quot;{}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  // Check if the response code is positive (indicating a successful request).&lt;br /&gt;
  if (httpResponseCode &amp;gt; 0) {&lt;br /&gt;
    Serial.print(&amp;quot;HTTP Response code: &amp;quot;);&lt;br /&gt;
    Serial.println(httpResponseCode);&lt;br /&gt;
    payload = http.getString();&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
    Serial.print(&amp;quot;Error code: &amp;quot;);&lt;br /&gt;
    Serial.println(httpResponseCode);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Close the HTTP connection.&lt;br /&gt;
  http.end();&lt;br /&gt;
&lt;br /&gt;
  return payload;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 Explications : Partie à modifier avec vos données, ssid, password, openWeatherMapApiKey, city, countryCode&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// WiFi network name // WiFi password&lt;br /&gt;
&lt;br /&gt;
const char* ssid = &amp;quot;yanfa_software&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;yanfa-123456&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// OpenWeatherMap API key. This key is used to access weather data from the OpenWeatherMap API.&lt;br /&gt;
String openWeatherMapApiKey = &amp;quot;3c03d1f4e2dd3e14474a9a3a2f2299ff&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// City and country code for which weather data will be fetched.&lt;br /&gt;
String city = &amp;quot;London&amp;quot;;&lt;br /&gt;
String countryCode = &amp;quot;2643743&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Code HelloWord ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
	* @file HelloWorld.ino&lt;br /&gt;
	* @author HalfSweet (Email:HalfSweet@HalfSweet.cn or QQ:2522182733)&lt;br /&gt;
	* @brief Ce fichier est un exemple de programme permettant d&amp;#039;afficher «Hello World» sur un écran à encre électronique. Il illustre uniquement la méthode la plus simple pour allumer l&amp;#039;écran. &lt;br /&gt;
        * Veuillez consulter la documentation pour connaître l&amp;#039;utilisation des différentes fonctions.&lt;br /&gt;
	* @version 0.1&lt;br /&gt;
	* @date 2022-01-30&lt;br /&gt;
	*&lt;br /&gt;
	* @copyright Copyright (c) 2022&lt;br /&gt;
	*&lt;br /&gt;
*/ &lt;br /&gt;
#include &amp;lt;Arduino.h&amp;gt;&lt;br /&gt;
#include &amp;lt;EPaperDrive.h&amp;gt;&lt;br /&gt;
// Inclure le système de fichiers à utiliser, par exemple:&lt;br /&gt;
#include &amp;lt;LittleFS.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define BAUD_SPEED 74880 // Débit en bauds pour le débogage du port série, modifiable selon les besoins&lt;br /&gt;
&lt;br /&gt;
#define CS 15&lt;br /&gt;
#define RST 2&lt;br /&gt;
#define DC 0&lt;br /&gt;
#define BUSY 4&lt;br /&gt;
#define CLK 14&lt;br /&gt;
#define DIN 13&lt;br /&gt;
&lt;br /&gt;
EPaperDrive EPD(0, CS, RST, DC, BUSY, CLK, DIN); //Instanciation de la bibliothèque de pilotes, utilisant ici le protocole SPI logiciel&lt;br /&gt;
&lt;br /&gt;
const uint8_t city_icon[24] = {&lt;br /&gt;
	/* 0X01,0X01,0X0C,0X00,0X0C,0X00, */&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X1C,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X77,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X41,&lt;br /&gt;
	0X80,&lt;br /&gt;
	0X9C,&lt;br /&gt;
	0X60,&lt;br /&gt;
	0XA2,&lt;br /&gt;
	0X30,&lt;br /&gt;
	0XA2,&lt;br /&gt;
	0X30,&lt;br /&gt;
	0X9C,&lt;br /&gt;
	0XC0,&lt;br /&gt;
	0X41,&lt;br /&gt;
	0X80,&lt;br /&gt;
	0X77,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X1C,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
	void setup()&lt;br /&gt;
	{&lt;br /&gt;
	Serial.begin(BAUD_SPEED);&lt;br /&gt;
	LittleFS.begin(); 			  // Veuillez initialiser manuellement le système de fichiers avant de passer le pointeur.&lt;br /&gt;
&lt;br /&gt;
	EPD.SetFS(&amp;amp;LittleFS); 			 // Définit le système de fichiers pour le stockage des polices. La valeur passée est le pointeur d&amp;#039;opération pour ce système de fichiers. &lt;br /&gt;
                                                 //Vous pouvez la modifier.&lt;br /&gt;
	EPD.EPD_Set_Model(HINKE0266A15A0); 	 // Définit le type d&amp;#039;écran. Consultez la documentation pour les modèles spécifiques.&lt;br /&gt;
	EPD.EPD_init_Full(); 			// Initialisation du rafraîchissement complet, en utilisant la forme d&amp;#039;onde de rafraîchissement complet.&lt;br /&gt;
	EPD.clearbuffer(); 		        // Efface le tampon (écran blanc).&lt;br /&gt;
	EPD.fontscale = 2; 			// Facteur d&amp;#039;échelle des polices (1 et 2 pris en charge, également applicable aux images. &lt;br /&gt;
                                                // N&amp;#039;oubliez pas de le remettre à 1 après utilisation).&lt;br /&gt;
	EPD.SetFont(FONT12); 		       // Sélectionne la police. Consultez la documentation pour connaître les polices prises en charge.&lt;br /&gt;
	EPD.DrawUTF(0, 0, &amp;quot;Hello&amp;quot;); &amp;quot;World&amp;quot;);  // Dessiner la chaîne&lt;br /&gt;
	EPD.DrawUTF(26, 0, &amp;quot;J&amp;#039;aime les écrans à encre électronique&amp;quot;); 	&lt;br /&gt;
                                               // Dessiner la chaîne&lt;br /&gt;
	EPD.fontscale = 1; 		       // Rétablir le facteur d&amp;#039;échelle de la police à 1&lt;br /&gt;
	EPD.DrawXbm_P(60, 0, 12, 12, (uint8_t *)city_icon); 			 // Dessiner l&amp;#039;image&lt;br /&gt;
&lt;br /&gt;
	Serial.printf(&amp;quot;Image tamponnée dessinée, prête pour un rafraîchissement complet\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_Dis_Full((uint8_t *)EPD.EPDbuffer, 1); // Transmettre l&amp;#039;image tamponnée à la puce de contrôle de l&amp;#039;écran pour un rafraîchissement complet&lt;br /&gt;
	EPD.deepsleep(); // Mettre l&amp;#039;écran en veille&lt;br /&gt;
	Serial.println(&amp;quot;Rafraîchissement complet terminé&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	delay(5000);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_init_Part(); // Initialiser la partie Actualisation&lt;br /&gt;
	EPD.clearbuffer();&lt;br /&gt;
	EPD.fontscale = 2;&lt;br /&gt;
	EPD.SetFont(FONT12); EPD.DrawUTF(0, 0, &amp;quot;Actualisation locale activée&amp;quot;);&lt;br /&gt;
	Serial.printf(&amp;quot;Actualisation locale en cours\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_Dis_Part(0, 23, 0, 199, (uint8_t *)EPD.EPDbuffer, 1); // Transfert de l&amp;#039;image du tampon vers la puce de contrôle d&amp;#039;écran pour l&amp;#039;actualisation locale sur le nouvel écran&lt;br /&gt;
	Serial.printf(&amp;quot;Actualisation locale terminée\n&amp;quot;);&lt;br /&gt;
	EPD.deepsleep();&lt;br /&gt;
&lt;br /&gt;
} void loop()&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
	delay(1); // Empêcher le chien de garde de s&amp;#039;interrompre&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>144.2.107.134</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1910</id>
		<title>CrowPanel-ESP32-E-Paper-HMI-1.54</title>
		<link rel="alternate" type="text/html" href="https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1910"/>
		<updated>2025-11-26T23:29:10Z</updated>

		<summary type="html">&lt;p&gt;144.2.107.134: /* Arduine Mise en route (Setup) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== E-Paper-HMI-1.54 (Elecrow) ==&lt;br /&gt;
&lt;br /&gt;
=== Liens externes ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_HMI_1.54-inch_Display.html Wiki&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_1.54-inch_Arduino_Tutorial.html Arduino Setup&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/crowpanel-esp32-1-54-e-paper-hmi-display-with-152-152-resolution-black-white-color-driven-by-spi-interface.html Shop&lt;br /&gt;
&lt;br /&gt;
 BLE debugging assistant&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/1-54-inch-152-152-e-paper-display-black-white-e-ink-display-with-spi-communication.html&lt;br /&gt;
&lt;br /&gt;
=== Caractéristiques ===&lt;br /&gt;
&lt;br /&gt;
Driver Chip : &amp;lt;b&amp;gt;SSD1680&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Résolution 152 x 152&amp;lt;br&amp;gt;&lt;br /&gt;
Couleur noir et blanc&amp;lt;br&amp;gt;&lt;br /&gt;
Pilote ESP32-S3 comme contrôleur principal&amp;lt;br&amp;gt;&lt;br /&gt;
PSRAM : 8MB&amp;lt;br&amp;gt;&lt;br /&gt;
Flash :	8MB&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Images ===&lt;br /&gt;
[[File:E-Paper-HMI-1.54-1.png|300px]]&lt;br /&gt;
&lt;br /&gt;
[[File:E-Paper-HMI-1.54-2.png|300px]]&lt;br /&gt;
[[File:E-Paper-HMI-1.54-3.png|300px]]&lt;br /&gt;
&lt;br /&gt;
=== Ressources ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/download/product/CrowPanel/E-paper/Image2Lcd_v2.9.zip Image2Lcd_v2.9&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152 GitHub&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152/archive/refs/heads/master.zip GitHub ZIP&lt;br /&gt;
&lt;br /&gt;
=== Arduine Mise en route (Setup) ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. Téléchargez les fichiers de bibliothèque utilisés par ce produit dans le dossier « bibliothèques ».&lt;br /&gt;
&lt;br /&gt;
C:\Users\Documents\Arduino\libraries\&lt;br /&gt;
&lt;br /&gt;
2. Ouvrez l&amp;#039;IDE Arduino&amp;lt;br&amp;gt;&lt;br /&gt;
chercher ESP32 dans Boards Manager, installez si cela n&amp;#039;est pas déjà fait &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;by Espressif Systems&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. Click &amp;quot;Tools&amp;quot;-&amp;gt;&amp;quot;Board&amp;quot;-&amp;gt;&amp;quot;esp32&amp;quot;-&amp;gt;&amp;quot;ESP32S3 Dev Module&amp;quot;, &lt;br /&gt;
&lt;br /&gt;
and the &amp;quot;Partition Scheme&amp;quot; select &lt;br /&gt;
&amp;quot;Huge APP (3MB No OTA/1MB SPIFFS)&amp;quot;, &lt;br /&gt;
&amp;quot;PSRAM&amp;quot; select &amp;quot;OPI PSRAM&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[File:Setup-Arduino-1.png|300px]]&lt;br /&gt;
&lt;br /&gt;
=== Librairies ===&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;Arduino.h&amp;gt;   // Inclure la bibliothèque principale Arduino&lt;br /&gt;
 #include &amp;quot;EPD_GUI.h&amp;quot;   // Inclure la bibliothèque pour l&amp;#039;écran à encre électronique&lt;br /&gt;
 #include &amp;quot;Pic.h&amp;quot;       // Inclure la bibliothèque de fonctions personnalisées&lt;br /&gt;
 #include &amp;quot;FS.h&amp;quot;        // Bibliothèque du système de fichiers pour les opérations sur les fichiers&lt;br /&gt;
 #include &amp;quot;SPIFFS.h&amp;quot;    // Bibliothèque du système de fichiers SPIFFS pour la lecture et l&amp;#039;écriture de fichiers&lt;br /&gt;
 #include &amp;lt;WiFi.h&amp;gt;      // Bibliothèque WiFi pour la création et la gestion des connexions WiFi&lt;br /&gt;
 #include &amp;lt;Ticker.h&amp;gt;    // Bibliothèque de chronométrage&lt;br /&gt;
 #include &amp;lt;WebServer.h&amp;gt; // Bibliothèque de serveur Web pour la création d&amp;#039;un serveur HTTP&lt;br /&gt;
&lt;br /&gt;
=== Code Exemples ===&lt;br /&gt;
&lt;br /&gt;
Arduino Code for demos&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_WIFI_refresh.ino &amp;lt;b&amp;gt;Update via WiFi&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_ble_refresh.ino  &amp;lt;b&amp;gt;Update via Bluetooth&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_wifi_http_openweather.ino&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arduino Code for examples&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_PWR.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_wifi.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_BLE.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_key.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_Global_refresh.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_partial_refresh.ino&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=smDFHRxDYdw&lt;br /&gt;
&lt;br /&gt;
=== Code wifi_http_openweather ===&lt;br /&gt;
&lt;br /&gt;
https://openweathermap.org/ Veuillez vous enregistrer afin de vous procurer votre OpenWeatherMap API key&lt;br /&gt;
&lt;br /&gt;
http://bulk.openweathermap.org/sample/ on trouve ici : city.list.json.gz, le countryCode de votre ville (variable city)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;lt;HTTPClient.h&amp;gt;&lt;br /&gt;
#include &amp;lt;Arduino_JSON.h&amp;gt;&lt;br /&gt;
#include &amp;quot;EPD_GUI.h&amp;quot;&lt;br /&gt;
#include &amp;quot;Pic.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
// Define an array for black and white image data, which serves as the buffer for the e-paper display.&lt;br /&gt;
// The size of the buffer is determined according to the resolution of the e-paper display.&lt;br /&gt;
uint8_t ImageBW[2888];&lt;br /&gt;
&lt;br /&gt;
// WiFi network name // WiFi password&lt;br /&gt;
const char* ssid = &amp;quot;yanfa_software&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;yanfa-123456&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// OpenWeatherMap API key. This key is used to access weather data from the OpenWeatherMap API.&lt;br /&gt;
String openWeatherMapApiKey = &amp;quot;3c03d1f4e2dd3e14474a9a3a2f2299ff&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// City and country code for which weather data will be fetched.&lt;br /&gt;
String city = &amp;quot;London&amp;quot;;&lt;br /&gt;
String countryCode = &amp;quot;2643743&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Variables related to timing and API calls.&lt;br /&gt;
// lastTime keeps track of the last time the API was called.&lt;br /&gt;
unsigned long lastTime = 0;&lt;br /&gt;
// timerDelay determines the time interval between API calls. For testing, it&amp;#039;s set to 10 seconds (10000 milliseconds).&lt;br /&gt;
// In a final application, this should be set according to the API call limits per hour/minute.&lt;br /&gt;
unsigned long timerDelay = 10000;&lt;br /&gt;
&lt;br /&gt;
// Variables related to JSON data.&lt;br /&gt;
// jsonBuffer stores the raw JSON data received from the API.&lt;br /&gt;
String jsonBuffer;&lt;br /&gt;
// httpResponseCode holds the response code from the HTTP request.&lt;br /&gt;
int httpResponseCode;&lt;br /&gt;
// myObject is a JSON variable that will hold the parsed JSON data.&lt;br /&gt;
JSONVar myObject;&lt;br /&gt;
&lt;br /&gt;
// Variables related to weather information.&lt;br /&gt;
// weather stores the main weather description.&lt;br /&gt;
String weather;&lt;br /&gt;
// temperature stores the temperature value.&lt;br /&gt;
String temperature;&lt;br /&gt;
// humidity stores the humidity value.&lt;br /&gt;
String humidity;&lt;br /&gt;
// sea_level stores the sea level value.&lt;br /&gt;
String sea_level;&lt;br /&gt;
// wind_speed stores the wind speed value.&lt;br /&gt;
String wind_speed;&lt;br /&gt;
// city_js stores the name of the city.&lt;br /&gt;
String city_js;&lt;br /&gt;
// weather_flag is a flag that determines which weather icon to display based on the weather description.&lt;br /&gt;
int weather_flag = 0;&lt;br /&gt;
&lt;br /&gt;
// Function to display weather forecast on the e-paper display.&lt;br /&gt;
void UI_weather_forecast()&lt;br /&gt;
{&lt;br /&gt;
  char buffer[40];&lt;br /&gt;
&lt;br /&gt;
  EPD_HW_RESET();&lt;br /&gt;
&lt;br /&gt;
  // Display a background picture on the e-paper.&lt;br /&gt;
  EPD_ShowPicture(0, 0, 152, 152, pic, BLACK);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  //If you need to replace the display options,&lt;br /&gt;
  //open the following options: temp, wind, visit, hum&lt;br /&gt;
  //The following uses the hum option as an example&lt;br /&gt;
&lt;br /&gt;
  //Visit&lt;br /&gt;
  //EPD_ShowPicture(76, 92, 56, 72, gImage_visit, BLACK);&lt;br /&gt;
  //Wind&lt;br /&gt;
  //EPD_ShowPicture(76, 92, 56, 72, gImage_wind, BLACK);&lt;br /&gt;
  //Temp&lt;br /&gt;
  //  EPD_ShowPicture(92, 0, 56, 72, gImage_temp, BLACK);&lt;br /&gt;
  //Hum&lt;br /&gt;
&lt;br /&gt;
  EPD_Display(ImageBW);&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_DeepSleep();&lt;br /&gt;
&lt;br /&gt;
  EPD_GPIOInit();&lt;br /&gt;
  Paint_NewImage(ImageBW, EPD_W, EPD_H, 270, WHITE);&lt;br /&gt;
  // Paint_Clear(WHITE);&lt;br /&gt;
  EPD_FastMode1Init();&lt;br /&gt;
  // EPD_Display_Clear();&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_Clear_R26H();&lt;br /&gt;
&lt;br /&gt;
  // Display the update time (it seems to be mislabeled as city_js here, might need to be corrected depending on the actual intention).&lt;br /&gt;
  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, city_js);&lt;br /&gt;
  EPD_ShowString(20, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //If you need to replace the display options,&lt;br /&gt;
  //open the following options: temp, wind, visit, hum&lt;br /&gt;
  //The following uses the hum option as an example&lt;br /&gt;
&lt;br /&gt;
  //Hum&lt;br /&gt;
  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, humidity);&lt;br /&gt;
  EPD_ShowString(105, 140, buffer,  12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //Temp&lt;br /&gt;
  //       memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  //       snprintf(buffer, sizeof(buffer), &amp;quot;%s C&amp;quot;, temperature);&lt;br /&gt;
  //       EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //Wind&lt;br /&gt;
  // memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  // snprintf(buffer, sizeof(buffer), &amp;quot;%s m/s&amp;quot;, wind_speed);&lt;br /&gt;
  // EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //visit&lt;br /&gt;
  //  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  //  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, sea_level);&lt;br /&gt;
  //  EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  // Update the e-paper display with the new content.&lt;br /&gt;
  EPD_Display(ImageBW);&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_DeepSleep();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200); // Initialize the serial communication.&lt;br /&gt;
&lt;br /&gt;
  // Connect to the WiFi network.&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  Serial.println(&amp;quot;Connecting&amp;quot;);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot;&amp;quot;);&lt;br /&gt;
  Serial.print(&amp;quot;Connected to WiFi network with IP Address: &amp;quot;);&lt;br /&gt;
  Serial.println(WiFi.localIP()); // Print the IP address of the device after successful connection.&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Timer set to 10 seconds (timerDelay variable), it will take 10 seconds before publishing the first reading.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Set pin 7 as an output pin to control the power of the e-paper display.&lt;br /&gt;
  pinMode(7, OUTPUT);&lt;br /&gt;
  digitalWrite(7, HIGH);&lt;br /&gt;
&lt;br /&gt;
  EPD_GPIOInit();&lt;br /&gt;
  Paint_NewImage(ImageBW, EPD_W, EPD_H, 0, WHITE);&lt;br /&gt;
  Paint_Clear(WHITE);&lt;br /&gt;
  EPD_FastMode1Init();&lt;br /&gt;
  EPD_Display_Clear();&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_Clear_R26H();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  js_analysis();&lt;br /&gt;
  UI_weather_forecast();&lt;br /&gt;
  delay(1000 * 60 * 60);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void js_analysis()&lt;br /&gt;
{&lt;br /&gt;
  // Check if the device is connected to the WiFi network.&lt;br /&gt;
  if (WiFi.status() == WL_CONNECTED) {&lt;br /&gt;
    // Construct the URL for the OpenWeatherMap API request.&lt;br /&gt;
    String serverPath = &amp;quot;http://api.openweathermap.org/data/2.5/weather?q=&amp;quot; + city + &amp;quot;,&amp;quot; + countryCode + &amp;quot;&amp;amp;APPID=&amp;quot; + openWeatherMapApiKey + &amp;quot;&amp;amp;units=metric&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    // Keep trying until a successful response (status code 200) is received.&lt;br /&gt;
    while (httpResponseCode != 200) {&lt;br /&gt;
      // Make an HTTP GET request to the API and store the response in jsonBuffer.&lt;br /&gt;
      jsonBuffer = httpGETRequest(serverPath.c_str());&lt;br /&gt;
      Serial.println(jsonBuffer);&lt;br /&gt;
      myObject = JSON.parse(jsonBuffer);&lt;br /&gt;
&lt;br /&gt;
      // Check if the JSON parsing was successful.&lt;br /&gt;
      if (JSON.typeof(myObject) == &amp;quot;undefined&amp;quot;) {&lt;br /&gt;
        Serial.println(&amp;quot;Parsing input failed!&amp;quot;);&lt;br /&gt;
        return;&lt;br /&gt;
      }&lt;br /&gt;
      delay(2000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Extract weather information from the parsed JSON data.&lt;br /&gt;
    weather = JSON.stringify(myObject[&amp;quot;weather&amp;quot;][0][&amp;quot;main&amp;quot;]);&lt;br /&gt;
    temperature = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;temp&amp;quot;]);&lt;br /&gt;
    humidity = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;humidity&amp;quot;]);&lt;br /&gt;
    sea_level = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;sea_level&amp;quot;]);&lt;br /&gt;
    wind_speed = JSON.stringify(myObject[&amp;quot;wind&amp;quot;][&amp;quot;speed&amp;quot;]);&lt;br /&gt;
    city_js = JSON.stringify(myObject[&amp;quot;name&amp;quot;]);&lt;br /&gt;
&lt;br /&gt;
    // Print the extracted weather information for debugging purposes.&lt;br /&gt;
    Serial.print(&amp;quot;String weather: &amp;quot;);&lt;br /&gt;
    Serial.println(weather);&lt;br /&gt;
    Serial.print(&amp;quot;String Temperature: &amp;quot;);&lt;br /&gt;
    Serial.println(temperature);&lt;br /&gt;
    Serial.print(&amp;quot;String humidity: &amp;quot;);&lt;br /&gt;
    Serial.println(humidity);&lt;br /&gt;
    Serial.print(&amp;quot;String sea_level: &amp;quot;);&lt;br /&gt;
    Serial.println(sea_level);&lt;br /&gt;
    Serial.print(&amp;quot;String wind_speed: &amp;quot;);&lt;br /&gt;
    Serial.println(wind_speed);&lt;br /&gt;
    Serial.print(&amp;quot;String city_js: &amp;quot;);&lt;br /&gt;
    Serial.println(city_js);&lt;br /&gt;
&lt;br /&gt;
    // Determine the weather icon based on the weather description.&lt;br /&gt;
    if (weather.indexOf(&amp;quot;clouds&amp;quot;) != -1 || weather.indexOf(&amp;quot;Clouds&amp;quot;) != -1 ) {&lt;br /&gt;
      weather_flag = 1;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;clear sky&amp;quot;) != -1 || weather.indexOf(&amp;quot;Clear sky&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 3;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;rain&amp;quot;) != -1 || weather.indexOf(&amp;quot;Rain&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 5;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;thunderstorm&amp;quot;) != -1 || weather.indexOf(&amp;quot;Thunderstorm&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 2;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;snow&amp;quot;) != -1 || weather.indexOf(&amp;quot;Snow&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 4;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;mist&amp;quot;) != -1 || weather.indexOf(&amp;quot;Mist&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 0;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
    // Print a message if the device is not connected to the WiFi network.&lt;br /&gt;
    Serial.println(&amp;quot;WiFi Disconnected&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Function to make an HTTP GET request and return the response.&lt;br /&gt;
String httpGETRequest(const char* serverName) {&lt;br /&gt;
  WiFiClient client;&lt;br /&gt;
  HTTPClient http;&lt;br /&gt;
&lt;br /&gt;
  // Initialize the HTTP client with the server name.&lt;br /&gt;
  http.begin(client, serverName);&lt;br /&gt;
&lt;br /&gt;
  // Send an HTTP GET request.&lt;br /&gt;
  httpResponseCode = http.GET();&lt;br /&gt;
&lt;br /&gt;
  // Initialize the response payload as an empty JSON object.&lt;br /&gt;
  String payload = &amp;quot;{}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  // Check if the response code is positive (indicating a successful request).&lt;br /&gt;
  if (httpResponseCode &amp;gt; 0) {&lt;br /&gt;
    Serial.print(&amp;quot;HTTP Response code: &amp;quot;);&lt;br /&gt;
    Serial.println(httpResponseCode);&lt;br /&gt;
    payload = http.getString();&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
    Serial.print(&amp;quot;Error code: &amp;quot;);&lt;br /&gt;
    Serial.println(httpResponseCode);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Close the HTTP connection.&lt;br /&gt;
  http.end();&lt;br /&gt;
&lt;br /&gt;
  return payload;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 Explications : Partie à modifier avec vos données, ssid, password, openWeatherMapApiKey, city, countryCode&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// WiFi network name // WiFi password&lt;br /&gt;
&lt;br /&gt;
const char* ssid = &amp;quot;yanfa_software&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;yanfa-123456&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// OpenWeatherMap API key. This key is used to access weather data from the OpenWeatherMap API.&lt;br /&gt;
String openWeatherMapApiKey = &amp;quot;3c03d1f4e2dd3e14474a9a3a2f2299ff&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// City and country code for which weather data will be fetched.&lt;br /&gt;
String city = &amp;quot;London&amp;quot;;&lt;br /&gt;
String countryCode = &amp;quot;2643743&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Code HelloWord ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
	* @file HelloWorld.ino&lt;br /&gt;
	* @author HalfSweet (Email:HalfSweet@HalfSweet.cn or QQ:2522182733)&lt;br /&gt;
	* @brief Ce fichier est un exemple de programme permettant d&amp;#039;afficher «Hello World» sur un écran à encre électronique. Il illustre uniquement la méthode la plus simple pour allumer l&amp;#039;écran. &lt;br /&gt;
        * Veuillez consulter la documentation pour connaître l&amp;#039;utilisation des différentes fonctions.&lt;br /&gt;
	* @version 0.1&lt;br /&gt;
	* @date 2022-01-30&lt;br /&gt;
	*&lt;br /&gt;
	* @copyright Copyright (c) 2022&lt;br /&gt;
	*&lt;br /&gt;
*/ &lt;br /&gt;
#include &amp;lt;Arduino.h&amp;gt;&lt;br /&gt;
#include &amp;lt;EPaperDrive.h&amp;gt;&lt;br /&gt;
// Inclure le système de fichiers à utiliser, par exemple:&lt;br /&gt;
#include &amp;lt;LittleFS.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define BAUD_SPEED 74880 // Débit en bauds pour le débogage du port série, modifiable selon les besoins&lt;br /&gt;
&lt;br /&gt;
#define CS 15&lt;br /&gt;
#define RST 2&lt;br /&gt;
#define DC 0&lt;br /&gt;
#define BUSY 4&lt;br /&gt;
#define CLK 14&lt;br /&gt;
#define DIN 13&lt;br /&gt;
&lt;br /&gt;
EPaperDrive EPD(0, CS, RST, DC, BUSY, CLK, DIN); //Instanciation de la bibliothèque de pilotes, utilisant ici le protocole SPI logiciel&lt;br /&gt;
&lt;br /&gt;
const uint8_t city_icon[24] = {&lt;br /&gt;
	/* 0X01,0X01,0X0C,0X00,0X0C,0X00, */&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X1C,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X77,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X41,&lt;br /&gt;
	0X80,&lt;br /&gt;
	0X9C,&lt;br /&gt;
	0X60,&lt;br /&gt;
	0XA2,&lt;br /&gt;
	0X30,&lt;br /&gt;
	0XA2,&lt;br /&gt;
	0X30,&lt;br /&gt;
	0X9C,&lt;br /&gt;
	0XC0,&lt;br /&gt;
	0X41,&lt;br /&gt;
	0X80,&lt;br /&gt;
	0X77,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X1C,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
	void setup()&lt;br /&gt;
	{&lt;br /&gt;
	Serial.begin(BAUD_SPEED);&lt;br /&gt;
	LittleFS.begin(); 			  // Veuillez initialiser manuellement le système de fichiers avant de passer le pointeur.&lt;br /&gt;
&lt;br /&gt;
	EPD.SetFS(&amp;amp;LittleFS); 			 // Définit le système de fichiers pour le stockage des polices. La valeur passée est le pointeur d&amp;#039;opération pour ce système de fichiers. &lt;br /&gt;
                                                 //Vous pouvez la modifier.&lt;br /&gt;
	EPD.EPD_Set_Model(HINKE0266A15A0); 	 // Définit le type d&amp;#039;écran. Consultez la documentation pour les modèles spécifiques.&lt;br /&gt;
	EPD.EPD_init_Full(); 			// Initialisation du rafraîchissement complet, en utilisant la forme d&amp;#039;onde de rafraîchissement complet.&lt;br /&gt;
	EPD.clearbuffer(); 		        // Efface le tampon (écran blanc).&lt;br /&gt;
	EPD.fontscale = 2; 			// Facteur d&amp;#039;échelle des polices (1 et 2 pris en charge, également applicable aux images. &lt;br /&gt;
                                                // N&amp;#039;oubliez pas de le remettre à 1 après utilisation).&lt;br /&gt;
	EPD.SetFont(FONT12); 		       // Sélectionne la police. Consultez la documentation pour connaître les polices prises en charge.&lt;br /&gt;
	EPD.DrawUTF(0, 0, &amp;quot;Hello&amp;quot;); &amp;quot;World&amp;quot;);  // Dessiner la chaîne&lt;br /&gt;
	EPD.DrawUTF(26, 0, &amp;quot;J&amp;#039;aime les écrans à encre électronique&amp;quot;); 	&lt;br /&gt;
                                               // Dessiner la chaîne&lt;br /&gt;
	EPD.fontscale = 1; 		       // Rétablir le facteur d&amp;#039;échelle de la police à 1&lt;br /&gt;
	EPD.DrawXbm_P(60, 0, 12, 12, (uint8_t *)city_icon); 			 // Dessiner l&amp;#039;image&lt;br /&gt;
&lt;br /&gt;
	Serial.printf(&amp;quot;Image tamponnée dessinée, prête pour un rafraîchissement complet\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_Dis_Full((uint8_t *)EPD.EPDbuffer, 1); // Transmettre l&amp;#039;image tamponnée à la puce de contrôle de l&amp;#039;écran pour un rafraîchissement complet&lt;br /&gt;
	EPD.deepsleep(); // Mettre l&amp;#039;écran en veille&lt;br /&gt;
	Serial.println(&amp;quot;Rafraîchissement complet terminé&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	delay(5000);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_init_Part(); // Initialiser la partie Actualisation&lt;br /&gt;
	EPD.clearbuffer();&lt;br /&gt;
	EPD.fontscale = 2;&lt;br /&gt;
	EPD.SetFont(FONT12); EPD.DrawUTF(0, 0, &amp;quot;Actualisation locale activée&amp;quot;);&lt;br /&gt;
	Serial.printf(&amp;quot;Actualisation locale en cours\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_Dis_Part(0, 23, 0, 199, (uint8_t *)EPD.EPDbuffer, 1); // Transfert de l&amp;#039;image du tampon vers la puce de contrôle d&amp;#039;écran pour l&amp;#039;actualisation locale sur le nouvel écran&lt;br /&gt;
	Serial.printf(&amp;quot;Actualisation locale terminée\n&amp;quot;);&lt;br /&gt;
	EPD.deepsleep();&lt;br /&gt;
&lt;br /&gt;
} void loop()&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
	delay(1); // Empêcher le chien de garde de s&amp;#039;interrompre&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>144.2.107.134</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1909</id>
		<title>CrowPanel-ESP32-E-Paper-HMI-1.54</title>
		<link rel="alternate" type="text/html" href="https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1909"/>
		<updated>2025-11-26T23:28:35Z</updated>

		<summary type="html">&lt;p&gt;144.2.107.134: /* Arduine Mise en route (Setup) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== E-Paper-HMI-1.54 (Elecrow) ==&lt;br /&gt;
&lt;br /&gt;
=== Liens externes ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_HMI_1.54-inch_Display.html Wiki&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_1.54-inch_Arduino_Tutorial.html Arduino Setup&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/crowpanel-esp32-1-54-e-paper-hmi-display-with-152-152-resolution-black-white-color-driven-by-spi-interface.html Shop&lt;br /&gt;
&lt;br /&gt;
 BLE debugging assistant&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/1-54-inch-152-152-e-paper-display-black-white-e-ink-display-with-spi-communication.html&lt;br /&gt;
&lt;br /&gt;
=== Caractéristiques ===&lt;br /&gt;
&lt;br /&gt;
Driver Chip : &amp;lt;b&amp;gt;SSD1680&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Résolution 152 x 152&amp;lt;br&amp;gt;&lt;br /&gt;
Couleur noir et blanc&amp;lt;br&amp;gt;&lt;br /&gt;
Pilote ESP32-S3 comme contrôleur principal&amp;lt;br&amp;gt;&lt;br /&gt;
PSRAM : 8MB&amp;lt;br&amp;gt;&lt;br /&gt;
Flash :	8MB&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Images ===&lt;br /&gt;
[[File:E-Paper-HMI-1.54-1.png|300px]]&lt;br /&gt;
&lt;br /&gt;
[[File:E-Paper-HMI-1.54-2.png|300px]]&lt;br /&gt;
[[File:E-Paper-HMI-1.54-3.png|300px]]&lt;br /&gt;
&lt;br /&gt;
=== Ressources ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/download/product/CrowPanel/E-paper/Image2Lcd_v2.9.zip Image2Lcd_v2.9&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152 GitHub&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152/archive/refs/heads/master.zip GitHub ZIP&lt;br /&gt;
&lt;br /&gt;
=== Arduine Mise en route (Setup) ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. Téléchargez les fichiers de bibliothèque utilisés par ce produit dans le dossier « bibliothèques ».&lt;br /&gt;
&lt;br /&gt;
C:\Users\Documents\Arduino\libraries\&lt;br /&gt;
&lt;br /&gt;
2. Ouvrez l&amp;#039;IDE Arduino&amp;lt;br&amp;gt;&lt;br /&gt;
chercher ESP32 dans Boards Manager, installez si cela n&amp;#039;est pas déjà fait &amp;lt;br&amp;gt;&lt;br /&gt;
by Espressif Systems&lt;br /&gt;
&lt;br /&gt;
3. Click &amp;quot;Tools&amp;quot;-&amp;gt;&amp;quot;Board&amp;quot;-&amp;gt;&amp;quot;esp32&amp;quot;-&amp;gt;&amp;quot;ESP32S3 Dev Module&amp;quot;, &lt;br /&gt;
&lt;br /&gt;
and the &amp;quot;Partition Scheme&amp;quot; select &lt;br /&gt;
&amp;quot;Huge APP (3MB No OTA/1MB SPIFFS)&amp;quot;, &lt;br /&gt;
&amp;quot;PSRAM&amp;quot; select &amp;quot;OPI PSRAM&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[File:Setup-Arduino-1.png|300px]]&lt;br /&gt;
&lt;br /&gt;
=== Librairies ===&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;Arduino.h&amp;gt;   // Inclure la bibliothèque principale Arduino&lt;br /&gt;
 #include &amp;quot;EPD_GUI.h&amp;quot;   // Inclure la bibliothèque pour l&amp;#039;écran à encre électronique&lt;br /&gt;
 #include &amp;quot;Pic.h&amp;quot;       // Inclure la bibliothèque de fonctions personnalisées&lt;br /&gt;
 #include &amp;quot;FS.h&amp;quot;        // Bibliothèque du système de fichiers pour les opérations sur les fichiers&lt;br /&gt;
 #include &amp;quot;SPIFFS.h&amp;quot;    // Bibliothèque du système de fichiers SPIFFS pour la lecture et l&amp;#039;écriture de fichiers&lt;br /&gt;
 #include &amp;lt;WiFi.h&amp;gt;      // Bibliothèque WiFi pour la création et la gestion des connexions WiFi&lt;br /&gt;
 #include &amp;lt;Ticker.h&amp;gt;    // Bibliothèque de chronométrage&lt;br /&gt;
 #include &amp;lt;WebServer.h&amp;gt; // Bibliothèque de serveur Web pour la création d&amp;#039;un serveur HTTP&lt;br /&gt;
&lt;br /&gt;
=== Code Exemples ===&lt;br /&gt;
&lt;br /&gt;
Arduino Code for demos&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_WIFI_refresh.ino &amp;lt;b&amp;gt;Update via WiFi&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_ble_refresh.ino  &amp;lt;b&amp;gt;Update via Bluetooth&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_wifi_http_openweather.ino&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arduino Code for examples&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_PWR.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_wifi.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_BLE.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_key.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_Global_refresh.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_partial_refresh.ino&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=smDFHRxDYdw&lt;br /&gt;
&lt;br /&gt;
=== Code wifi_http_openweather ===&lt;br /&gt;
&lt;br /&gt;
https://openweathermap.org/ Veuillez vous enregistrer afin de vous procurer votre OpenWeatherMap API key&lt;br /&gt;
&lt;br /&gt;
http://bulk.openweathermap.org/sample/ on trouve ici : city.list.json.gz, le countryCode de votre ville (variable city)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;lt;HTTPClient.h&amp;gt;&lt;br /&gt;
#include &amp;lt;Arduino_JSON.h&amp;gt;&lt;br /&gt;
#include &amp;quot;EPD_GUI.h&amp;quot;&lt;br /&gt;
#include &amp;quot;Pic.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
// Define an array for black and white image data, which serves as the buffer for the e-paper display.&lt;br /&gt;
// The size of the buffer is determined according to the resolution of the e-paper display.&lt;br /&gt;
uint8_t ImageBW[2888];&lt;br /&gt;
&lt;br /&gt;
// WiFi network name // WiFi password&lt;br /&gt;
const char* ssid = &amp;quot;yanfa_software&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;yanfa-123456&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// OpenWeatherMap API key. This key is used to access weather data from the OpenWeatherMap API.&lt;br /&gt;
String openWeatherMapApiKey = &amp;quot;3c03d1f4e2dd3e14474a9a3a2f2299ff&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// City and country code for which weather data will be fetched.&lt;br /&gt;
String city = &amp;quot;London&amp;quot;;&lt;br /&gt;
String countryCode = &amp;quot;2643743&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Variables related to timing and API calls.&lt;br /&gt;
// lastTime keeps track of the last time the API was called.&lt;br /&gt;
unsigned long lastTime = 0;&lt;br /&gt;
// timerDelay determines the time interval between API calls. For testing, it&amp;#039;s set to 10 seconds (10000 milliseconds).&lt;br /&gt;
// In a final application, this should be set according to the API call limits per hour/minute.&lt;br /&gt;
unsigned long timerDelay = 10000;&lt;br /&gt;
&lt;br /&gt;
// Variables related to JSON data.&lt;br /&gt;
// jsonBuffer stores the raw JSON data received from the API.&lt;br /&gt;
String jsonBuffer;&lt;br /&gt;
// httpResponseCode holds the response code from the HTTP request.&lt;br /&gt;
int httpResponseCode;&lt;br /&gt;
// myObject is a JSON variable that will hold the parsed JSON data.&lt;br /&gt;
JSONVar myObject;&lt;br /&gt;
&lt;br /&gt;
// Variables related to weather information.&lt;br /&gt;
// weather stores the main weather description.&lt;br /&gt;
String weather;&lt;br /&gt;
// temperature stores the temperature value.&lt;br /&gt;
String temperature;&lt;br /&gt;
// humidity stores the humidity value.&lt;br /&gt;
String humidity;&lt;br /&gt;
// sea_level stores the sea level value.&lt;br /&gt;
String sea_level;&lt;br /&gt;
// wind_speed stores the wind speed value.&lt;br /&gt;
String wind_speed;&lt;br /&gt;
// city_js stores the name of the city.&lt;br /&gt;
String city_js;&lt;br /&gt;
// weather_flag is a flag that determines which weather icon to display based on the weather description.&lt;br /&gt;
int weather_flag = 0;&lt;br /&gt;
&lt;br /&gt;
// Function to display weather forecast on the e-paper display.&lt;br /&gt;
void UI_weather_forecast()&lt;br /&gt;
{&lt;br /&gt;
  char buffer[40];&lt;br /&gt;
&lt;br /&gt;
  EPD_HW_RESET();&lt;br /&gt;
&lt;br /&gt;
  // Display a background picture on the e-paper.&lt;br /&gt;
  EPD_ShowPicture(0, 0, 152, 152, pic, BLACK);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  //If you need to replace the display options,&lt;br /&gt;
  //open the following options: temp, wind, visit, hum&lt;br /&gt;
  //The following uses the hum option as an example&lt;br /&gt;
&lt;br /&gt;
  //Visit&lt;br /&gt;
  //EPD_ShowPicture(76, 92, 56, 72, gImage_visit, BLACK);&lt;br /&gt;
  //Wind&lt;br /&gt;
  //EPD_ShowPicture(76, 92, 56, 72, gImage_wind, BLACK);&lt;br /&gt;
  //Temp&lt;br /&gt;
  //  EPD_ShowPicture(92, 0, 56, 72, gImage_temp, BLACK);&lt;br /&gt;
  //Hum&lt;br /&gt;
&lt;br /&gt;
  EPD_Display(ImageBW);&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_DeepSleep();&lt;br /&gt;
&lt;br /&gt;
  EPD_GPIOInit();&lt;br /&gt;
  Paint_NewImage(ImageBW, EPD_W, EPD_H, 270, WHITE);&lt;br /&gt;
  // Paint_Clear(WHITE);&lt;br /&gt;
  EPD_FastMode1Init();&lt;br /&gt;
  // EPD_Display_Clear();&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_Clear_R26H();&lt;br /&gt;
&lt;br /&gt;
  // Display the update time (it seems to be mislabeled as city_js here, might need to be corrected depending on the actual intention).&lt;br /&gt;
  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, city_js);&lt;br /&gt;
  EPD_ShowString(20, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //If you need to replace the display options,&lt;br /&gt;
  //open the following options: temp, wind, visit, hum&lt;br /&gt;
  //The following uses the hum option as an example&lt;br /&gt;
&lt;br /&gt;
  //Hum&lt;br /&gt;
  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, humidity);&lt;br /&gt;
  EPD_ShowString(105, 140, buffer,  12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //Temp&lt;br /&gt;
  //       memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  //       snprintf(buffer, sizeof(buffer), &amp;quot;%s C&amp;quot;, temperature);&lt;br /&gt;
  //       EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //Wind&lt;br /&gt;
  // memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  // snprintf(buffer, sizeof(buffer), &amp;quot;%s m/s&amp;quot;, wind_speed);&lt;br /&gt;
  // EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //visit&lt;br /&gt;
  //  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  //  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, sea_level);&lt;br /&gt;
  //  EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  // Update the e-paper display with the new content.&lt;br /&gt;
  EPD_Display(ImageBW);&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_DeepSleep();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200); // Initialize the serial communication.&lt;br /&gt;
&lt;br /&gt;
  // Connect to the WiFi network.&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  Serial.println(&amp;quot;Connecting&amp;quot;);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot;&amp;quot;);&lt;br /&gt;
  Serial.print(&amp;quot;Connected to WiFi network with IP Address: &amp;quot;);&lt;br /&gt;
  Serial.println(WiFi.localIP()); // Print the IP address of the device after successful connection.&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Timer set to 10 seconds (timerDelay variable), it will take 10 seconds before publishing the first reading.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Set pin 7 as an output pin to control the power of the e-paper display.&lt;br /&gt;
  pinMode(7, OUTPUT);&lt;br /&gt;
  digitalWrite(7, HIGH);&lt;br /&gt;
&lt;br /&gt;
  EPD_GPIOInit();&lt;br /&gt;
  Paint_NewImage(ImageBW, EPD_W, EPD_H, 0, WHITE);&lt;br /&gt;
  Paint_Clear(WHITE);&lt;br /&gt;
  EPD_FastMode1Init();&lt;br /&gt;
  EPD_Display_Clear();&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_Clear_R26H();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  js_analysis();&lt;br /&gt;
  UI_weather_forecast();&lt;br /&gt;
  delay(1000 * 60 * 60);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void js_analysis()&lt;br /&gt;
{&lt;br /&gt;
  // Check if the device is connected to the WiFi network.&lt;br /&gt;
  if (WiFi.status() == WL_CONNECTED) {&lt;br /&gt;
    // Construct the URL for the OpenWeatherMap API request.&lt;br /&gt;
    String serverPath = &amp;quot;http://api.openweathermap.org/data/2.5/weather?q=&amp;quot; + city + &amp;quot;,&amp;quot; + countryCode + &amp;quot;&amp;amp;APPID=&amp;quot; + openWeatherMapApiKey + &amp;quot;&amp;amp;units=metric&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    // Keep trying until a successful response (status code 200) is received.&lt;br /&gt;
    while (httpResponseCode != 200) {&lt;br /&gt;
      // Make an HTTP GET request to the API and store the response in jsonBuffer.&lt;br /&gt;
      jsonBuffer = httpGETRequest(serverPath.c_str());&lt;br /&gt;
      Serial.println(jsonBuffer);&lt;br /&gt;
      myObject = JSON.parse(jsonBuffer);&lt;br /&gt;
&lt;br /&gt;
      // Check if the JSON parsing was successful.&lt;br /&gt;
      if (JSON.typeof(myObject) == &amp;quot;undefined&amp;quot;) {&lt;br /&gt;
        Serial.println(&amp;quot;Parsing input failed!&amp;quot;);&lt;br /&gt;
        return;&lt;br /&gt;
      }&lt;br /&gt;
      delay(2000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Extract weather information from the parsed JSON data.&lt;br /&gt;
    weather = JSON.stringify(myObject[&amp;quot;weather&amp;quot;][0][&amp;quot;main&amp;quot;]);&lt;br /&gt;
    temperature = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;temp&amp;quot;]);&lt;br /&gt;
    humidity = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;humidity&amp;quot;]);&lt;br /&gt;
    sea_level = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;sea_level&amp;quot;]);&lt;br /&gt;
    wind_speed = JSON.stringify(myObject[&amp;quot;wind&amp;quot;][&amp;quot;speed&amp;quot;]);&lt;br /&gt;
    city_js = JSON.stringify(myObject[&amp;quot;name&amp;quot;]);&lt;br /&gt;
&lt;br /&gt;
    // Print the extracted weather information for debugging purposes.&lt;br /&gt;
    Serial.print(&amp;quot;String weather: &amp;quot;);&lt;br /&gt;
    Serial.println(weather);&lt;br /&gt;
    Serial.print(&amp;quot;String Temperature: &amp;quot;);&lt;br /&gt;
    Serial.println(temperature);&lt;br /&gt;
    Serial.print(&amp;quot;String humidity: &amp;quot;);&lt;br /&gt;
    Serial.println(humidity);&lt;br /&gt;
    Serial.print(&amp;quot;String sea_level: &amp;quot;);&lt;br /&gt;
    Serial.println(sea_level);&lt;br /&gt;
    Serial.print(&amp;quot;String wind_speed: &amp;quot;);&lt;br /&gt;
    Serial.println(wind_speed);&lt;br /&gt;
    Serial.print(&amp;quot;String city_js: &amp;quot;);&lt;br /&gt;
    Serial.println(city_js);&lt;br /&gt;
&lt;br /&gt;
    // Determine the weather icon based on the weather description.&lt;br /&gt;
    if (weather.indexOf(&amp;quot;clouds&amp;quot;) != -1 || weather.indexOf(&amp;quot;Clouds&amp;quot;) != -1 ) {&lt;br /&gt;
      weather_flag = 1;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;clear sky&amp;quot;) != -1 || weather.indexOf(&amp;quot;Clear sky&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 3;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;rain&amp;quot;) != -1 || weather.indexOf(&amp;quot;Rain&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 5;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;thunderstorm&amp;quot;) != -1 || weather.indexOf(&amp;quot;Thunderstorm&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 2;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;snow&amp;quot;) != -1 || weather.indexOf(&amp;quot;Snow&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 4;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;mist&amp;quot;) != -1 || weather.indexOf(&amp;quot;Mist&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 0;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
    // Print a message if the device is not connected to the WiFi network.&lt;br /&gt;
    Serial.println(&amp;quot;WiFi Disconnected&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Function to make an HTTP GET request and return the response.&lt;br /&gt;
String httpGETRequest(const char* serverName) {&lt;br /&gt;
  WiFiClient client;&lt;br /&gt;
  HTTPClient http;&lt;br /&gt;
&lt;br /&gt;
  // Initialize the HTTP client with the server name.&lt;br /&gt;
  http.begin(client, serverName);&lt;br /&gt;
&lt;br /&gt;
  // Send an HTTP GET request.&lt;br /&gt;
  httpResponseCode = http.GET();&lt;br /&gt;
&lt;br /&gt;
  // Initialize the response payload as an empty JSON object.&lt;br /&gt;
  String payload = &amp;quot;{}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  // Check if the response code is positive (indicating a successful request).&lt;br /&gt;
  if (httpResponseCode &amp;gt; 0) {&lt;br /&gt;
    Serial.print(&amp;quot;HTTP Response code: &amp;quot;);&lt;br /&gt;
    Serial.println(httpResponseCode);&lt;br /&gt;
    payload = http.getString();&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
    Serial.print(&amp;quot;Error code: &amp;quot;);&lt;br /&gt;
    Serial.println(httpResponseCode);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Close the HTTP connection.&lt;br /&gt;
  http.end();&lt;br /&gt;
&lt;br /&gt;
  return payload;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 Explications : Partie à modifier avec vos données, ssid, password, openWeatherMapApiKey, city, countryCode&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// WiFi network name // WiFi password&lt;br /&gt;
&lt;br /&gt;
const char* ssid = &amp;quot;yanfa_software&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;yanfa-123456&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// OpenWeatherMap API key. This key is used to access weather data from the OpenWeatherMap API.&lt;br /&gt;
String openWeatherMapApiKey = &amp;quot;3c03d1f4e2dd3e14474a9a3a2f2299ff&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// City and country code for which weather data will be fetched.&lt;br /&gt;
String city = &amp;quot;London&amp;quot;;&lt;br /&gt;
String countryCode = &amp;quot;2643743&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Code HelloWord ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
	* @file HelloWorld.ino&lt;br /&gt;
	* @author HalfSweet (Email:HalfSweet@HalfSweet.cn or QQ:2522182733)&lt;br /&gt;
	* @brief Ce fichier est un exemple de programme permettant d&amp;#039;afficher «Hello World» sur un écran à encre électronique. Il illustre uniquement la méthode la plus simple pour allumer l&amp;#039;écran. &lt;br /&gt;
        * Veuillez consulter la documentation pour connaître l&amp;#039;utilisation des différentes fonctions.&lt;br /&gt;
	* @version 0.1&lt;br /&gt;
	* @date 2022-01-30&lt;br /&gt;
	*&lt;br /&gt;
	* @copyright Copyright (c) 2022&lt;br /&gt;
	*&lt;br /&gt;
*/ &lt;br /&gt;
#include &amp;lt;Arduino.h&amp;gt;&lt;br /&gt;
#include &amp;lt;EPaperDrive.h&amp;gt;&lt;br /&gt;
// Inclure le système de fichiers à utiliser, par exemple:&lt;br /&gt;
#include &amp;lt;LittleFS.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define BAUD_SPEED 74880 // Débit en bauds pour le débogage du port série, modifiable selon les besoins&lt;br /&gt;
&lt;br /&gt;
#define CS 15&lt;br /&gt;
#define RST 2&lt;br /&gt;
#define DC 0&lt;br /&gt;
#define BUSY 4&lt;br /&gt;
#define CLK 14&lt;br /&gt;
#define DIN 13&lt;br /&gt;
&lt;br /&gt;
EPaperDrive EPD(0, CS, RST, DC, BUSY, CLK, DIN); //Instanciation de la bibliothèque de pilotes, utilisant ici le protocole SPI logiciel&lt;br /&gt;
&lt;br /&gt;
const uint8_t city_icon[24] = {&lt;br /&gt;
	/* 0X01,0X01,0X0C,0X00,0X0C,0X00, */&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X1C,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X77,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X41,&lt;br /&gt;
	0X80,&lt;br /&gt;
	0X9C,&lt;br /&gt;
	0X60,&lt;br /&gt;
	0XA2,&lt;br /&gt;
	0X30,&lt;br /&gt;
	0XA2,&lt;br /&gt;
	0X30,&lt;br /&gt;
	0X9C,&lt;br /&gt;
	0XC0,&lt;br /&gt;
	0X41,&lt;br /&gt;
	0X80,&lt;br /&gt;
	0X77,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X1C,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
	void setup()&lt;br /&gt;
	{&lt;br /&gt;
	Serial.begin(BAUD_SPEED);&lt;br /&gt;
	LittleFS.begin(); 			  // Veuillez initialiser manuellement le système de fichiers avant de passer le pointeur.&lt;br /&gt;
&lt;br /&gt;
	EPD.SetFS(&amp;amp;LittleFS); 			 // Définit le système de fichiers pour le stockage des polices. La valeur passée est le pointeur d&amp;#039;opération pour ce système de fichiers. &lt;br /&gt;
                                                 //Vous pouvez la modifier.&lt;br /&gt;
	EPD.EPD_Set_Model(HINKE0266A15A0); 	 // Définit le type d&amp;#039;écran. Consultez la documentation pour les modèles spécifiques.&lt;br /&gt;
	EPD.EPD_init_Full(); 			// Initialisation du rafraîchissement complet, en utilisant la forme d&amp;#039;onde de rafraîchissement complet.&lt;br /&gt;
	EPD.clearbuffer(); 		        // Efface le tampon (écran blanc).&lt;br /&gt;
	EPD.fontscale = 2; 			// Facteur d&amp;#039;échelle des polices (1 et 2 pris en charge, également applicable aux images. &lt;br /&gt;
                                                // N&amp;#039;oubliez pas de le remettre à 1 après utilisation).&lt;br /&gt;
	EPD.SetFont(FONT12); 		       // Sélectionne la police. Consultez la documentation pour connaître les polices prises en charge.&lt;br /&gt;
	EPD.DrawUTF(0, 0, &amp;quot;Hello&amp;quot;); &amp;quot;World&amp;quot;);  // Dessiner la chaîne&lt;br /&gt;
	EPD.DrawUTF(26, 0, &amp;quot;J&amp;#039;aime les écrans à encre électronique&amp;quot;); 	&lt;br /&gt;
                                               // Dessiner la chaîne&lt;br /&gt;
	EPD.fontscale = 1; 		       // Rétablir le facteur d&amp;#039;échelle de la police à 1&lt;br /&gt;
	EPD.DrawXbm_P(60, 0, 12, 12, (uint8_t *)city_icon); 			 // Dessiner l&amp;#039;image&lt;br /&gt;
&lt;br /&gt;
	Serial.printf(&amp;quot;Image tamponnée dessinée, prête pour un rafraîchissement complet\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_Dis_Full((uint8_t *)EPD.EPDbuffer, 1); // Transmettre l&amp;#039;image tamponnée à la puce de contrôle de l&amp;#039;écran pour un rafraîchissement complet&lt;br /&gt;
	EPD.deepsleep(); // Mettre l&amp;#039;écran en veille&lt;br /&gt;
	Serial.println(&amp;quot;Rafraîchissement complet terminé&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	delay(5000);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_init_Part(); // Initialiser la partie Actualisation&lt;br /&gt;
	EPD.clearbuffer();&lt;br /&gt;
	EPD.fontscale = 2;&lt;br /&gt;
	EPD.SetFont(FONT12); EPD.DrawUTF(0, 0, &amp;quot;Actualisation locale activée&amp;quot;);&lt;br /&gt;
	Serial.printf(&amp;quot;Actualisation locale en cours\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_Dis_Part(0, 23, 0, 199, (uint8_t *)EPD.EPDbuffer, 1); // Transfert de l&amp;#039;image du tampon vers la puce de contrôle d&amp;#039;écran pour l&amp;#039;actualisation locale sur le nouvel écran&lt;br /&gt;
	Serial.printf(&amp;quot;Actualisation locale terminée\n&amp;quot;);&lt;br /&gt;
	EPD.deepsleep();&lt;br /&gt;
&lt;br /&gt;
} void loop()&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
	delay(1); // Empêcher le chien de garde de s&amp;#039;interrompre&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>144.2.107.134</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1908</id>
		<title>CrowPanel-ESP32-E-Paper-HMI-1.54</title>
		<link rel="alternate" type="text/html" href="https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1908"/>
		<updated>2025-11-26T23:28:04Z</updated>

		<summary type="html">&lt;p&gt;144.2.107.134: /* Arduine Mise en route (Setup) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== E-Paper-HMI-1.54 (Elecrow) ==&lt;br /&gt;
&lt;br /&gt;
=== Liens externes ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_HMI_1.54-inch_Display.html Wiki&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_1.54-inch_Arduino_Tutorial.html Arduino Setup&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/crowpanel-esp32-1-54-e-paper-hmi-display-with-152-152-resolution-black-white-color-driven-by-spi-interface.html Shop&lt;br /&gt;
&lt;br /&gt;
 BLE debugging assistant&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/1-54-inch-152-152-e-paper-display-black-white-e-ink-display-with-spi-communication.html&lt;br /&gt;
&lt;br /&gt;
=== Caractéristiques ===&lt;br /&gt;
&lt;br /&gt;
Driver Chip : &amp;lt;b&amp;gt;SSD1680&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Résolution 152 x 152&amp;lt;br&amp;gt;&lt;br /&gt;
Couleur noir et blanc&amp;lt;br&amp;gt;&lt;br /&gt;
Pilote ESP32-S3 comme contrôleur principal&amp;lt;br&amp;gt;&lt;br /&gt;
PSRAM : 8MB&amp;lt;br&amp;gt;&lt;br /&gt;
Flash :	8MB&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Images ===&lt;br /&gt;
[[File:E-Paper-HMI-1.54-1.png|300px]]&lt;br /&gt;
&lt;br /&gt;
[[File:E-Paper-HMI-1.54-2.png|300px]]&lt;br /&gt;
[[File:E-Paper-HMI-1.54-3.png|300px]]&lt;br /&gt;
&lt;br /&gt;
=== Ressources ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/download/product/CrowPanel/E-paper/Image2Lcd_v2.9.zip Image2Lcd_v2.9&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152 GitHub&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152/archive/refs/heads/master.zip GitHub ZIP&lt;br /&gt;
&lt;br /&gt;
=== Arduine Mise en route (Setup) ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Téléchargez les fichiers de bibliothèque utilisés par ce produit dans le dossier « bibliothèques ».&lt;br /&gt;
&lt;br /&gt;
C:\Users\Documents\Arduino\libraries\&lt;br /&gt;
&lt;br /&gt;
2.Ouvrez l&amp;#039;IDE Arduino&amp;lt;br&amp;gt;&lt;br /&gt;
chercher ESP32 dans Boards Manager, installez si cela n&amp;#039;est pas déjà fait &amp;lt;br&amp;gt;&lt;br /&gt;
by Espressif Systems&lt;br /&gt;
&lt;br /&gt;
Click &amp;quot;Tools&amp;quot;-&amp;gt;&amp;quot;Board&amp;quot;-&amp;gt;&amp;quot;esp32&amp;quot;-&amp;gt;&amp;quot;ESP32S3 Dev Module&amp;quot;, &lt;br /&gt;
&lt;br /&gt;
and the &amp;quot;Partition Scheme&amp;quot; select &lt;br /&gt;
&amp;quot;Huge APP (3MB No OTA/1MB SPIFFS)&amp;quot;, &lt;br /&gt;
&amp;quot;PSRAM&amp;quot; select &amp;quot;OPI PSRAM&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[File:Setup-Arduino-1.png|300px]]&lt;br /&gt;
&lt;br /&gt;
=== Librairies ===&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;Arduino.h&amp;gt;   // Inclure la bibliothèque principale Arduino&lt;br /&gt;
 #include &amp;quot;EPD_GUI.h&amp;quot;   // Inclure la bibliothèque pour l&amp;#039;écran à encre électronique&lt;br /&gt;
 #include &amp;quot;Pic.h&amp;quot;       // Inclure la bibliothèque de fonctions personnalisées&lt;br /&gt;
 #include &amp;quot;FS.h&amp;quot;        // Bibliothèque du système de fichiers pour les opérations sur les fichiers&lt;br /&gt;
 #include &amp;quot;SPIFFS.h&amp;quot;    // Bibliothèque du système de fichiers SPIFFS pour la lecture et l&amp;#039;écriture de fichiers&lt;br /&gt;
 #include &amp;lt;WiFi.h&amp;gt;      // Bibliothèque WiFi pour la création et la gestion des connexions WiFi&lt;br /&gt;
 #include &amp;lt;Ticker.h&amp;gt;    // Bibliothèque de chronométrage&lt;br /&gt;
 #include &amp;lt;WebServer.h&amp;gt; // Bibliothèque de serveur Web pour la création d&amp;#039;un serveur HTTP&lt;br /&gt;
&lt;br /&gt;
=== Code Exemples ===&lt;br /&gt;
&lt;br /&gt;
Arduino Code for demos&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_WIFI_refresh.ino &amp;lt;b&amp;gt;Update via WiFi&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_ble_refresh.ino  &amp;lt;b&amp;gt;Update via Bluetooth&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_wifi_http_openweather.ino&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arduino Code for examples&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_PWR.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_wifi.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_BLE.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_key.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_Global_refresh.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_partial_refresh.ino&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=smDFHRxDYdw&lt;br /&gt;
&lt;br /&gt;
=== Code wifi_http_openweather ===&lt;br /&gt;
&lt;br /&gt;
https://openweathermap.org/ Veuillez vous enregistrer afin de vous procurer votre OpenWeatherMap API key&lt;br /&gt;
&lt;br /&gt;
http://bulk.openweathermap.org/sample/ on trouve ici : city.list.json.gz, le countryCode de votre ville (variable city)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;lt;HTTPClient.h&amp;gt;&lt;br /&gt;
#include &amp;lt;Arduino_JSON.h&amp;gt;&lt;br /&gt;
#include &amp;quot;EPD_GUI.h&amp;quot;&lt;br /&gt;
#include &amp;quot;Pic.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
// Define an array for black and white image data, which serves as the buffer for the e-paper display.&lt;br /&gt;
// The size of the buffer is determined according to the resolution of the e-paper display.&lt;br /&gt;
uint8_t ImageBW[2888];&lt;br /&gt;
&lt;br /&gt;
// WiFi network name // WiFi password&lt;br /&gt;
const char* ssid = &amp;quot;yanfa_software&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;yanfa-123456&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// OpenWeatherMap API key. This key is used to access weather data from the OpenWeatherMap API.&lt;br /&gt;
String openWeatherMapApiKey = &amp;quot;3c03d1f4e2dd3e14474a9a3a2f2299ff&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// City and country code for which weather data will be fetched.&lt;br /&gt;
String city = &amp;quot;London&amp;quot;;&lt;br /&gt;
String countryCode = &amp;quot;2643743&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Variables related to timing and API calls.&lt;br /&gt;
// lastTime keeps track of the last time the API was called.&lt;br /&gt;
unsigned long lastTime = 0;&lt;br /&gt;
// timerDelay determines the time interval between API calls. For testing, it&amp;#039;s set to 10 seconds (10000 milliseconds).&lt;br /&gt;
// In a final application, this should be set according to the API call limits per hour/minute.&lt;br /&gt;
unsigned long timerDelay = 10000;&lt;br /&gt;
&lt;br /&gt;
// Variables related to JSON data.&lt;br /&gt;
// jsonBuffer stores the raw JSON data received from the API.&lt;br /&gt;
String jsonBuffer;&lt;br /&gt;
// httpResponseCode holds the response code from the HTTP request.&lt;br /&gt;
int httpResponseCode;&lt;br /&gt;
// myObject is a JSON variable that will hold the parsed JSON data.&lt;br /&gt;
JSONVar myObject;&lt;br /&gt;
&lt;br /&gt;
// Variables related to weather information.&lt;br /&gt;
// weather stores the main weather description.&lt;br /&gt;
String weather;&lt;br /&gt;
// temperature stores the temperature value.&lt;br /&gt;
String temperature;&lt;br /&gt;
// humidity stores the humidity value.&lt;br /&gt;
String humidity;&lt;br /&gt;
// sea_level stores the sea level value.&lt;br /&gt;
String sea_level;&lt;br /&gt;
// wind_speed stores the wind speed value.&lt;br /&gt;
String wind_speed;&lt;br /&gt;
// city_js stores the name of the city.&lt;br /&gt;
String city_js;&lt;br /&gt;
// weather_flag is a flag that determines which weather icon to display based on the weather description.&lt;br /&gt;
int weather_flag = 0;&lt;br /&gt;
&lt;br /&gt;
// Function to display weather forecast on the e-paper display.&lt;br /&gt;
void UI_weather_forecast()&lt;br /&gt;
{&lt;br /&gt;
  char buffer[40];&lt;br /&gt;
&lt;br /&gt;
  EPD_HW_RESET();&lt;br /&gt;
&lt;br /&gt;
  // Display a background picture on the e-paper.&lt;br /&gt;
  EPD_ShowPicture(0, 0, 152, 152, pic, BLACK);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  //If you need to replace the display options,&lt;br /&gt;
  //open the following options: temp, wind, visit, hum&lt;br /&gt;
  //The following uses the hum option as an example&lt;br /&gt;
&lt;br /&gt;
  //Visit&lt;br /&gt;
  //EPD_ShowPicture(76, 92, 56, 72, gImage_visit, BLACK);&lt;br /&gt;
  //Wind&lt;br /&gt;
  //EPD_ShowPicture(76, 92, 56, 72, gImage_wind, BLACK);&lt;br /&gt;
  //Temp&lt;br /&gt;
  //  EPD_ShowPicture(92, 0, 56, 72, gImage_temp, BLACK);&lt;br /&gt;
  //Hum&lt;br /&gt;
&lt;br /&gt;
  EPD_Display(ImageBW);&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_DeepSleep();&lt;br /&gt;
&lt;br /&gt;
  EPD_GPIOInit();&lt;br /&gt;
  Paint_NewImage(ImageBW, EPD_W, EPD_H, 270, WHITE);&lt;br /&gt;
  // Paint_Clear(WHITE);&lt;br /&gt;
  EPD_FastMode1Init();&lt;br /&gt;
  // EPD_Display_Clear();&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_Clear_R26H();&lt;br /&gt;
&lt;br /&gt;
  // Display the update time (it seems to be mislabeled as city_js here, might need to be corrected depending on the actual intention).&lt;br /&gt;
  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, city_js);&lt;br /&gt;
  EPD_ShowString(20, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //If you need to replace the display options,&lt;br /&gt;
  //open the following options: temp, wind, visit, hum&lt;br /&gt;
  //The following uses the hum option as an example&lt;br /&gt;
&lt;br /&gt;
  //Hum&lt;br /&gt;
  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, humidity);&lt;br /&gt;
  EPD_ShowString(105, 140, buffer,  12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //Temp&lt;br /&gt;
  //       memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  //       snprintf(buffer, sizeof(buffer), &amp;quot;%s C&amp;quot;, temperature);&lt;br /&gt;
  //       EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //Wind&lt;br /&gt;
  // memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  // snprintf(buffer, sizeof(buffer), &amp;quot;%s m/s&amp;quot;, wind_speed);&lt;br /&gt;
  // EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //visit&lt;br /&gt;
  //  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  //  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, sea_level);&lt;br /&gt;
  //  EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  // Update the e-paper display with the new content.&lt;br /&gt;
  EPD_Display(ImageBW);&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_DeepSleep();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200); // Initialize the serial communication.&lt;br /&gt;
&lt;br /&gt;
  // Connect to the WiFi network.&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  Serial.println(&amp;quot;Connecting&amp;quot;);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot;&amp;quot;);&lt;br /&gt;
  Serial.print(&amp;quot;Connected to WiFi network with IP Address: &amp;quot;);&lt;br /&gt;
  Serial.println(WiFi.localIP()); // Print the IP address of the device after successful connection.&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Timer set to 10 seconds (timerDelay variable), it will take 10 seconds before publishing the first reading.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Set pin 7 as an output pin to control the power of the e-paper display.&lt;br /&gt;
  pinMode(7, OUTPUT);&lt;br /&gt;
  digitalWrite(7, HIGH);&lt;br /&gt;
&lt;br /&gt;
  EPD_GPIOInit();&lt;br /&gt;
  Paint_NewImage(ImageBW, EPD_W, EPD_H, 0, WHITE);&lt;br /&gt;
  Paint_Clear(WHITE);&lt;br /&gt;
  EPD_FastMode1Init();&lt;br /&gt;
  EPD_Display_Clear();&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_Clear_R26H();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  js_analysis();&lt;br /&gt;
  UI_weather_forecast();&lt;br /&gt;
  delay(1000 * 60 * 60);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void js_analysis()&lt;br /&gt;
{&lt;br /&gt;
  // Check if the device is connected to the WiFi network.&lt;br /&gt;
  if (WiFi.status() == WL_CONNECTED) {&lt;br /&gt;
    // Construct the URL for the OpenWeatherMap API request.&lt;br /&gt;
    String serverPath = &amp;quot;http://api.openweathermap.org/data/2.5/weather?q=&amp;quot; + city + &amp;quot;,&amp;quot; + countryCode + &amp;quot;&amp;amp;APPID=&amp;quot; + openWeatherMapApiKey + &amp;quot;&amp;amp;units=metric&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    // Keep trying until a successful response (status code 200) is received.&lt;br /&gt;
    while (httpResponseCode != 200) {&lt;br /&gt;
      // Make an HTTP GET request to the API and store the response in jsonBuffer.&lt;br /&gt;
      jsonBuffer = httpGETRequest(serverPath.c_str());&lt;br /&gt;
      Serial.println(jsonBuffer);&lt;br /&gt;
      myObject = JSON.parse(jsonBuffer);&lt;br /&gt;
&lt;br /&gt;
      // Check if the JSON parsing was successful.&lt;br /&gt;
      if (JSON.typeof(myObject) == &amp;quot;undefined&amp;quot;) {&lt;br /&gt;
        Serial.println(&amp;quot;Parsing input failed!&amp;quot;);&lt;br /&gt;
        return;&lt;br /&gt;
      }&lt;br /&gt;
      delay(2000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Extract weather information from the parsed JSON data.&lt;br /&gt;
    weather = JSON.stringify(myObject[&amp;quot;weather&amp;quot;][0][&amp;quot;main&amp;quot;]);&lt;br /&gt;
    temperature = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;temp&amp;quot;]);&lt;br /&gt;
    humidity = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;humidity&amp;quot;]);&lt;br /&gt;
    sea_level = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;sea_level&amp;quot;]);&lt;br /&gt;
    wind_speed = JSON.stringify(myObject[&amp;quot;wind&amp;quot;][&amp;quot;speed&amp;quot;]);&lt;br /&gt;
    city_js = JSON.stringify(myObject[&amp;quot;name&amp;quot;]);&lt;br /&gt;
&lt;br /&gt;
    // Print the extracted weather information for debugging purposes.&lt;br /&gt;
    Serial.print(&amp;quot;String weather: &amp;quot;);&lt;br /&gt;
    Serial.println(weather);&lt;br /&gt;
    Serial.print(&amp;quot;String Temperature: &amp;quot;);&lt;br /&gt;
    Serial.println(temperature);&lt;br /&gt;
    Serial.print(&amp;quot;String humidity: &amp;quot;);&lt;br /&gt;
    Serial.println(humidity);&lt;br /&gt;
    Serial.print(&amp;quot;String sea_level: &amp;quot;);&lt;br /&gt;
    Serial.println(sea_level);&lt;br /&gt;
    Serial.print(&amp;quot;String wind_speed: &amp;quot;);&lt;br /&gt;
    Serial.println(wind_speed);&lt;br /&gt;
    Serial.print(&amp;quot;String city_js: &amp;quot;);&lt;br /&gt;
    Serial.println(city_js);&lt;br /&gt;
&lt;br /&gt;
    // Determine the weather icon based on the weather description.&lt;br /&gt;
    if (weather.indexOf(&amp;quot;clouds&amp;quot;) != -1 || weather.indexOf(&amp;quot;Clouds&amp;quot;) != -1 ) {&lt;br /&gt;
      weather_flag = 1;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;clear sky&amp;quot;) != -1 || weather.indexOf(&amp;quot;Clear sky&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 3;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;rain&amp;quot;) != -1 || weather.indexOf(&amp;quot;Rain&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 5;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;thunderstorm&amp;quot;) != -1 || weather.indexOf(&amp;quot;Thunderstorm&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 2;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;snow&amp;quot;) != -1 || weather.indexOf(&amp;quot;Snow&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 4;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;mist&amp;quot;) != -1 || weather.indexOf(&amp;quot;Mist&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 0;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
    // Print a message if the device is not connected to the WiFi network.&lt;br /&gt;
    Serial.println(&amp;quot;WiFi Disconnected&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Function to make an HTTP GET request and return the response.&lt;br /&gt;
String httpGETRequest(const char* serverName) {&lt;br /&gt;
  WiFiClient client;&lt;br /&gt;
  HTTPClient http;&lt;br /&gt;
&lt;br /&gt;
  // Initialize the HTTP client with the server name.&lt;br /&gt;
  http.begin(client, serverName);&lt;br /&gt;
&lt;br /&gt;
  // Send an HTTP GET request.&lt;br /&gt;
  httpResponseCode = http.GET();&lt;br /&gt;
&lt;br /&gt;
  // Initialize the response payload as an empty JSON object.&lt;br /&gt;
  String payload = &amp;quot;{}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  // Check if the response code is positive (indicating a successful request).&lt;br /&gt;
  if (httpResponseCode &amp;gt; 0) {&lt;br /&gt;
    Serial.print(&amp;quot;HTTP Response code: &amp;quot;);&lt;br /&gt;
    Serial.println(httpResponseCode);&lt;br /&gt;
    payload = http.getString();&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
    Serial.print(&amp;quot;Error code: &amp;quot;);&lt;br /&gt;
    Serial.println(httpResponseCode);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Close the HTTP connection.&lt;br /&gt;
  http.end();&lt;br /&gt;
&lt;br /&gt;
  return payload;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 Explications : Partie à modifier avec vos données, ssid, password, openWeatherMapApiKey, city, countryCode&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// WiFi network name // WiFi password&lt;br /&gt;
&lt;br /&gt;
const char* ssid = &amp;quot;yanfa_software&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;yanfa-123456&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// OpenWeatherMap API key. This key is used to access weather data from the OpenWeatherMap API.&lt;br /&gt;
String openWeatherMapApiKey = &amp;quot;3c03d1f4e2dd3e14474a9a3a2f2299ff&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// City and country code for which weather data will be fetched.&lt;br /&gt;
String city = &amp;quot;London&amp;quot;;&lt;br /&gt;
String countryCode = &amp;quot;2643743&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Code HelloWord ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
	* @file HelloWorld.ino&lt;br /&gt;
	* @author HalfSweet (Email:HalfSweet@HalfSweet.cn or QQ:2522182733)&lt;br /&gt;
	* @brief Ce fichier est un exemple de programme permettant d&amp;#039;afficher «Hello World» sur un écran à encre électronique. Il illustre uniquement la méthode la plus simple pour allumer l&amp;#039;écran. &lt;br /&gt;
        * Veuillez consulter la documentation pour connaître l&amp;#039;utilisation des différentes fonctions.&lt;br /&gt;
	* @version 0.1&lt;br /&gt;
	* @date 2022-01-30&lt;br /&gt;
	*&lt;br /&gt;
	* @copyright Copyright (c) 2022&lt;br /&gt;
	*&lt;br /&gt;
*/ &lt;br /&gt;
#include &amp;lt;Arduino.h&amp;gt;&lt;br /&gt;
#include &amp;lt;EPaperDrive.h&amp;gt;&lt;br /&gt;
// Inclure le système de fichiers à utiliser, par exemple:&lt;br /&gt;
#include &amp;lt;LittleFS.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define BAUD_SPEED 74880 // Débit en bauds pour le débogage du port série, modifiable selon les besoins&lt;br /&gt;
&lt;br /&gt;
#define CS 15&lt;br /&gt;
#define RST 2&lt;br /&gt;
#define DC 0&lt;br /&gt;
#define BUSY 4&lt;br /&gt;
#define CLK 14&lt;br /&gt;
#define DIN 13&lt;br /&gt;
&lt;br /&gt;
EPaperDrive EPD(0, CS, RST, DC, BUSY, CLK, DIN); //Instanciation de la bibliothèque de pilotes, utilisant ici le protocole SPI logiciel&lt;br /&gt;
&lt;br /&gt;
const uint8_t city_icon[24] = {&lt;br /&gt;
	/* 0X01,0X01,0X0C,0X00,0X0C,0X00, */&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X1C,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X77,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X41,&lt;br /&gt;
	0X80,&lt;br /&gt;
	0X9C,&lt;br /&gt;
	0X60,&lt;br /&gt;
	0XA2,&lt;br /&gt;
	0X30,&lt;br /&gt;
	0XA2,&lt;br /&gt;
	0X30,&lt;br /&gt;
	0X9C,&lt;br /&gt;
	0XC0,&lt;br /&gt;
	0X41,&lt;br /&gt;
	0X80,&lt;br /&gt;
	0X77,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X1C,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
	void setup()&lt;br /&gt;
	{&lt;br /&gt;
	Serial.begin(BAUD_SPEED);&lt;br /&gt;
	LittleFS.begin(); 			  // Veuillez initialiser manuellement le système de fichiers avant de passer le pointeur.&lt;br /&gt;
&lt;br /&gt;
	EPD.SetFS(&amp;amp;LittleFS); 			 // Définit le système de fichiers pour le stockage des polices. La valeur passée est le pointeur d&amp;#039;opération pour ce système de fichiers. &lt;br /&gt;
                                                 //Vous pouvez la modifier.&lt;br /&gt;
	EPD.EPD_Set_Model(HINKE0266A15A0); 	 // Définit le type d&amp;#039;écran. Consultez la documentation pour les modèles spécifiques.&lt;br /&gt;
	EPD.EPD_init_Full(); 			// Initialisation du rafraîchissement complet, en utilisant la forme d&amp;#039;onde de rafraîchissement complet.&lt;br /&gt;
	EPD.clearbuffer(); 		        // Efface le tampon (écran blanc).&lt;br /&gt;
	EPD.fontscale = 2; 			// Facteur d&amp;#039;échelle des polices (1 et 2 pris en charge, également applicable aux images. &lt;br /&gt;
                                                // N&amp;#039;oubliez pas de le remettre à 1 après utilisation).&lt;br /&gt;
	EPD.SetFont(FONT12); 		       // Sélectionne la police. Consultez la documentation pour connaître les polices prises en charge.&lt;br /&gt;
	EPD.DrawUTF(0, 0, &amp;quot;Hello&amp;quot;); &amp;quot;World&amp;quot;);  // Dessiner la chaîne&lt;br /&gt;
	EPD.DrawUTF(26, 0, &amp;quot;J&amp;#039;aime les écrans à encre électronique&amp;quot;); 	&lt;br /&gt;
                                               // Dessiner la chaîne&lt;br /&gt;
	EPD.fontscale = 1; 		       // Rétablir le facteur d&amp;#039;échelle de la police à 1&lt;br /&gt;
	EPD.DrawXbm_P(60, 0, 12, 12, (uint8_t *)city_icon); 			 // Dessiner l&amp;#039;image&lt;br /&gt;
&lt;br /&gt;
	Serial.printf(&amp;quot;Image tamponnée dessinée, prête pour un rafraîchissement complet\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_Dis_Full((uint8_t *)EPD.EPDbuffer, 1); // Transmettre l&amp;#039;image tamponnée à la puce de contrôle de l&amp;#039;écran pour un rafraîchissement complet&lt;br /&gt;
	EPD.deepsleep(); // Mettre l&amp;#039;écran en veille&lt;br /&gt;
	Serial.println(&amp;quot;Rafraîchissement complet terminé&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	delay(5000);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_init_Part(); // Initialiser la partie Actualisation&lt;br /&gt;
	EPD.clearbuffer();&lt;br /&gt;
	EPD.fontscale = 2;&lt;br /&gt;
	EPD.SetFont(FONT12); EPD.DrawUTF(0, 0, &amp;quot;Actualisation locale activée&amp;quot;);&lt;br /&gt;
	Serial.printf(&amp;quot;Actualisation locale en cours\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_Dis_Part(0, 23, 0, 199, (uint8_t *)EPD.EPDbuffer, 1); // Transfert de l&amp;#039;image du tampon vers la puce de contrôle d&amp;#039;écran pour l&amp;#039;actualisation locale sur le nouvel écran&lt;br /&gt;
	Serial.printf(&amp;quot;Actualisation locale terminée\n&amp;quot;);&lt;br /&gt;
	EPD.deepsleep();&lt;br /&gt;
&lt;br /&gt;
} void loop()&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
	delay(1); // Empêcher le chien de garde de s&amp;#039;interrompre&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>144.2.107.134</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1900</id>
		<title>CrowPanel-ESP32-E-Paper-HMI-1.54</title>
		<link rel="alternate" type="text/html" href="https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1900"/>
		<updated>2025-11-24T23:59:59Z</updated>

		<summary type="html">&lt;p&gt;144.2.107.134: /* Code Exemples */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== E-Paper-HMI-1.54 (Elecrow) ==&lt;br /&gt;
&lt;br /&gt;
=== Liens externes ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_HMI_1.54-inch_Display.html Wiki&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_1.54-inch_Arduino_Tutorial.html Arduino Setup&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/crowpanel-esp32-1-54-e-paper-hmi-display-with-152-152-resolution-black-white-color-driven-by-spi-interface.html Shop&lt;br /&gt;
&lt;br /&gt;
 BLE debugging assistant&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/1-54-inch-152-152-e-paper-display-black-white-e-ink-display-with-spi-communication.html&lt;br /&gt;
&lt;br /&gt;
=== Caractéristiques ===&lt;br /&gt;
&lt;br /&gt;
Driver Chip : &amp;lt;b&amp;gt;SSD1680&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Résolution 152 x 152&amp;lt;br&amp;gt;&lt;br /&gt;
Couleur noir et blanc&amp;lt;br&amp;gt;&lt;br /&gt;
Pilote ESP32-S3 comme contrôleur principal&amp;lt;br&amp;gt;&lt;br /&gt;
PSRAM : 8MB&amp;lt;br&amp;gt;&lt;br /&gt;
Flash :	8MB&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Images ===&lt;br /&gt;
[[File:E-Paper-HMI-1.54-1.png|300px]]&lt;br /&gt;
&lt;br /&gt;
[[File:E-Paper-HMI-1.54-2.png|300px]]&lt;br /&gt;
[[File:E-Paper-HMI-1.54-3.png|300px]]&lt;br /&gt;
&lt;br /&gt;
=== Ressources ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/download/product/CrowPanel/E-paper/Image2Lcd_v2.9.zip Image2Lcd_v2.9&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152 GitHub&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152/archive/refs/heads/master.zip GitHub ZIP&lt;br /&gt;
&lt;br /&gt;
=== Arduine Mise en route (Setup) ===&lt;br /&gt;
&lt;br /&gt;
Click &amp;quot;Tools&amp;quot;-&amp;gt;&amp;quot;Board&amp;quot;-&amp;gt;&amp;quot;esp32&amp;quot;-&amp;gt;&amp;quot;ESP32S3 Dev Module&amp;quot;, &lt;br /&gt;
&lt;br /&gt;
and the &amp;quot;Partition Scheme&amp;quot; select &lt;br /&gt;
&amp;quot;Huge APP (3MB No OTA/1MB SPIFFS)&amp;quot;, &lt;br /&gt;
&amp;quot;PSRAM&amp;quot; select &amp;quot;OPI PSRAM&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[File:Setup-Arduino-1.png|300px]]&lt;br /&gt;
&lt;br /&gt;
=== Librairies ===&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;Arduino.h&amp;gt;   // Inclure la bibliothèque principale Arduino&lt;br /&gt;
 #include &amp;quot;EPD_GUI.h&amp;quot;   // Inclure la bibliothèque pour l&amp;#039;écran à encre électronique&lt;br /&gt;
 #include &amp;quot;Pic.h&amp;quot;       // Inclure la bibliothèque de fonctions personnalisées&lt;br /&gt;
 #include &amp;quot;FS.h&amp;quot;        // Bibliothèque du système de fichiers pour les opérations sur les fichiers&lt;br /&gt;
 #include &amp;quot;SPIFFS.h&amp;quot;    // Bibliothèque du système de fichiers SPIFFS pour la lecture et l&amp;#039;écriture de fichiers&lt;br /&gt;
 #include &amp;lt;WiFi.h&amp;gt;      // Bibliothèque WiFi pour la création et la gestion des connexions WiFi&lt;br /&gt;
 #include &amp;lt;Ticker.h&amp;gt;    // Bibliothèque de chronométrage&lt;br /&gt;
 #include &amp;lt;WebServer.h&amp;gt; // Bibliothèque de serveur Web pour la création d&amp;#039;un serveur HTTP&lt;br /&gt;
&lt;br /&gt;
=== Code Exemples ===&lt;br /&gt;
&lt;br /&gt;
Arduino Code for demos&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_WIFI_refresh.ino &amp;lt;b&amp;gt;Update via WiFi&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_ble_refresh.ino  &amp;lt;b&amp;gt;Update via Bluetooth&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_wifi_http_openweather.ino&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arduino Code for examples&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_PWR.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_wifi.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_BLE.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_key.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_Global_refresh.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_partial_refresh.ino&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=smDFHRxDYdw&lt;br /&gt;
&lt;br /&gt;
=== Code wifi_http_openweather ===&lt;br /&gt;
&lt;br /&gt;
https://openweathermap.org/ Veuillez vous enregistrer afin de vous procurer votre OpenWeatherMap API key&lt;br /&gt;
&lt;br /&gt;
http://bulk.openweathermap.org/sample/ on trouve ici : city.list.json.gz, le countryCode de votre ville (variable city)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;lt;HTTPClient.h&amp;gt;&lt;br /&gt;
#include &amp;lt;Arduino_JSON.h&amp;gt;&lt;br /&gt;
#include &amp;quot;EPD_GUI.h&amp;quot;&lt;br /&gt;
#include &amp;quot;Pic.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
// Define an array for black and white image data, which serves as the buffer for the e-paper display.&lt;br /&gt;
// The size of the buffer is determined according to the resolution of the e-paper display.&lt;br /&gt;
uint8_t ImageBW[2888];&lt;br /&gt;
&lt;br /&gt;
// WiFi network name // WiFi password&lt;br /&gt;
const char* ssid = &amp;quot;yanfa_software&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;yanfa-123456&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// OpenWeatherMap API key. This key is used to access weather data from the OpenWeatherMap API.&lt;br /&gt;
String openWeatherMapApiKey = &amp;quot;3c03d1f4e2dd3e14474a9a3a2f2299ff&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// City and country code for which weather data will be fetched.&lt;br /&gt;
String city = &amp;quot;London&amp;quot;;&lt;br /&gt;
String countryCode = &amp;quot;2643743&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Variables related to timing and API calls.&lt;br /&gt;
// lastTime keeps track of the last time the API was called.&lt;br /&gt;
unsigned long lastTime = 0;&lt;br /&gt;
// timerDelay determines the time interval between API calls. For testing, it&amp;#039;s set to 10 seconds (10000 milliseconds).&lt;br /&gt;
// In a final application, this should be set according to the API call limits per hour/minute.&lt;br /&gt;
unsigned long timerDelay = 10000;&lt;br /&gt;
&lt;br /&gt;
// Variables related to JSON data.&lt;br /&gt;
// jsonBuffer stores the raw JSON data received from the API.&lt;br /&gt;
String jsonBuffer;&lt;br /&gt;
// httpResponseCode holds the response code from the HTTP request.&lt;br /&gt;
int httpResponseCode;&lt;br /&gt;
// myObject is a JSON variable that will hold the parsed JSON data.&lt;br /&gt;
JSONVar myObject;&lt;br /&gt;
&lt;br /&gt;
// Variables related to weather information.&lt;br /&gt;
// weather stores the main weather description.&lt;br /&gt;
String weather;&lt;br /&gt;
// temperature stores the temperature value.&lt;br /&gt;
String temperature;&lt;br /&gt;
// humidity stores the humidity value.&lt;br /&gt;
String humidity;&lt;br /&gt;
// sea_level stores the sea level value.&lt;br /&gt;
String sea_level;&lt;br /&gt;
// wind_speed stores the wind speed value.&lt;br /&gt;
String wind_speed;&lt;br /&gt;
// city_js stores the name of the city.&lt;br /&gt;
String city_js;&lt;br /&gt;
// weather_flag is a flag that determines which weather icon to display based on the weather description.&lt;br /&gt;
int weather_flag = 0;&lt;br /&gt;
&lt;br /&gt;
// Function to display weather forecast on the e-paper display.&lt;br /&gt;
void UI_weather_forecast()&lt;br /&gt;
{&lt;br /&gt;
  char buffer[40];&lt;br /&gt;
&lt;br /&gt;
  EPD_HW_RESET();&lt;br /&gt;
&lt;br /&gt;
  // Display a background picture on the e-paper.&lt;br /&gt;
  EPD_ShowPicture(0, 0, 152, 152, pic, BLACK);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  //If you need to replace the display options,&lt;br /&gt;
  //open the following options: temp, wind, visit, hum&lt;br /&gt;
  //The following uses the hum option as an example&lt;br /&gt;
&lt;br /&gt;
  //Visit&lt;br /&gt;
  //EPD_ShowPicture(76, 92, 56, 72, gImage_visit, BLACK);&lt;br /&gt;
  //Wind&lt;br /&gt;
  //EPD_ShowPicture(76, 92, 56, 72, gImage_wind, BLACK);&lt;br /&gt;
  //Temp&lt;br /&gt;
  //  EPD_ShowPicture(92, 0, 56, 72, gImage_temp, BLACK);&lt;br /&gt;
  //Hum&lt;br /&gt;
&lt;br /&gt;
  EPD_Display(ImageBW);&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_DeepSleep();&lt;br /&gt;
&lt;br /&gt;
  EPD_GPIOInit();&lt;br /&gt;
  Paint_NewImage(ImageBW, EPD_W, EPD_H, 270, WHITE);&lt;br /&gt;
  // Paint_Clear(WHITE);&lt;br /&gt;
  EPD_FastMode1Init();&lt;br /&gt;
  // EPD_Display_Clear();&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_Clear_R26H();&lt;br /&gt;
&lt;br /&gt;
  // Display the update time (it seems to be mislabeled as city_js here, might need to be corrected depending on the actual intention).&lt;br /&gt;
  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, city_js);&lt;br /&gt;
  EPD_ShowString(20, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //If you need to replace the display options,&lt;br /&gt;
  //open the following options: temp, wind, visit, hum&lt;br /&gt;
  //The following uses the hum option as an example&lt;br /&gt;
&lt;br /&gt;
  //Hum&lt;br /&gt;
  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, humidity);&lt;br /&gt;
  EPD_ShowString(105, 140, buffer,  12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //Temp&lt;br /&gt;
  //       memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  //       snprintf(buffer, sizeof(buffer), &amp;quot;%s C&amp;quot;, temperature);&lt;br /&gt;
  //       EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //Wind&lt;br /&gt;
  // memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  // snprintf(buffer, sizeof(buffer), &amp;quot;%s m/s&amp;quot;, wind_speed);&lt;br /&gt;
  // EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //visit&lt;br /&gt;
  //  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  //  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, sea_level);&lt;br /&gt;
  //  EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  // Update the e-paper display with the new content.&lt;br /&gt;
  EPD_Display(ImageBW);&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_DeepSleep();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200); // Initialize the serial communication.&lt;br /&gt;
&lt;br /&gt;
  // Connect to the WiFi network.&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  Serial.println(&amp;quot;Connecting&amp;quot;);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot;&amp;quot;);&lt;br /&gt;
  Serial.print(&amp;quot;Connected to WiFi network with IP Address: &amp;quot;);&lt;br /&gt;
  Serial.println(WiFi.localIP()); // Print the IP address of the device after successful connection.&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Timer set to 10 seconds (timerDelay variable), it will take 10 seconds before publishing the first reading.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Set pin 7 as an output pin to control the power of the e-paper display.&lt;br /&gt;
  pinMode(7, OUTPUT);&lt;br /&gt;
  digitalWrite(7, HIGH);&lt;br /&gt;
&lt;br /&gt;
  EPD_GPIOInit();&lt;br /&gt;
  Paint_NewImage(ImageBW, EPD_W, EPD_H, 0, WHITE);&lt;br /&gt;
  Paint_Clear(WHITE);&lt;br /&gt;
  EPD_FastMode1Init();&lt;br /&gt;
  EPD_Display_Clear();&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_Clear_R26H();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  js_analysis();&lt;br /&gt;
  UI_weather_forecast();&lt;br /&gt;
  delay(1000 * 60 * 60);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void js_analysis()&lt;br /&gt;
{&lt;br /&gt;
  // Check if the device is connected to the WiFi network.&lt;br /&gt;
  if (WiFi.status() == WL_CONNECTED) {&lt;br /&gt;
    // Construct the URL for the OpenWeatherMap API request.&lt;br /&gt;
    String serverPath = &amp;quot;http://api.openweathermap.org/data/2.5/weather?q=&amp;quot; + city + &amp;quot;,&amp;quot; + countryCode + &amp;quot;&amp;amp;APPID=&amp;quot; + openWeatherMapApiKey + &amp;quot;&amp;amp;units=metric&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    // Keep trying until a successful response (status code 200) is received.&lt;br /&gt;
    while (httpResponseCode != 200) {&lt;br /&gt;
      // Make an HTTP GET request to the API and store the response in jsonBuffer.&lt;br /&gt;
      jsonBuffer = httpGETRequest(serverPath.c_str());&lt;br /&gt;
      Serial.println(jsonBuffer);&lt;br /&gt;
      myObject = JSON.parse(jsonBuffer);&lt;br /&gt;
&lt;br /&gt;
      // Check if the JSON parsing was successful.&lt;br /&gt;
      if (JSON.typeof(myObject) == &amp;quot;undefined&amp;quot;) {&lt;br /&gt;
        Serial.println(&amp;quot;Parsing input failed!&amp;quot;);&lt;br /&gt;
        return;&lt;br /&gt;
      }&lt;br /&gt;
      delay(2000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Extract weather information from the parsed JSON data.&lt;br /&gt;
    weather = JSON.stringify(myObject[&amp;quot;weather&amp;quot;][0][&amp;quot;main&amp;quot;]);&lt;br /&gt;
    temperature = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;temp&amp;quot;]);&lt;br /&gt;
    humidity = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;humidity&amp;quot;]);&lt;br /&gt;
    sea_level = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;sea_level&amp;quot;]);&lt;br /&gt;
    wind_speed = JSON.stringify(myObject[&amp;quot;wind&amp;quot;][&amp;quot;speed&amp;quot;]);&lt;br /&gt;
    city_js = JSON.stringify(myObject[&amp;quot;name&amp;quot;]);&lt;br /&gt;
&lt;br /&gt;
    // Print the extracted weather information for debugging purposes.&lt;br /&gt;
    Serial.print(&amp;quot;String weather: &amp;quot;);&lt;br /&gt;
    Serial.println(weather);&lt;br /&gt;
    Serial.print(&amp;quot;String Temperature: &amp;quot;);&lt;br /&gt;
    Serial.println(temperature);&lt;br /&gt;
    Serial.print(&amp;quot;String humidity: &amp;quot;);&lt;br /&gt;
    Serial.println(humidity);&lt;br /&gt;
    Serial.print(&amp;quot;String sea_level: &amp;quot;);&lt;br /&gt;
    Serial.println(sea_level);&lt;br /&gt;
    Serial.print(&amp;quot;String wind_speed: &amp;quot;);&lt;br /&gt;
    Serial.println(wind_speed);&lt;br /&gt;
    Serial.print(&amp;quot;String city_js: &amp;quot;);&lt;br /&gt;
    Serial.println(city_js);&lt;br /&gt;
&lt;br /&gt;
    // Determine the weather icon based on the weather description.&lt;br /&gt;
    if (weather.indexOf(&amp;quot;clouds&amp;quot;) != -1 || weather.indexOf(&amp;quot;Clouds&amp;quot;) != -1 ) {&lt;br /&gt;
      weather_flag = 1;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;clear sky&amp;quot;) != -1 || weather.indexOf(&amp;quot;Clear sky&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 3;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;rain&amp;quot;) != -1 || weather.indexOf(&amp;quot;Rain&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 5;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;thunderstorm&amp;quot;) != -1 || weather.indexOf(&amp;quot;Thunderstorm&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 2;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;snow&amp;quot;) != -1 || weather.indexOf(&amp;quot;Snow&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 4;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;mist&amp;quot;) != -1 || weather.indexOf(&amp;quot;Mist&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 0;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
    // Print a message if the device is not connected to the WiFi network.&lt;br /&gt;
    Serial.println(&amp;quot;WiFi Disconnected&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Function to make an HTTP GET request and return the response.&lt;br /&gt;
String httpGETRequest(const char* serverName) {&lt;br /&gt;
  WiFiClient client;&lt;br /&gt;
  HTTPClient http;&lt;br /&gt;
&lt;br /&gt;
  // Initialize the HTTP client with the server name.&lt;br /&gt;
  http.begin(client, serverName);&lt;br /&gt;
&lt;br /&gt;
  // Send an HTTP GET request.&lt;br /&gt;
  httpResponseCode = http.GET();&lt;br /&gt;
&lt;br /&gt;
  // Initialize the response payload as an empty JSON object.&lt;br /&gt;
  String payload = &amp;quot;{}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  // Check if the response code is positive (indicating a successful request).&lt;br /&gt;
  if (httpResponseCode &amp;gt; 0) {&lt;br /&gt;
    Serial.print(&amp;quot;HTTP Response code: &amp;quot;);&lt;br /&gt;
    Serial.println(httpResponseCode);&lt;br /&gt;
    payload = http.getString();&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
    Serial.print(&amp;quot;Error code: &amp;quot;);&lt;br /&gt;
    Serial.println(httpResponseCode);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Close the HTTP connection.&lt;br /&gt;
  http.end();&lt;br /&gt;
&lt;br /&gt;
  return payload;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 Explications : Partie à modifier avec vos données, ssid, password, openWeatherMapApiKey, city, countryCode&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// WiFi network name // WiFi password&lt;br /&gt;
&lt;br /&gt;
const char* ssid = &amp;quot;yanfa_software&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;yanfa-123456&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// OpenWeatherMap API key. This key is used to access weather data from the OpenWeatherMap API.&lt;br /&gt;
String openWeatherMapApiKey = &amp;quot;3c03d1f4e2dd3e14474a9a3a2f2299ff&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// City and country code for which weather data will be fetched.&lt;br /&gt;
String city = &amp;quot;London&amp;quot;;&lt;br /&gt;
String countryCode = &amp;quot;2643743&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Code HelloWord ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
	* @file HelloWorld.ino&lt;br /&gt;
	* @author HalfSweet (Email:HalfSweet@HalfSweet.cn or QQ:2522182733)&lt;br /&gt;
	* @brief Ce fichier est un exemple de programme permettant d&amp;#039;afficher «Hello World» sur un écran à encre électronique. Il illustre uniquement la méthode la plus simple pour allumer l&amp;#039;écran. Veuillez consulter la documentation pour connaître l&amp;#039;utilisation des différentes fonctions.&lt;br /&gt;
	* @version 0.1&lt;br /&gt;
	* @date 2022-01-30&lt;br /&gt;
	*&lt;br /&gt;
	* @copyright Copyright (c) 2022&lt;br /&gt;
	*&lt;br /&gt;
*/ &lt;br /&gt;
#include &amp;lt;Arduino.h&amp;gt;&lt;br /&gt;
#include &amp;lt;EPaperDrive.h&amp;gt;&lt;br /&gt;
// Inclure le système de fichiers à utiliser, par exemple:&lt;br /&gt;
#include &amp;lt;LittleFS.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define BAUD_SPEED 74880 // Débit en bauds pour le débogage du port série, modifiable selon les besoins&lt;br /&gt;
&lt;br /&gt;
#define CS 15&lt;br /&gt;
#define RST 2&lt;br /&gt;
#define DC 0&lt;br /&gt;
#define BUSY 4&lt;br /&gt;
#define CLK 14&lt;br /&gt;
#define DIN 13&lt;br /&gt;
&lt;br /&gt;
EPaperDrive EPD(0, CS, RST, DC, BUSY, CLK, DIN); //Instanciation de la bibliothèque de pilotes, utilisant ici le protocole SPI logiciel&lt;br /&gt;
&lt;br /&gt;
const uint8_t city_icon[24] = {&lt;br /&gt;
	/* 0X01,0X01,0X0C,0X00,0X0C,0X00, */&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X1C,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X77,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X41,&lt;br /&gt;
	0X80,&lt;br /&gt;
	0X9C,&lt;br /&gt;
	0X60,&lt;br /&gt;
	0XA2,&lt;br /&gt;
	0X30,&lt;br /&gt;
	0XA2,&lt;br /&gt;
	0X30,&lt;br /&gt;
	0X9C,&lt;br /&gt;
	0XC0,&lt;br /&gt;
	0X41,&lt;br /&gt;
	0X80,&lt;br /&gt;
	0X77,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X1C,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
	void setup()&lt;br /&gt;
	{&lt;br /&gt;
	Serial.begin(BAUD_SPEED);&lt;br /&gt;
	LittleFS.begin(); 						// Veuillez initialiser manuellement le système de fichiers avant de passer le pointeur.&lt;br /&gt;
&lt;br /&gt;
	EPD.SetFS(&amp;amp;LittleFS); 					// Définit le système de fichiers pour le stockage des polices. La valeur passée est le pointeur d&amp;#039;opération pour ce système de fichiers. Vous pouvez la modifier.&lt;br /&gt;
	EPD.EPD_Set_Model(HINKE0266A15A0); 		// Définit le type d&amp;#039;écran. Consultez la documentation pour les modèles spécifiques.&lt;br /&gt;
	EPD.EPD_init_Full(); 					// Initialisation du rafraîchissement complet, en utilisant la forme d&amp;#039;onde de rafraîchissement complet.&lt;br /&gt;
	EPD.clearbuffer(); 						// Efface le tampon (écran blanc).&lt;br /&gt;
	EPD.fontscale = 2; 						// Facteur d&amp;#039;échelle des polices (1 et 2 pris en charge, également applicable aux images. N&amp;#039;oubliez pas de le remettre à 1 après utilisation).&lt;br /&gt;
	EPD.SetFont(FONT12); 					// Sélectionne la police. Consultez la documentation pour connaître les polices prises en charge.&lt;br /&gt;
	EPD.DrawUTF(0, 0, &amp;quot;Hello&amp;quot;); &amp;quot;World&amp;quot;); 	// Dessiner la chaîne&lt;br /&gt;
	EPD.DrawUTF(26, 0, &amp;quot;J&amp;#039;aime les écrans à encre électronique&amp;quot;); 	// Dessiner la chaîne&lt;br /&gt;
	EPD.fontscale = 1; 												// Rétablir le facteur d&amp;#039;échelle de la police à 1&lt;br /&gt;
	EPD.DrawXbm_P(60, 0, 12, 12, (uint8_t *)city_icon); 			// Dessiner l&amp;#039;image&lt;br /&gt;
&lt;br /&gt;
	Serial.printf(&amp;quot;Image tamponnée dessinée, prête pour un rafraîchissement complet\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_Dis_Full((uint8_t *)EPD.EPDbuffer, 1); // Transmettre l&amp;#039;image tamponnée à la puce de contrôle de l&amp;#039;écran pour un rafraîchissement complet&lt;br /&gt;
	EPD.deepsleep(); // Mettre l&amp;#039;écran en veille&lt;br /&gt;
	Serial.println(&amp;quot;Rafraîchissement complet terminé&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	delay(5000);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_init_Part(); // Initialiser la partie Actualisation&lt;br /&gt;
	EPD.clearbuffer();&lt;br /&gt;
	EPD.fontscale = 2;&lt;br /&gt;
	EPD.SetFont(FONT12); EPD.DrawUTF(0, 0, &amp;quot;Actualisation locale activée&amp;quot;);&lt;br /&gt;
	Serial.printf(&amp;quot;Actualisation locale en cours\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_Dis_Part(0, 23, 0, 199, (uint8_t *)EPD.EPDbuffer, 1); // Transfert de l&amp;#039;image du tampon vers la puce de contrôle d&amp;#039;écran pour l&amp;#039;actualisation locale sur le nouvel écran&lt;br /&gt;
	Serial.printf(&amp;quot;Actualisation locale terminée\n&amp;quot;);&lt;br /&gt;
	EPD.deepsleep();&lt;br /&gt;
&lt;br /&gt;
} void loop()&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
	delay(1); // Empêcher le chien de garde de s&amp;#039;interrompre&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>144.2.107.134</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1899</id>
		<title>CrowPanel-ESP32-E-Paper-HMI-1.54</title>
		<link rel="alternate" type="text/html" href="https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1899"/>
		<updated>2025-11-24T23:59:01Z</updated>

		<summary type="html">&lt;p&gt;144.2.107.134: /* Code Exemples */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== E-Paper-HMI-1.54 (Elecrow) ==&lt;br /&gt;
&lt;br /&gt;
=== Liens externes ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_HMI_1.54-inch_Display.html Wiki&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_1.54-inch_Arduino_Tutorial.html Arduino Setup&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/crowpanel-esp32-1-54-e-paper-hmi-display-with-152-152-resolution-black-white-color-driven-by-spi-interface.html Shop&lt;br /&gt;
&lt;br /&gt;
 BLE debugging assistant&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/1-54-inch-152-152-e-paper-display-black-white-e-ink-display-with-spi-communication.html&lt;br /&gt;
&lt;br /&gt;
=== Caractéristiques ===&lt;br /&gt;
&lt;br /&gt;
Driver Chip : &amp;lt;b&amp;gt;SSD1680&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Résolution 152 x 152&amp;lt;br&amp;gt;&lt;br /&gt;
Couleur noir et blanc&amp;lt;br&amp;gt;&lt;br /&gt;
Pilote ESP32-S3 comme contrôleur principal&amp;lt;br&amp;gt;&lt;br /&gt;
PSRAM : 8MB&amp;lt;br&amp;gt;&lt;br /&gt;
Flash :	8MB&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Images ===&lt;br /&gt;
[[File:E-Paper-HMI-1.54-1.png|300px]]&lt;br /&gt;
&lt;br /&gt;
[[File:E-Paper-HMI-1.54-2.png|300px]]&lt;br /&gt;
[[File:E-Paper-HMI-1.54-3.png|300px]]&lt;br /&gt;
&lt;br /&gt;
=== Ressources ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/download/product/CrowPanel/E-paper/Image2Lcd_v2.9.zip Image2Lcd_v2.9&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152 GitHub&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152/archive/refs/heads/master.zip GitHub ZIP&lt;br /&gt;
&lt;br /&gt;
=== Arduine Mise en route (Setup) ===&lt;br /&gt;
&lt;br /&gt;
Click &amp;quot;Tools&amp;quot;-&amp;gt;&amp;quot;Board&amp;quot;-&amp;gt;&amp;quot;esp32&amp;quot;-&amp;gt;&amp;quot;ESP32S3 Dev Module&amp;quot;, &lt;br /&gt;
&lt;br /&gt;
and the &amp;quot;Partition Scheme&amp;quot; select &lt;br /&gt;
&amp;quot;Huge APP (3MB No OTA/1MB SPIFFS)&amp;quot;, &lt;br /&gt;
&amp;quot;PSRAM&amp;quot; select &amp;quot;OPI PSRAM&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[File:Setup-Arduino-1.png|300px]]&lt;br /&gt;
&lt;br /&gt;
=== Librairies ===&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;Arduino.h&amp;gt;   // Inclure la bibliothèque principale Arduino&lt;br /&gt;
 #include &amp;quot;EPD_GUI.h&amp;quot;   // Inclure la bibliothèque pour l&amp;#039;écran à encre électronique&lt;br /&gt;
 #include &amp;quot;Pic.h&amp;quot;       // Inclure la bibliothèque de fonctions personnalisées&lt;br /&gt;
 #include &amp;quot;FS.h&amp;quot;        // Bibliothèque du système de fichiers pour les opérations sur les fichiers&lt;br /&gt;
 #include &amp;quot;SPIFFS.h&amp;quot;    // Bibliothèque du système de fichiers SPIFFS pour la lecture et l&amp;#039;écriture de fichiers&lt;br /&gt;
 #include &amp;lt;WiFi.h&amp;gt;      // Bibliothèque WiFi pour la création et la gestion des connexions WiFi&lt;br /&gt;
 #include &amp;lt;Ticker.h&amp;gt;    // Bibliothèque de chronométrage&lt;br /&gt;
 #include &amp;lt;WebServer.h&amp;gt; // Bibliothèque de serveur Web pour la création d&amp;#039;un serveur HTTP&lt;br /&gt;
&lt;br /&gt;
=== Code Exemples ===&lt;br /&gt;
&lt;br /&gt;
Arduino Code for demos&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_WIFI_refresh.ino &amp;lt;b&amp;gt;Update via WiFi&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_ble_refresh.ino  &amp;lt;b&amp;gt;Update via Bluetooth&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_wifi_http_openweather.ino&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arduino Code for examples&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_PWR.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_wifi.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_BLE.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_key.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_Global_refresh.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_partial_refresh.ino&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Code wifi_http_openweather ===&lt;br /&gt;
&lt;br /&gt;
https://openweathermap.org/ Veuillez vous enregistrer afin de vous procurer votre OpenWeatherMap API key&lt;br /&gt;
&lt;br /&gt;
http://bulk.openweathermap.org/sample/ on trouve ici : city.list.json.gz, le countryCode de votre ville (variable city)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;lt;HTTPClient.h&amp;gt;&lt;br /&gt;
#include &amp;lt;Arduino_JSON.h&amp;gt;&lt;br /&gt;
#include &amp;quot;EPD_GUI.h&amp;quot;&lt;br /&gt;
#include &amp;quot;Pic.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
// Define an array for black and white image data, which serves as the buffer for the e-paper display.&lt;br /&gt;
// The size of the buffer is determined according to the resolution of the e-paper display.&lt;br /&gt;
uint8_t ImageBW[2888];&lt;br /&gt;
&lt;br /&gt;
// WiFi network name // WiFi password&lt;br /&gt;
const char* ssid = &amp;quot;yanfa_software&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;yanfa-123456&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// OpenWeatherMap API key. This key is used to access weather data from the OpenWeatherMap API.&lt;br /&gt;
String openWeatherMapApiKey = &amp;quot;3c03d1f4e2dd3e14474a9a3a2f2299ff&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// City and country code for which weather data will be fetched.&lt;br /&gt;
String city = &amp;quot;London&amp;quot;;&lt;br /&gt;
String countryCode = &amp;quot;2643743&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Variables related to timing and API calls.&lt;br /&gt;
// lastTime keeps track of the last time the API was called.&lt;br /&gt;
unsigned long lastTime = 0;&lt;br /&gt;
// timerDelay determines the time interval between API calls. For testing, it&amp;#039;s set to 10 seconds (10000 milliseconds).&lt;br /&gt;
// In a final application, this should be set according to the API call limits per hour/minute.&lt;br /&gt;
unsigned long timerDelay = 10000;&lt;br /&gt;
&lt;br /&gt;
// Variables related to JSON data.&lt;br /&gt;
// jsonBuffer stores the raw JSON data received from the API.&lt;br /&gt;
String jsonBuffer;&lt;br /&gt;
// httpResponseCode holds the response code from the HTTP request.&lt;br /&gt;
int httpResponseCode;&lt;br /&gt;
// myObject is a JSON variable that will hold the parsed JSON data.&lt;br /&gt;
JSONVar myObject;&lt;br /&gt;
&lt;br /&gt;
// Variables related to weather information.&lt;br /&gt;
// weather stores the main weather description.&lt;br /&gt;
String weather;&lt;br /&gt;
// temperature stores the temperature value.&lt;br /&gt;
String temperature;&lt;br /&gt;
// humidity stores the humidity value.&lt;br /&gt;
String humidity;&lt;br /&gt;
// sea_level stores the sea level value.&lt;br /&gt;
String sea_level;&lt;br /&gt;
// wind_speed stores the wind speed value.&lt;br /&gt;
String wind_speed;&lt;br /&gt;
// city_js stores the name of the city.&lt;br /&gt;
String city_js;&lt;br /&gt;
// weather_flag is a flag that determines which weather icon to display based on the weather description.&lt;br /&gt;
int weather_flag = 0;&lt;br /&gt;
&lt;br /&gt;
// Function to display weather forecast on the e-paper display.&lt;br /&gt;
void UI_weather_forecast()&lt;br /&gt;
{&lt;br /&gt;
  char buffer[40];&lt;br /&gt;
&lt;br /&gt;
  EPD_HW_RESET();&lt;br /&gt;
&lt;br /&gt;
  // Display a background picture on the e-paper.&lt;br /&gt;
  EPD_ShowPicture(0, 0, 152, 152, pic, BLACK);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  //If you need to replace the display options,&lt;br /&gt;
  //open the following options: temp, wind, visit, hum&lt;br /&gt;
  //The following uses the hum option as an example&lt;br /&gt;
&lt;br /&gt;
  //Visit&lt;br /&gt;
  //EPD_ShowPicture(76, 92, 56, 72, gImage_visit, BLACK);&lt;br /&gt;
  //Wind&lt;br /&gt;
  //EPD_ShowPicture(76, 92, 56, 72, gImage_wind, BLACK);&lt;br /&gt;
  //Temp&lt;br /&gt;
  //  EPD_ShowPicture(92, 0, 56, 72, gImage_temp, BLACK);&lt;br /&gt;
  //Hum&lt;br /&gt;
&lt;br /&gt;
  EPD_Display(ImageBW);&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_DeepSleep();&lt;br /&gt;
&lt;br /&gt;
  EPD_GPIOInit();&lt;br /&gt;
  Paint_NewImage(ImageBW, EPD_W, EPD_H, 270, WHITE);&lt;br /&gt;
  // Paint_Clear(WHITE);&lt;br /&gt;
  EPD_FastMode1Init();&lt;br /&gt;
  // EPD_Display_Clear();&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_Clear_R26H();&lt;br /&gt;
&lt;br /&gt;
  // Display the update time (it seems to be mislabeled as city_js here, might need to be corrected depending on the actual intention).&lt;br /&gt;
  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, city_js);&lt;br /&gt;
  EPD_ShowString(20, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //If you need to replace the display options,&lt;br /&gt;
  //open the following options: temp, wind, visit, hum&lt;br /&gt;
  //The following uses the hum option as an example&lt;br /&gt;
&lt;br /&gt;
  //Hum&lt;br /&gt;
  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, humidity);&lt;br /&gt;
  EPD_ShowString(105, 140, buffer,  12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //Temp&lt;br /&gt;
  //       memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  //       snprintf(buffer, sizeof(buffer), &amp;quot;%s C&amp;quot;, temperature);&lt;br /&gt;
  //       EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //Wind&lt;br /&gt;
  // memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  // snprintf(buffer, sizeof(buffer), &amp;quot;%s m/s&amp;quot;, wind_speed);&lt;br /&gt;
  // EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //visit&lt;br /&gt;
  //  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  //  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, sea_level);&lt;br /&gt;
  //  EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  // Update the e-paper display with the new content.&lt;br /&gt;
  EPD_Display(ImageBW);&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_DeepSleep();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200); // Initialize the serial communication.&lt;br /&gt;
&lt;br /&gt;
  // Connect to the WiFi network.&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  Serial.println(&amp;quot;Connecting&amp;quot;);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot;&amp;quot;);&lt;br /&gt;
  Serial.print(&amp;quot;Connected to WiFi network with IP Address: &amp;quot;);&lt;br /&gt;
  Serial.println(WiFi.localIP()); // Print the IP address of the device after successful connection.&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Timer set to 10 seconds (timerDelay variable), it will take 10 seconds before publishing the first reading.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Set pin 7 as an output pin to control the power of the e-paper display.&lt;br /&gt;
  pinMode(7, OUTPUT);&lt;br /&gt;
  digitalWrite(7, HIGH);&lt;br /&gt;
&lt;br /&gt;
  EPD_GPIOInit();&lt;br /&gt;
  Paint_NewImage(ImageBW, EPD_W, EPD_H, 0, WHITE);&lt;br /&gt;
  Paint_Clear(WHITE);&lt;br /&gt;
  EPD_FastMode1Init();&lt;br /&gt;
  EPD_Display_Clear();&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_Clear_R26H();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  js_analysis();&lt;br /&gt;
  UI_weather_forecast();&lt;br /&gt;
  delay(1000 * 60 * 60);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void js_analysis()&lt;br /&gt;
{&lt;br /&gt;
  // Check if the device is connected to the WiFi network.&lt;br /&gt;
  if (WiFi.status() == WL_CONNECTED) {&lt;br /&gt;
    // Construct the URL for the OpenWeatherMap API request.&lt;br /&gt;
    String serverPath = &amp;quot;http://api.openweathermap.org/data/2.5/weather?q=&amp;quot; + city + &amp;quot;,&amp;quot; + countryCode + &amp;quot;&amp;amp;APPID=&amp;quot; + openWeatherMapApiKey + &amp;quot;&amp;amp;units=metric&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    // Keep trying until a successful response (status code 200) is received.&lt;br /&gt;
    while (httpResponseCode != 200) {&lt;br /&gt;
      // Make an HTTP GET request to the API and store the response in jsonBuffer.&lt;br /&gt;
      jsonBuffer = httpGETRequest(serverPath.c_str());&lt;br /&gt;
      Serial.println(jsonBuffer);&lt;br /&gt;
      myObject = JSON.parse(jsonBuffer);&lt;br /&gt;
&lt;br /&gt;
      // Check if the JSON parsing was successful.&lt;br /&gt;
      if (JSON.typeof(myObject) == &amp;quot;undefined&amp;quot;) {&lt;br /&gt;
        Serial.println(&amp;quot;Parsing input failed!&amp;quot;);&lt;br /&gt;
        return;&lt;br /&gt;
      }&lt;br /&gt;
      delay(2000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Extract weather information from the parsed JSON data.&lt;br /&gt;
    weather = JSON.stringify(myObject[&amp;quot;weather&amp;quot;][0][&amp;quot;main&amp;quot;]);&lt;br /&gt;
    temperature = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;temp&amp;quot;]);&lt;br /&gt;
    humidity = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;humidity&amp;quot;]);&lt;br /&gt;
    sea_level = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;sea_level&amp;quot;]);&lt;br /&gt;
    wind_speed = JSON.stringify(myObject[&amp;quot;wind&amp;quot;][&amp;quot;speed&amp;quot;]);&lt;br /&gt;
    city_js = JSON.stringify(myObject[&amp;quot;name&amp;quot;]);&lt;br /&gt;
&lt;br /&gt;
    // Print the extracted weather information for debugging purposes.&lt;br /&gt;
    Serial.print(&amp;quot;String weather: &amp;quot;);&lt;br /&gt;
    Serial.println(weather);&lt;br /&gt;
    Serial.print(&amp;quot;String Temperature: &amp;quot;);&lt;br /&gt;
    Serial.println(temperature);&lt;br /&gt;
    Serial.print(&amp;quot;String humidity: &amp;quot;);&lt;br /&gt;
    Serial.println(humidity);&lt;br /&gt;
    Serial.print(&amp;quot;String sea_level: &amp;quot;);&lt;br /&gt;
    Serial.println(sea_level);&lt;br /&gt;
    Serial.print(&amp;quot;String wind_speed: &amp;quot;);&lt;br /&gt;
    Serial.println(wind_speed);&lt;br /&gt;
    Serial.print(&amp;quot;String city_js: &amp;quot;);&lt;br /&gt;
    Serial.println(city_js);&lt;br /&gt;
&lt;br /&gt;
    // Determine the weather icon based on the weather description.&lt;br /&gt;
    if (weather.indexOf(&amp;quot;clouds&amp;quot;) != -1 || weather.indexOf(&amp;quot;Clouds&amp;quot;) != -1 ) {&lt;br /&gt;
      weather_flag = 1;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;clear sky&amp;quot;) != -1 || weather.indexOf(&amp;quot;Clear sky&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 3;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;rain&amp;quot;) != -1 || weather.indexOf(&amp;quot;Rain&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 5;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;thunderstorm&amp;quot;) != -1 || weather.indexOf(&amp;quot;Thunderstorm&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 2;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;snow&amp;quot;) != -1 || weather.indexOf(&amp;quot;Snow&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 4;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;mist&amp;quot;) != -1 || weather.indexOf(&amp;quot;Mist&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 0;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
    // Print a message if the device is not connected to the WiFi network.&lt;br /&gt;
    Serial.println(&amp;quot;WiFi Disconnected&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Function to make an HTTP GET request and return the response.&lt;br /&gt;
String httpGETRequest(const char* serverName) {&lt;br /&gt;
  WiFiClient client;&lt;br /&gt;
  HTTPClient http;&lt;br /&gt;
&lt;br /&gt;
  // Initialize the HTTP client with the server name.&lt;br /&gt;
  http.begin(client, serverName);&lt;br /&gt;
&lt;br /&gt;
  // Send an HTTP GET request.&lt;br /&gt;
  httpResponseCode = http.GET();&lt;br /&gt;
&lt;br /&gt;
  // Initialize the response payload as an empty JSON object.&lt;br /&gt;
  String payload = &amp;quot;{}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  // Check if the response code is positive (indicating a successful request).&lt;br /&gt;
  if (httpResponseCode &amp;gt; 0) {&lt;br /&gt;
    Serial.print(&amp;quot;HTTP Response code: &amp;quot;);&lt;br /&gt;
    Serial.println(httpResponseCode);&lt;br /&gt;
    payload = http.getString();&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
    Serial.print(&amp;quot;Error code: &amp;quot;);&lt;br /&gt;
    Serial.println(httpResponseCode);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Close the HTTP connection.&lt;br /&gt;
  http.end();&lt;br /&gt;
&lt;br /&gt;
  return payload;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 Explications : Partie à modifier avec vos données, ssid, password, openWeatherMapApiKey, city, countryCode&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// WiFi network name // WiFi password&lt;br /&gt;
&lt;br /&gt;
const char* ssid = &amp;quot;yanfa_software&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;yanfa-123456&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// OpenWeatherMap API key. This key is used to access weather data from the OpenWeatherMap API.&lt;br /&gt;
String openWeatherMapApiKey = &amp;quot;3c03d1f4e2dd3e14474a9a3a2f2299ff&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// City and country code for which weather data will be fetched.&lt;br /&gt;
String city = &amp;quot;London&amp;quot;;&lt;br /&gt;
String countryCode = &amp;quot;2643743&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Code HelloWord ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
	* @file HelloWorld.ino&lt;br /&gt;
	* @author HalfSweet (Email:HalfSweet@HalfSweet.cn or QQ:2522182733)&lt;br /&gt;
	* @brief Ce fichier est un exemple de programme permettant d&amp;#039;afficher «Hello World» sur un écran à encre électronique. Il illustre uniquement la méthode la plus simple pour allumer l&amp;#039;écran. Veuillez consulter la documentation pour connaître l&amp;#039;utilisation des différentes fonctions.&lt;br /&gt;
	* @version 0.1&lt;br /&gt;
	* @date 2022-01-30&lt;br /&gt;
	*&lt;br /&gt;
	* @copyright Copyright (c) 2022&lt;br /&gt;
	*&lt;br /&gt;
*/ &lt;br /&gt;
#include &amp;lt;Arduino.h&amp;gt;&lt;br /&gt;
#include &amp;lt;EPaperDrive.h&amp;gt;&lt;br /&gt;
// Inclure le système de fichiers à utiliser, par exemple:&lt;br /&gt;
#include &amp;lt;LittleFS.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define BAUD_SPEED 74880 // Débit en bauds pour le débogage du port série, modifiable selon les besoins&lt;br /&gt;
&lt;br /&gt;
#define CS 15&lt;br /&gt;
#define RST 2&lt;br /&gt;
#define DC 0&lt;br /&gt;
#define BUSY 4&lt;br /&gt;
#define CLK 14&lt;br /&gt;
#define DIN 13&lt;br /&gt;
&lt;br /&gt;
EPaperDrive EPD(0, CS, RST, DC, BUSY, CLK, DIN); //Instanciation de la bibliothèque de pilotes, utilisant ici le protocole SPI logiciel&lt;br /&gt;
&lt;br /&gt;
const uint8_t city_icon[24] = {&lt;br /&gt;
	/* 0X01,0X01,0X0C,0X00,0X0C,0X00, */&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X1C,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X77,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X41,&lt;br /&gt;
	0X80,&lt;br /&gt;
	0X9C,&lt;br /&gt;
	0X60,&lt;br /&gt;
	0XA2,&lt;br /&gt;
	0X30,&lt;br /&gt;
	0XA2,&lt;br /&gt;
	0X30,&lt;br /&gt;
	0X9C,&lt;br /&gt;
	0XC0,&lt;br /&gt;
	0X41,&lt;br /&gt;
	0X80,&lt;br /&gt;
	0X77,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X1C,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
	void setup()&lt;br /&gt;
	{&lt;br /&gt;
	Serial.begin(BAUD_SPEED);&lt;br /&gt;
	LittleFS.begin(); 						// Veuillez initialiser manuellement le système de fichiers avant de passer le pointeur.&lt;br /&gt;
&lt;br /&gt;
	EPD.SetFS(&amp;amp;LittleFS); 					// Définit le système de fichiers pour le stockage des polices. La valeur passée est le pointeur d&amp;#039;opération pour ce système de fichiers. Vous pouvez la modifier.&lt;br /&gt;
	EPD.EPD_Set_Model(HINKE0266A15A0); 		// Définit le type d&amp;#039;écran. Consultez la documentation pour les modèles spécifiques.&lt;br /&gt;
	EPD.EPD_init_Full(); 					// Initialisation du rafraîchissement complet, en utilisant la forme d&amp;#039;onde de rafraîchissement complet.&lt;br /&gt;
	EPD.clearbuffer(); 						// Efface le tampon (écran blanc).&lt;br /&gt;
	EPD.fontscale = 2; 						// Facteur d&amp;#039;échelle des polices (1 et 2 pris en charge, également applicable aux images. N&amp;#039;oubliez pas de le remettre à 1 après utilisation).&lt;br /&gt;
	EPD.SetFont(FONT12); 					// Sélectionne la police. Consultez la documentation pour connaître les polices prises en charge.&lt;br /&gt;
	EPD.DrawUTF(0, 0, &amp;quot;Hello&amp;quot;); &amp;quot;World&amp;quot;); 	// Dessiner la chaîne&lt;br /&gt;
	EPD.DrawUTF(26, 0, &amp;quot;J&amp;#039;aime les écrans à encre électronique&amp;quot;); 	// Dessiner la chaîne&lt;br /&gt;
	EPD.fontscale = 1; 												// Rétablir le facteur d&amp;#039;échelle de la police à 1&lt;br /&gt;
	EPD.DrawXbm_P(60, 0, 12, 12, (uint8_t *)city_icon); 			// Dessiner l&amp;#039;image&lt;br /&gt;
&lt;br /&gt;
	Serial.printf(&amp;quot;Image tamponnée dessinée, prête pour un rafraîchissement complet\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_Dis_Full((uint8_t *)EPD.EPDbuffer, 1); // Transmettre l&amp;#039;image tamponnée à la puce de contrôle de l&amp;#039;écran pour un rafraîchissement complet&lt;br /&gt;
	EPD.deepsleep(); // Mettre l&amp;#039;écran en veille&lt;br /&gt;
	Serial.println(&amp;quot;Rafraîchissement complet terminé&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	delay(5000);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_init_Part(); // Initialiser la partie Actualisation&lt;br /&gt;
	EPD.clearbuffer();&lt;br /&gt;
	EPD.fontscale = 2;&lt;br /&gt;
	EPD.SetFont(FONT12); EPD.DrawUTF(0, 0, &amp;quot;Actualisation locale activée&amp;quot;);&lt;br /&gt;
	Serial.printf(&amp;quot;Actualisation locale en cours\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_Dis_Part(0, 23, 0, 199, (uint8_t *)EPD.EPDbuffer, 1); // Transfert de l&amp;#039;image du tampon vers la puce de contrôle d&amp;#039;écran pour l&amp;#039;actualisation locale sur le nouvel écran&lt;br /&gt;
	Serial.printf(&amp;quot;Actualisation locale terminée\n&amp;quot;);&lt;br /&gt;
	EPD.deepsleep();&lt;br /&gt;
&lt;br /&gt;
} void loop()&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
	delay(1); // Empêcher le chien de garde de s&amp;#039;interrompre&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>144.2.107.134</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1898</id>
		<title>CrowPanel-ESP32-E-Paper-HMI-1.54</title>
		<link rel="alternate" type="text/html" href="https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1898"/>
		<updated>2025-11-24T23:58:29Z</updated>

		<summary type="html">&lt;p&gt;144.2.107.134: /* Code Exemples */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== E-Paper-HMI-1.54 (Elecrow) ==&lt;br /&gt;
&lt;br /&gt;
=== Liens externes ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_HMI_1.54-inch_Display.html Wiki&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_1.54-inch_Arduino_Tutorial.html Arduino Setup&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/crowpanel-esp32-1-54-e-paper-hmi-display-with-152-152-resolution-black-white-color-driven-by-spi-interface.html Shop&lt;br /&gt;
&lt;br /&gt;
 BLE debugging assistant&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/1-54-inch-152-152-e-paper-display-black-white-e-ink-display-with-spi-communication.html&lt;br /&gt;
&lt;br /&gt;
=== Caractéristiques ===&lt;br /&gt;
&lt;br /&gt;
Driver Chip : &amp;lt;b&amp;gt;SSD1680&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Résolution 152 x 152&amp;lt;br&amp;gt;&lt;br /&gt;
Couleur noir et blanc&amp;lt;br&amp;gt;&lt;br /&gt;
Pilote ESP32-S3 comme contrôleur principal&amp;lt;br&amp;gt;&lt;br /&gt;
PSRAM : 8MB&amp;lt;br&amp;gt;&lt;br /&gt;
Flash :	8MB&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Images ===&lt;br /&gt;
[[File:E-Paper-HMI-1.54-1.png|300px]]&lt;br /&gt;
&lt;br /&gt;
[[File:E-Paper-HMI-1.54-2.png|300px]]&lt;br /&gt;
[[File:E-Paper-HMI-1.54-3.png|300px]]&lt;br /&gt;
&lt;br /&gt;
=== Ressources ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/download/product/CrowPanel/E-paper/Image2Lcd_v2.9.zip Image2Lcd_v2.9&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152 GitHub&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152/archive/refs/heads/master.zip GitHub ZIP&lt;br /&gt;
&lt;br /&gt;
=== Arduine Mise en route (Setup) ===&lt;br /&gt;
&lt;br /&gt;
Click &amp;quot;Tools&amp;quot;-&amp;gt;&amp;quot;Board&amp;quot;-&amp;gt;&amp;quot;esp32&amp;quot;-&amp;gt;&amp;quot;ESP32S3 Dev Module&amp;quot;, &lt;br /&gt;
&lt;br /&gt;
and the &amp;quot;Partition Scheme&amp;quot; select &lt;br /&gt;
&amp;quot;Huge APP (3MB No OTA/1MB SPIFFS)&amp;quot;, &lt;br /&gt;
&amp;quot;PSRAM&amp;quot; select &amp;quot;OPI PSRAM&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[File:Setup-Arduino-1.png|300px]]&lt;br /&gt;
&lt;br /&gt;
=== Librairies ===&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;Arduino.h&amp;gt;   // Inclure la bibliothèque principale Arduino&lt;br /&gt;
 #include &amp;quot;EPD_GUI.h&amp;quot;   // Inclure la bibliothèque pour l&amp;#039;écran à encre électronique&lt;br /&gt;
 #include &amp;quot;Pic.h&amp;quot;       // Inclure la bibliothèque de fonctions personnalisées&lt;br /&gt;
 #include &amp;quot;FS.h&amp;quot;        // Bibliothèque du système de fichiers pour les opérations sur les fichiers&lt;br /&gt;
 #include &amp;quot;SPIFFS.h&amp;quot;    // Bibliothèque du système de fichiers SPIFFS pour la lecture et l&amp;#039;écriture de fichiers&lt;br /&gt;
 #include &amp;lt;WiFi.h&amp;gt;      // Bibliothèque WiFi pour la création et la gestion des connexions WiFi&lt;br /&gt;
 #include &amp;lt;Ticker.h&amp;gt;    // Bibliothèque de chronométrage&lt;br /&gt;
 #include &amp;lt;WebServer.h&amp;gt; // Bibliothèque de serveur Web pour la création d&amp;#039;un serveur HTTP&lt;br /&gt;
&lt;br /&gt;
=== Code Exemples ===&lt;br /&gt;
&lt;br /&gt;
Arduino Code for demos&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_WIFI_refresh.ino &amp;lt;b&amp;gt;Update via WiFi&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_ble_refresh.ino  &amp;lt;b&amp;gt;Update via Bluetooth&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_wifi_http_openweather.ino&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Code wifi_http_openweather ===&lt;br /&gt;
&lt;br /&gt;
https://openweathermap.org/ Veuillez vous enregistrer afin de vous procurer votre OpenWeatherMap API key&lt;br /&gt;
&lt;br /&gt;
http://bulk.openweathermap.org/sample/ on trouve ici : city.list.json.gz, le countryCode de votre ville (variable city)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;lt;HTTPClient.h&amp;gt;&lt;br /&gt;
#include &amp;lt;Arduino_JSON.h&amp;gt;&lt;br /&gt;
#include &amp;quot;EPD_GUI.h&amp;quot;&lt;br /&gt;
#include &amp;quot;Pic.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
// Define an array for black and white image data, which serves as the buffer for the e-paper display.&lt;br /&gt;
// The size of the buffer is determined according to the resolution of the e-paper display.&lt;br /&gt;
uint8_t ImageBW[2888];&lt;br /&gt;
&lt;br /&gt;
// WiFi network name // WiFi password&lt;br /&gt;
const char* ssid = &amp;quot;yanfa_software&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;yanfa-123456&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// OpenWeatherMap API key. This key is used to access weather data from the OpenWeatherMap API.&lt;br /&gt;
String openWeatherMapApiKey = &amp;quot;3c03d1f4e2dd3e14474a9a3a2f2299ff&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// City and country code for which weather data will be fetched.&lt;br /&gt;
String city = &amp;quot;London&amp;quot;;&lt;br /&gt;
String countryCode = &amp;quot;2643743&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Variables related to timing and API calls.&lt;br /&gt;
// lastTime keeps track of the last time the API was called.&lt;br /&gt;
unsigned long lastTime = 0;&lt;br /&gt;
// timerDelay determines the time interval between API calls. For testing, it&amp;#039;s set to 10 seconds (10000 milliseconds).&lt;br /&gt;
// In a final application, this should be set according to the API call limits per hour/minute.&lt;br /&gt;
unsigned long timerDelay = 10000;&lt;br /&gt;
&lt;br /&gt;
// Variables related to JSON data.&lt;br /&gt;
// jsonBuffer stores the raw JSON data received from the API.&lt;br /&gt;
String jsonBuffer;&lt;br /&gt;
// httpResponseCode holds the response code from the HTTP request.&lt;br /&gt;
int httpResponseCode;&lt;br /&gt;
// myObject is a JSON variable that will hold the parsed JSON data.&lt;br /&gt;
JSONVar myObject;&lt;br /&gt;
&lt;br /&gt;
// Variables related to weather information.&lt;br /&gt;
// weather stores the main weather description.&lt;br /&gt;
String weather;&lt;br /&gt;
// temperature stores the temperature value.&lt;br /&gt;
String temperature;&lt;br /&gt;
// humidity stores the humidity value.&lt;br /&gt;
String humidity;&lt;br /&gt;
// sea_level stores the sea level value.&lt;br /&gt;
String sea_level;&lt;br /&gt;
// wind_speed stores the wind speed value.&lt;br /&gt;
String wind_speed;&lt;br /&gt;
// city_js stores the name of the city.&lt;br /&gt;
String city_js;&lt;br /&gt;
// weather_flag is a flag that determines which weather icon to display based on the weather description.&lt;br /&gt;
int weather_flag = 0;&lt;br /&gt;
&lt;br /&gt;
// Function to display weather forecast on the e-paper display.&lt;br /&gt;
void UI_weather_forecast()&lt;br /&gt;
{&lt;br /&gt;
  char buffer[40];&lt;br /&gt;
&lt;br /&gt;
  EPD_HW_RESET();&lt;br /&gt;
&lt;br /&gt;
  // Display a background picture on the e-paper.&lt;br /&gt;
  EPD_ShowPicture(0, 0, 152, 152, pic, BLACK);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  //If you need to replace the display options,&lt;br /&gt;
  //open the following options: temp, wind, visit, hum&lt;br /&gt;
  //The following uses the hum option as an example&lt;br /&gt;
&lt;br /&gt;
  //Visit&lt;br /&gt;
  //EPD_ShowPicture(76, 92, 56, 72, gImage_visit, BLACK);&lt;br /&gt;
  //Wind&lt;br /&gt;
  //EPD_ShowPicture(76, 92, 56, 72, gImage_wind, BLACK);&lt;br /&gt;
  //Temp&lt;br /&gt;
  //  EPD_ShowPicture(92, 0, 56, 72, gImage_temp, BLACK);&lt;br /&gt;
  //Hum&lt;br /&gt;
&lt;br /&gt;
  EPD_Display(ImageBW);&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_DeepSleep();&lt;br /&gt;
&lt;br /&gt;
  EPD_GPIOInit();&lt;br /&gt;
  Paint_NewImage(ImageBW, EPD_W, EPD_H, 270, WHITE);&lt;br /&gt;
  // Paint_Clear(WHITE);&lt;br /&gt;
  EPD_FastMode1Init();&lt;br /&gt;
  // EPD_Display_Clear();&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_Clear_R26H();&lt;br /&gt;
&lt;br /&gt;
  // Display the update time (it seems to be mislabeled as city_js here, might need to be corrected depending on the actual intention).&lt;br /&gt;
  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, city_js);&lt;br /&gt;
  EPD_ShowString(20, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //If you need to replace the display options,&lt;br /&gt;
  //open the following options: temp, wind, visit, hum&lt;br /&gt;
  //The following uses the hum option as an example&lt;br /&gt;
&lt;br /&gt;
  //Hum&lt;br /&gt;
  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, humidity);&lt;br /&gt;
  EPD_ShowString(105, 140, buffer,  12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //Temp&lt;br /&gt;
  //       memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  //       snprintf(buffer, sizeof(buffer), &amp;quot;%s C&amp;quot;, temperature);&lt;br /&gt;
  //       EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //Wind&lt;br /&gt;
  // memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  // snprintf(buffer, sizeof(buffer), &amp;quot;%s m/s&amp;quot;, wind_speed);&lt;br /&gt;
  // EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //visit&lt;br /&gt;
  //  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  //  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, sea_level);&lt;br /&gt;
  //  EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  // Update the e-paper display with the new content.&lt;br /&gt;
  EPD_Display(ImageBW);&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_DeepSleep();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200); // Initialize the serial communication.&lt;br /&gt;
&lt;br /&gt;
  // Connect to the WiFi network.&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  Serial.println(&amp;quot;Connecting&amp;quot;);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot;&amp;quot;);&lt;br /&gt;
  Serial.print(&amp;quot;Connected to WiFi network with IP Address: &amp;quot;);&lt;br /&gt;
  Serial.println(WiFi.localIP()); // Print the IP address of the device after successful connection.&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Timer set to 10 seconds (timerDelay variable), it will take 10 seconds before publishing the first reading.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Set pin 7 as an output pin to control the power of the e-paper display.&lt;br /&gt;
  pinMode(7, OUTPUT);&lt;br /&gt;
  digitalWrite(7, HIGH);&lt;br /&gt;
&lt;br /&gt;
  EPD_GPIOInit();&lt;br /&gt;
  Paint_NewImage(ImageBW, EPD_W, EPD_H, 0, WHITE);&lt;br /&gt;
  Paint_Clear(WHITE);&lt;br /&gt;
  EPD_FastMode1Init();&lt;br /&gt;
  EPD_Display_Clear();&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_Clear_R26H();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  js_analysis();&lt;br /&gt;
  UI_weather_forecast();&lt;br /&gt;
  delay(1000 * 60 * 60);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void js_analysis()&lt;br /&gt;
{&lt;br /&gt;
  // Check if the device is connected to the WiFi network.&lt;br /&gt;
  if (WiFi.status() == WL_CONNECTED) {&lt;br /&gt;
    // Construct the URL for the OpenWeatherMap API request.&lt;br /&gt;
    String serverPath = &amp;quot;http://api.openweathermap.org/data/2.5/weather?q=&amp;quot; + city + &amp;quot;,&amp;quot; + countryCode + &amp;quot;&amp;amp;APPID=&amp;quot; + openWeatherMapApiKey + &amp;quot;&amp;amp;units=metric&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    // Keep trying until a successful response (status code 200) is received.&lt;br /&gt;
    while (httpResponseCode != 200) {&lt;br /&gt;
      // Make an HTTP GET request to the API and store the response in jsonBuffer.&lt;br /&gt;
      jsonBuffer = httpGETRequest(serverPath.c_str());&lt;br /&gt;
      Serial.println(jsonBuffer);&lt;br /&gt;
      myObject = JSON.parse(jsonBuffer);&lt;br /&gt;
&lt;br /&gt;
      // Check if the JSON parsing was successful.&lt;br /&gt;
      if (JSON.typeof(myObject) == &amp;quot;undefined&amp;quot;) {&lt;br /&gt;
        Serial.println(&amp;quot;Parsing input failed!&amp;quot;);&lt;br /&gt;
        return;&lt;br /&gt;
      }&lt;br /&gt;
      delay(2000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Extract weather information from the parsed JSON data.&lt;br /&gt;
    weather = JSON.stringify(myObject[&amp;quot;weather&amp;quot;][0][&amp;quot;main&amp;quot;]);&lt;br /&gt;
    temperature = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;temp&amp;quot;]);&lt;br /&gt;
    humidity = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;humidity&amp;quot;]);&lt;br /&gt;
    sea_level = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;sea_level&amp;quot;]);&lt;br /&gt;
    wind_speed = JSON.stringify(myObject[&amp;quot;wind&amp;quot;][&amp;quot;speed&amp;quot;]);&lt;br /&gt;
    city_js = JSON.stringify(myObject[&amp;quot;name&amp;quot;]);&lt;br /&gt;
&lt;br /&gt;
    // Print the extracted weather information for debugging purposes.&lt;br /&gt;
    Serial.print(&amp;quot;String weather: &amp;quot;);&lt;br /&gt;
    Serial.println(weather);&lt;br /&gt;
    Serial.print(&amp;quot;String Temperature: &amp;quot;);&lt;br /&gt;
    Serial.println(temperature);&lt;br /&gt;
    Serial.print(&amp;quot;String humidity: &amp;quot;);&lt;br /&gt;
    Serial.println(humidity);&lt;br /&gt;
    Serial.print(&amp;quot;String sea_level: &amp;quot;);&lt;br /&gt;
    Serial.println(sea_level);&lt;br /&gt;
    Serial.print(&amp;quot;String wind_speed: &amp;quot;);&lt;br /&gt;
    Serial.println(wind_speed);&lt;br /&gt;
    Serial.print(&amp;quot;String city_js: &amp;quot;);&lt;br /&gt;
    Serial.println(city_js);&lt;br /&gt;
&lt;br /&gt;
    // Determine the weather icon based on the weather description.&lt;br /&gt;
    if (weather.indexOf(&amp;quot;clouds&amp;quot;) != -1 || weather.indexOf(&amp;quot;Clouds&amp;quot;) != -1 ) {&lt;br /&gt;
      weather_flag = 1;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;clear sky&amp;quot;) != -1 || weather.indexOf(&amp;quot;Clear sky&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 3;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;rain&amp;quot;) != -1 || weather.indexOf(&amp;quot;Rain&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 5;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;thunderstorm&amp;quot;) != -1 || weather.indexOf(&amp;quot;Thunderstorm&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 2;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;snow&amp;quot;) != -1 || weather.indexOf(&amp;quot;Snow&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 4;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;mist&amp;quot;) != -1 || weather.indexOf(&amp;quot;Mist&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 0;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
    // Print a message if the device is not connected to the WiFi network.&lt;br /&gt;
    Serial.println(&amp;quot;WiFi Disconnected&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Function to make an HTTP GET request and return the response.&lt;br /&gt;
String httpGETRequest(const char* serverName) {&lt;br /&gt;
  WiFiClient client;&lt;br /&gt;
  HTTPClient http;&lt;br /&gt;
&lt;br /&gt;
  // Initialize the HTTP client with the server name.&lt;br /&gt;
  http.begin(client, serverName);&lt;br /&gt;
&lt;br /&gt;
  // Send an HTTP GET request.&lt;br /&gt;
  httpResponseCode = http.GET();&lt;br /&gt;
&lt;br /&gt;
  // Initialize the response payload as an empty JSON object.&lt;br /&gt;
  String payload = &amp;quot;{}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  // Check if the response code is positive (indicating a successful request).&lt;br /&gt;
  if (httpResponseCode &amp;gt; 0) {&lt;br /&gt;
    Serial.print(&amp;quot;HTTP Response code: &amp;quot;);&lt;br /&gt;
    Serial.println(httpResponseCode);&lt;br /&gt;
    payload = http.getString();&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
    Serial.print(&amp;quot;Error code: &amp;quot;);&lt;br /&gt;
    Serial.println(httpResponseCode);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Close the HTTP connection.&lt;br /&gt;
  http.end();&lt;br /&gt;
&lt;br /&gt;
  return payload;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 Explications : Partie à modifier avec vos données, ssid, password, openWeatherMapApiKey, city, countryCode&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// WiFi network name // WiFi password&lt;br /&gt;
&lt;br /&gt;
const char* ssid = &amp;quot;yanfa_software&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;yanfa-123456&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// OpenWeatherMap API key. This key is used to access weather data from the OpenWeatherMap API.&lt;br /&gt;
String openWeatherMapApiKey = &amp;quot;3c03d1f4e2dd3e14474a9a3a2f2299ff&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// City and country code for which weather data will be fetched.&lt;br /&gt;
String city = &amp;quot;London&amp;quot;;&lt;br /&gt;
String countryCode = &amp;quot;2643743&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Code HelloWord ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
	* @file HelloWorld.ino&lt;br /&gt;
	* @author HalfSweet (Email:HalfSweet@HalfSweet.cn or QQ:2522182733)&lt;br /&gt;
	* @brief Ce fichier est un exemple de programme permettant d&amp;#039;afficher «Hello World» sur un écran à encre électronique. Il illustre uniquement la méthode la plus simple pour allumer l&amp;#039;écran. Veuillez consulter la documentation pour connaître l&amp;#039;utilisation des différentes fonctions.&lt;br /&gt;
	* @version 0.1&lt;br /&gt;
	* @date 2022-01-30&lt;br /&gt;
	*&lt;br /&gt;
	* @copyright Copyright (c) 2022&lt;br /&gt;
	*&lt;br /&gt;
*/ &lt;br /&gt;
#include &amp;lt;Arduino.h&amp;gt;&lt;br /&gt;
#include &amp;lt;EPaperDrive.h&amp;gt;&lt;br /&gt;
// Inclure le système de fichiers à utiliser, par exemple:&lt;br /&gt;
#include &amp;lt;LittleFS.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define BAUD_SPEED 74880 // Débit en bauds pour le débogage du port série, modifiable selon les besoins&lt;br /&gt;
&lt;br /&gt;
#define CS 15&lt;br /&gt;
#define RST 2&lt;br /&gt;
#define DC 0&lt;br /&gt;
#define BUSY 4&lt;br /&gt;
#define CLK 14&lt;br /&gt;
#define DIN 13&lt;br /&gt;
&lt;br /&gt;
EPaperDrive EPD(0, CS, RST, DC, BUSY, CLK, DIN); //Instanciation de la bibliothèque de pilotes, utilisant ici le protocole SPI logiciel&lt;br /&gt;
&lt;br /&gt;
const uint8_t city_icon[24] = {&lt;br /&gt;
	/* 0X01,0X01,0X0C,0X00,0X0C,0X00, */&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X1C,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X77,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X41,&lt;br /&gt;
	0X80,&lt;br /&gt;
	0X9C,&lt;br /&gt;
	0X60,&lt;br /&gt;
	0XA2,&lt;br /&gt;
	0X30,&lt;br /&gt;
	0XA2,&lt;br /&gt;
	0X30,&lt;br /&gt;
	0X9C,&lt;br /&gt;
	0XC0,&lt;br /&gt;
	0X41,&lt;br /&gt;
	0X80,&lt;br /&gt;
	0X77,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X1C,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
	void setup()&lt;br /&gt;
	{&lt;br /&gt;
	Serial.begin(BAUD_SPEED);&lt;br /&gt;
	LittleFS.begin(); 						// Veuillez initialiser manuellement le système de fichiers avant de passer le pointeur.&lt;br /&gt;
&lt;br /&gt;
	EPD.SetFS(&amp;amp;LittleFS); 					// Définit le système de fichiers pour le stockage des polices. La valeur passée est le pointeur d&amp;#039;opération pour ce système de fichiers. Vous pouvez la modifier.&lt;br /&gt;
	EPD.EPD_Set_Model(HINKE0266A15A0); 		// Définit le type d&amp;#039;écran. Consultez la documentation pour les modèles spécifiques.&lt;br /&gt;
	EPD.EPD_init_Full(); 					// Initialisation du rafraîchissement complet, en utilisant la forme d&amp;#039;onde de rafraîchissement complet.&lt;br /&gt;
	EPD.clearbuffer(); 						// Efface le tampon (écran blanc).&lt;br /&gt;
	EPD.fontscale = 2; 						// Facteur d&amp;#039;échelle des polices (1 et 2 pris en charge, également applicable aux images. N&amp;#039;oubliez pas de le remettre à 1 après utilisation).&lt;br /&gt;
	EPD.SetFont(FONT12); 					// Sélectionne la police. Consultez la documentation pour connaître les polices prises en charge.&lt;br /&gt;
	EPD.DrawUTF(0, 0, &amp;quot;Hello&amp;quot;); &amp;quot;World&amp;quot;); 	// Dessiner la chaîne&lt;br /&gt;
	EPD.DrawUTF(26, 0, &amp;quot;J&amp;#039;aime les écrans à encre électronique&amp;quot;); 	// Dessiner la chaîne&lt;br /&gt;
	EPD.fontscale = 1; 												// Rétablir le facteur d&amp;#039;échelle de la police à 1&lt;br /&gt;
	EPD.DrawXbm_P(60, 0, 12, 12, (uint8_t *)city_icon); 			// Dessiner l&amp;#039;image&lt;br /&gt;
&lt;br /&gt;
	Serial.printf(&amp;quot;Image tamponnée dessinée, prête pour un rafraîchissement complet\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_Dis_Full((uint8_t *)EPD.EPDbuffer, 1); // Transmettre l&amp;#039;image tamponnée à la puce de contrôle de l&amp;#039;écran pour un rafraîchissement complet&lt;br /&gt;
	EPD.deepsleep(); // Mettre l&amp;#039;écran en veille&lt;br /&gt;
	Serial.println(&amp;quot;Rafraîchissement complet terminé&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	delay(5000);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_init_Part(); // Initialiser la partie Actualisation&lt;br /&gt;
	EPD.clearbuffer();&lt;br /&gt;
	EPD.fontscale = 2;&lt;br /&gt;
	EPD.SetFont(FONT12); EPD.DrawUTF(0, 0, &amp;quot;Actualisation locale activée&amp;quot;);&lt;br /&gt;
	Serial.printf(&amp;quot;Actualisation locale en cours\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_Dis_Part(0, 23, 0, 199, (uint8_t *)EPD.EPDbuffer, 1); // Transfert de l&amp;#039;image du tampon vers la puce de contrôle d&amp;#039;écran pour l&amp;#039;actualisation locale sur le nouvel écran&lt;br /&gt;
	Serial.printf(&amp;quot;Actualisation locale terminée\n&amp;quot;);&lt;br /&gt;
	EPD.deepsleep();&lt;br /&gt;
&lt;br /&gt;
} void loop()&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
	delay(1); // Empêcher le chien de garde de s&amp;#039;interrompre&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>144.2.107.134</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1897</id>
		<title>CrowPanel-ESP32-E-Paper-HMI-1.54</title>
		<link rel="alternate" type="text/html" href="https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1897"/>
		<updated>2025-11-24T23:57:18Z</updated>

		<summary type="html">&lt;p&gt;144.2.107.134: /* Code Exemples */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== E-Paper-HMI-1.54 (Elecrow) ==&lt;br /&gt;
&lt;br /&gt;
=== Liens externes ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_HMI_1.54-inch_Display.html Wiki&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_1.54-inch_Arduino_Tutorial.html Arduino Setup&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/crowpanel-esp32-1-54-e-paper-hmi-display-with-152-152-resolution-black-white-color-driven-by-spi-interface.html Shop&lt;br /&gt;
&lt;br /&gt;
 BLE debugging assistant&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/1-54-inch-152-152-e-paper-display-black-white-e-ink-display-with-spi-communication.html&lt;br /&gt;
&lt;br /&gt;
=== Caractéristiques ===&lt;br /&gt;
&lt;br /&gt;
Driver Chip : &amp;lt;b&amp;gt;SSD1680&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Résolution 152 x 152&amp;lt;br&amp;gt;&lt;br /&gt;
Couleur noir et blanc&amp;lt;br&amp;gt;&lt;br /&gt;
Pilote ESP32-S3 comme contrôleur principal&amp;lt;br&amp;gt;&lt;br /&gt;
PSRAM : 8MB&amp;lt;br&amp;gt;&lt;br /&gt;
Flash :	8MB&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Images ===&lt;br /&gt;
[[File:E-Paper-HMI-1.54-1.png|300px]]&lt;br /&gt;
&lt;br /&gt;
[[File:E-Paper-HMI-1.54-2.png|300px]]&lt;br /&gt;
[[File:E-Paper-HMI-1.54-3.png|300px]]&lt;br /&gt;
&lt;br /&gt;
=== Ressources ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/download/product/CrowPanel/E-paper/Image2Lcd_v2.9.zip Image2Lcd_v2.9&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152 GitHub&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152/archive/refs/heads/master.zip GitHub ZIP&lt;br /&gt;
&lt;br /&gt;
=== Arduine Mise en route (Setup) ===&lt;br /&gt;
&lt;br /&gt;
Click &amp;quot;Tools&amp;quot;-&amp;gt;&amp;quot;Board&amp;quot;-&amp;gt;&amp;quot;esp32&amp;quot;-&amp;gt;&amp;quot;ESP32S3 Dev Module&amp;quot;, &lt;br /&gt;
&lt;br /&gt;
and the &amp;quot;Partition Scheme&amp;quot; select &lt;br /&gt;
&amp;quot;Huge APP (3MB No OTA/1MB SPIFFS)&amp;quot;, &lt;br /&gt;
&amp;quot;PSRAM&amp;quot; select &amp;quot;OPI PSRAM&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[File:Setup-Arduino-1.png|300px]]&lt;br /&gt;
&lt;br /&gt;
=== Librairies ===&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;Arduino.h&amp;gt;   // Inclure la bibliothèque principale Arduino&lt;br /&gt;
 #include &amp;quot;EPD_GUI.h&amp;quot;   // Inclure la bibliothèque pour l&amp;#039;écran à encre électronique&lt;br /&gt;
 #include &amp;quot;Pic.h&amp;quot;       // Inclure la bibliothèque de fonctions personnalisées&lt;br /&gt;
 #include &amp;quot;FS.h&amp;quot;        // Bibliothèque du système de fichiers pour les opérations sur les fichiers&lt;br /&gt;
 #include &amp;quot;SPIFFS.h&amp;quot;    // Bibliothèque du système de fichiers SPIFFS pour la lecture et l&amp;#039;écriture de fichiers&lt;br /&gt;
 #include &amp;lt;WiFi.h&amp;gt;      // Bibliothèque WiFi pour la création et la gestion des connexions WiFi&lt;br /&gt;
 #include &amp;lt;Ticker.h&amp;gt;    // Bibliothèque de chronométrage&lt;br /&gt;
 #include &amp;lt;WebServer.h&amp;gt; // Bibliothèque de serveur Web pour la création d&amp;#039;un serveur HTTP&lt;br /&gt;
&lt;br /&gt;
=== Code Exemples ===&lt;br /&gt;
&lt;br /&gt;
1.54_WIFI_refresh.ino &amp;lt;b&amp;gt;Update via WiFi&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_ble_refresh.ino  &amp;lt;b&amp;gt;Update via Bluetooth&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_wifi_http_openweather.ino&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Code wifi_http_openweather ===&lt;br /&gt;
&lt;br /&gt;
https://openweathermap.org/ Veuillez vous enregistrer afin de vous procurer votre OpenWeatherMap API key&lt;br /&gt;
&lt;br /&gt;
http://bulk.openweathermap.org/sample/ on trouve ici : city.list.json.gz, le countryCode de votre ville (variable city)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;lt;HTTPClient.h&amp;gt;&lt;br /&gt;
#include &amp;lt;Arduino_JSON.h&amp;gt;&lt;br /&gt;
#include &amp;quot;EPD_GUI.h&amp;quot;&lt;br /&gt;
#include &amp;quot;Pic.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
// Define an array for black and white image data, which serves as the buffer for the e-paper display.&lt;br /&gt;
// The size of the buffer is determined according to the resolution of the e-paper display.&lt;br /&gt;
uint8_t ImageBW[2888];&lt;br /&gt;
&lt;br /&gt;
// WiFi network name // WiFi password&lt;br /&gt;
const char* ssid = &amp;quot;yanfa_software&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;yanfa-123456&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// OpenWeatherMap API key. This key is used to access weather data from the OpenWeatherMap API.&lt;br /&gt;
String openWeatherMapApiKey = &amp;quot;3c03d1f4e2dd3e14474a9a3a2f2299ff&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// City and country code for which weather data will be fetched.&lt;br /&gt;
String city = &amp;quot;London&amp;quot;;&lt;br /&gt;
String countryCode = &amp;quot;2643743&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Variables related to timing and API calls.&lt;br /&gt;
// lastTime keeps track of the last time the API was called.&lt;br /&gt;
unsigned long lastTime = 0;&lt;br /&gt;
// timerDelay determines the time interval between API calls. For testing, it&amp;#039;s set to 10 seconds (10000 milliseconds).&lt;br /&gt;
// In a final application, this should be set according to the API call limits per hour/minute.&lt;br /&gt;
unsigned long timerDelay = 10000;&lt;br /&gt;
&lt;br /&gt;
// Variables related to JSON data.&lt;br /&gt;
// jsonBuffer stores the raw JSON data received from the API.&lt;br /&gt;
String jsonBuffer;&lt;br /&gt;
// httpResponseCode holds the response code from the HTTP request.&lt;br /&gt;
int httpResponseCode;&lt;br /&gt;
// myObject is a JSON variable that will hold the parsed JSON data.&lt;br /&gt;
JSONVar myObject;&lt;br /&gt;
&lt;br /&gt;
// Variables related to weather information.&lt;br /&gt;
// weather stores the main weather description.&lt;br /&gt;
String weather;&lt;br /&gt;
// temperature stores the temperature value.&lt;br /&gt;
String temperature;&lt;br /&gt;
// humidity stores the humidity value.&lt;br /&gt;
String humidity;&lt;br /&gt;
// sea_level stores the sea level value.&lt;br /&gt;
String sea_level;&lt;br /&gt;
// wind_speed stores the wind speed value.&lt;br /&gt;
String wind_speed;&lt;br /&gt;
// city_js stores the name of the city.&lt;br /&gt;
String city_js;&lt;br /&gt;
// weather_flag is a flag that determines which weather icon to display based on the weather description.&lt;br /&gt;
int weather_flag = 0;&lt;br /&gt;
&lt;br /&gt;
// Function to display weather forecast on the e-paper display.&lt;br /&gt;
void UI_weather_forecast()&lt;br /&gt;
{&lt;br /&gt;
  char buffer[40];&lt;br /&gt;
&lt;br /&gt;
  EPD_HW_RESET();&lt;br /&gt;
&lt;br /&gt;
  // Display a background picture on the e-paper.&lt;br /&gt;
  EPD_ShowPicture(0, 0, 152, 152, pic, BLACK);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  //If you need to replace the display options,&lt;br /&gt;
  //open the following options: temp, wind, visit, hum&lt;br /&gt;
  //The following uses the hum option as an example&lt;br /&gt;
&lt;br /&gt;
  //Visit&lt;br /&gt;
  //EPD_ShowPicture(76, 92, 56, 72, gImage_visit, BLACK);&lt;br /&gt;
  //Wind&lt;br /&gt;
  //EPD_ShowPicture(76, 92, 56, 72, gImage_wind, BLACK);&lt;br /&gt;
  //Temp&lt;br /&gt;
  //  EPD_ShowPicture(92, 0, 56, 72, gImage_temp, BLACK);&lt;br /&gt;
  //Hum&lt;br /&gt;
&lt;br /&gt;
  EPD_Display(ImageBW);&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_DeepSleep();&lt;br /&gt;
&lt;br /&gt;
  EPD_GPIOInit();&lt;br /&gt;
  Paint_NewImage(ImageBW, EPD_W, EPD_H, 270, WHITE);&lt;br /&gt;
  // Paint_Clear(WHITE);&lt;br /&gt;
  EPD_FastMode1Init();&lt;br /&gt;
  // EPD_Display_Clear();&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_Clear_R26H();&lt;br /&gt;
&lt;br /&gt;
  // Display the update time (it seems to be mislabeled as city_js here, might need to be corrected depending on the actual intention).&lt;br /&gt;
  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, city_js);&lt;br /&gt;
  EPD_ShowString(20, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //If you need to replace the display options,&lt;br /&gt;
  //open the following options: temp, wind, visit, hum&lt;br /&gt;
  //The following uses the hum option as an example&lt;br /&gt;
&lt;br /&gt;
  //Hum&lt;br /&gt;
  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, humidity);&lt;br /&gt;
  EPD_ShowString(105, 140, buffer,  12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //Temp&lt;br /&gt;
  //       memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  //       snprintf(buffer, sizeof(buffer), &amp;quot;%s C&amp;quot;, temperature);&lt;br /&gt;
  //       EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //Wind&lt;br /&gt;
  // memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  // snprintf(buffer, sizeof(buffer), &amp;quot;%s m/s&amp;quot;, wind_speed);&lt;br /&gt;
  // EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //visit&lt;br /&gt;
  //  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  //  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, sea_level);&lt;br /&gt;
  //  EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  // Update the e-paper display with the new content.&lt;br /&gt;
  EPD_Display(ImageBW);&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_DeepSleep();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200); // Initialize the serial communication.&lt;br /&gt;
&lt;br /&gt;
  // Connect to the WiFi network.&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  Serial.println(&amp;quot;Connecting&amp;quot;);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot;&amp;quot;);&lt;br /&gt;
  Serial.print(&amp;quot;Connected to WiFi network with IP Address: &amp;quot;);&lt;br /&gt;
  Serial.println(WiFi.localIP()); // Print the IP address of the device after successful connection.&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Timer set to 10 seconds (timerDelay variable), it will take 10 seconds before publishing the first reading.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Set pin 7 as an output pin to control the power of the e-paper display.&lt;br /&gt;
  pinMode(7, OUTPUT);&lt;br /&gt;
  digitalWrite(7, HIGH);&lt;br /&gt;
&lt;br /&gt;
  EPD_GPIOInit();&lt;br /&gt;
  Paint_NewImage(ImageBW, EPD_W, EPD_H, 0, WHITE);&lt;br /&gt;
  Paint_Clear(WHITE);&lt;br /&gt;
  EPD_FastMode1Init();&lt;br /&gt;
  EPD_Display_Clear();&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_Clear_R26H();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  js_analysis();&lt;br /&gt;
  UI_weather_forecast();&lt;br /&gt;
  delay(1000 * 60 * 60);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void js_analysis()&lt;br /&gt;
{&lt;br /&gt;
  // Check if the device is connected to the WiFi network.&lt;br /&gt;
  if (WiFi.status() == WL_CONNECTED) {&lt;br /&gt;
    // Construct the URL for the OpenWeatherMap API request.&lt;br /&gt;
    String serverPath = &amp;quot;http://api.openweathermap.org/data/2.5/weather?q=&amp;quot; + city + &amp;quot;,&amp;quot; + countryCode + &amp;quot;&amp;amp;APPID=&amp;quot; + openWeatherMapApiKey + &amp;quot;&amp;amp;units=metric&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    // Keep trying until a successful response (status code 200) is received.&lt;br /&gt;
    while (httpResponseCode != 200) {&lt;br /&gt;
      // Make an HTTP GET request to the API and store the response in jsonBuffer.&lt;br /&gt;
      jsonBuffer = httpGETRequest(serverPath.c_str());&lt;br /&gt;
      Serial.println(jsonBuffer);&lt;br /&gt;
      myObject = JSON.parse(jsonBuffer);&lt;br /&gt;
&lt;br /&gt;
      // Check if the JSON parsing was successful.&lt;br /&gt;
      if (JSON.typeof(myObject) == &amp;quot;undefined&amp;quot;) {&lt;br /&gt;
        Serial.println(&amp;quot;Parsing input failed!&amp;quot;);&lt;br /&gt;
        return;&lt;br /&gt;
      }&lt;br /&gt;
      delay(2000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Extract weather information from the parsed JSON data.&lt;br /&gt;
    weather = JSON.stringify(myObject[&amp;quot;weather&amp;quot;][0][&amp;quot;main&amp;quot;]);&lt;br /&gt;
    temperature = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;temp&amp;quot;]);&lt;br /&gt;
    humidity = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;humidity&amp;quot;]);&lt;br /&gt;
    sea_level = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;sea_level&amp;quot;]);&lt;br /&gt;
    wind_speed = JSON.stringify(myObject[&amp;quot;wind&amp;quot;][&amp;quot;speed&amp;quot;]);&lt;br /&gt;
    city_js = JSON.stringify(myObject[&amp;quot;name&amp;quot;]);&lt;br /&gt;
&lt;br /&gt;
    // Print the extracted weather information for debugging purposes.&lt;br /&gt;
    Serial.print(&amp;quot;String weather: &amp;quot;);&lt;br /&gt;
    Serial.println(weather);&lt;br /&gt;
    Serial.print(&amp;quot;String Temperature: &amp;quot;);&lt;br /&gt;
    Serial.println(temperature);&lt;br /&gt;
    Serial.print(&amp;quot;String humidity: &amp;quot;);&lt;br /&gt;
    Serial.println(humidity);&lt;br /&gt;
    Serial.print(&amp;quot;String sea_level: &amp;quot;);&lt;br /&gt;
    Serial.println(sea_level);&lt;br /&gt;
    Serial.print(&amp;quot;String wind_speed: &amp;quot;);&lt;br /&gt;
    Serial.println(wind_speed);&lt;br /&gt;
    Serial.print(&amp;quot;String city_js: &amp;quot;);&lt;br /&gt;
    Serial.println(city_js);&lt;br /&gt;
&lt;br /&gt;
    // Determine the weather icon based on the weather description.&lt;br /&gt;
    if (weather.indexOf(&amp;quot;clouds&amp;quot;) != -1 || weather.indexOf(&amp;quot;Clouds&amp;quot;) != -1 ) {&lt;br /&gt;
      weather_flag = 1;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;clear sky&amp;quot;) != -1 || weather.indexOf(&amp;quot;Clear sky&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 3;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;rain&amp;quot;) != -1 || weather.indexOf(&amp;quot;Rain&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 5;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;thunderstorm&amp;quot;) != -1 || weather.indexOf(&amp;quot;Thunderstorm&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 2;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;snow&amp;quot;) != -1 || weather.indexOf(&amp;quot;Snow&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 4;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;mist&amp;quot;) != -1 || weather.indexOf(&amp;quot;Mist&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 0;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
    // Print a message if the device is not connected to the WiFi network.&lt;br /&gt;
    Serial.println(&amp;quot;WiFi Disconnected&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Function to make an HTTP GET request and return the response.&lt;br /&gt;
String httpGETRequest(const char* serverName) {&lt;br /&gt;
  WiFiClient client;&lt;br /&gt;
  HTTPClient http;&lt;br /&gt;
&lt;br /&gt;
  // Initialize the HTTP client with the server name.&lt;br /&gt;
  http.begin(client, serverName);&lt;br /&gt;
&lt;br /&gt;
  // Send an HTTP GET request.&lt;br /&gt;
  httpResponseCode = http.GET();&lt;br /&gt;
&lt;br /&gt;
  // Initialize the response payload as an empty JSON object.&lt;br /&gt;
  String payload = &amp;quot;{}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  // Check if the response code is positive (indicating a successful request).&lt;br /&gt;
  if (httpResponseCode &amp;gt; 0) {&lt;br /&gt;
    Serial.print(&amp;quot;HTTP Response code: &amp;quot;);&lt;br /&gt;
    Serial.println(httpResponseCode);&lt;br /&gt;
    payload = http.getString();&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
    Serial.print(&amp;quot;Error code: &amp;quot;);&lt;br /&gt;
    Serial.println(httpResponseCode);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Close the HTTP connection.&lt;br /&gt;
  http.end();&lt;br /&gt;
&lt;br /&gt;
  return payload;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 Explications : Partie à modifier avec vos données, ssid, password, openWeatherMapApiKey, city, countryCode&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// WiFi network name // WiFi password&lt;br /&gt;
&lt;br /&gt;
const char* ssid = &amp;quot;yanfa_software&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;yanfa-123456&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// OpenWeatherMap API key. This key is used to access weather data from the OpenWeatherMap API.&lt;br /&gt;
String openWeatherMapApiKey = &amp;quot;3c03d1f4e2dd3e14474a9a3a2f2299ff&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// City and country code for which weather data will be fetched.&lt;br /&gt;
String city = &amp;quot;London&amp;quot;;&lt;br /&gt;
String countryCode = &amp;quot;2643743&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Code HelloWord ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
	* @file HelloWorld.ino&lt;br /&gt;
	* @author HalfSweet (Email:HalfSweet@HalfSweet.cn or QQ:2522182733)&lt;br /&gt;
	* @brief Ce fichier est un exemple de programme permettant d&amp;#039;afficher «Hello World» sur un écran à encre électronique. Il illustre uniquement la méthode la plus simple pour allumer l&amp;#039;écran. Veuillez consulter la documentation pour connaître l&amp;#039;utilisation des différentes fonctions.&lt;br /&gt;
	* @version 0.1&lt;br /&gt;
	* @date 2022-01-30&lt;br /&gt;
	*&lt;br /&gt;
	* @copyright Copyright (c) 2022&lt;br /&gt;
	*&lt;br /&gt;
*/ &lt;br /&gt;
#include &amp;lt;Arduino.h&amp;gt;&lt;br /&gt;
#include &amp;lt;EPaperDrive.h&amp;gt;&lt;br /&gt;
// Inclure le système de fichiers à utiliser, par exemple:&lt;br /&gt;
#include &amp;lt;LittleFS.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define BAUD_SPEED 74880 // Débit en bauds pour le débogage du port série, modifiable selon les besoins&lt;br /&gt;
&lt;br /&gt;
#define CS 15&lt;br /&gt;
#define RST 2&lt;br /&gt;
#define DC 0&lt;br /&gt;
#define BUSY 4&lt;br /&gt;
#define CLK 14&lt;br /&gt;
#define DIN 13&lt;br /&gt;
&lt;br /&gt;
EPaperDrive EPD(0, CS, RST, DC, BUSY, CLK, DIN); //Instanciation de la bibliothèque de pilotes, utilisant ici le protocole SPI logiciel&lt;br /&gt;
&lt;br /&gt;
const uint8_t city_icon[24] = {&lt;br /&gt;
	/* 0X01,0X01,0X0C,0X00,0X0C,0X00, */&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X1C,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X77,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X41,&lt;br /&gt;
	0X80,&lt;br /&gt;
	0X9C,&lt;br /&gt;
	0X60,&lt;br /&gt;
	0XA2,&lt;br /&gt;
	0X30,&lt;br /&gt;
	0XA2,&lt;br /&gt;
	0X30,&lt;br /&gt;
	0X9C,&lt;br /&gt;
	0XC0,&lt;br /&gt;
	0X41,&lt;br /&gt;
	0X80,&lt;br /&gt;
	0X77,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X1C,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
	void setup()&lt;br /&gt;
	{&lt;br /&gt;
	Serial.begin(BAUD_SPEED);&lt;br /&gt;
	LittleFS.begin(); 						// Veuillez initialiser manuellement le système de fichiers avant de passer le pointeur.&lt;br /&gt;
&lt;br /&gt;
	EPD.SetFS(&amp;amp;LittleFS); 					// Définit le système de fichiers pour le stockage des polices. La valeur passée est le pointeur d&amp;#039;opération pour ce système de fichiers. Vous pouvez la modifier.&lt;br /&gt;
	EPD.EPD_Set_Model(HINKE0266A15A0); 		// Définit le type d&amp;#039;écran. Consultez la documentation pour les modèles spécifiques.&lt;br /&gt;
	EPD.EPD_init_Full(); 					// Initialisation du rafraîchissement complet, en utilisant la forme d&amp;#039;onde de rafraîchissement complet.&lt;br /&gt;
	EPD.clearbuffer(); 						// Efface le tampon (écran blanc).&lt;br /&gt;
	EPD.fontscale = 2; 						// Facteur d&amp;#039;échelle des polices (1 et 2 pris en charge, également applicable aux images. N&amp;#039;oubliez pas de le remettre à 1 après utilisation).&lt;br /&gt;
	EPD.SetFont(FONT12); 					// Sélectionne la police. Consultez la documentation pour connaître les polices prises en charge.&lt;br /&gt;
	EPD.DrawUTF(0, 0, &amp;quot;Hello&amp;quot;); &amp;quot;World&amp;quot;); 	// Dessiner la chaîne&lt;br /&gt;
	EPD.DrawUTF(26, 0, &amp;quot;J&amp;#039;aime les écrans à encre électronique&amp;quot;); 	// Dessiner la chaîne&lt;br /&gt;
	EPD.fontscale = 1; 												// Rétablir le facteur d&amp;#039;échelle de la police à 1&lt;br /&gt;
	EPD.DrawXbm_P(60, 0, 12, 12, (uint8_t *)city_icon); 			// Dessiner l&amp;#039;image&lt;br /&gt;
&lt;br /&gt;
	Serial.printf(&amp;quot;Image tamponnée dessinée, prête pour un rafraîchissement complet\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_Dis_Full((uint8_t *)EPD.EPDbuffer, 1); // Transmettre l&amp;#039;image tamponnée à la puce de contrôle de l&amp;#039;écran pour un rafraîchissement complet&lt;br /&gt;
	EPD.deepsleep(); // Mettre l&amp;#039;écran en veille&lt;br /&gt;
	Serial.println(&amp;quot;Rafraîchissement complet terminé&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	delay(5000);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_init_Part(); // Initialiser la partie Actualisation&lt;br /&gt;
	EPD.clearbuffer();&lt;br /&gt;
	EPD.fontscale = 2;&lt;br /&gt;
	EPD.SetFont(FONT12); EPD.DrawUTF(0, 0, &amp;quot;Actualisation locale activée&amp;quot;);&lt;br /&gt;
	Serial.printf(&amp;quot;Actualisation locale en cours\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_Dis_Part(0, 23, 0, 199, (uint8_t *)EPD.EPDbuffer, 1); // Transfert de l&amp;#039;image du tampon vers la puce de contrôle d&amp;#039;écran pour l&amp;#039;actualisation locale sur le nouvel écran&lt;br /&gt;
	Serial.printf(&amp;quot;Actualisation locale terminée\n&amp;quot;);&lt;br /&gt;
	EPD.deepsleep();&lt;br /&gt;
&lt;br /&gt;
} void loop()&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
	delay(1); // Empêcher le chien de garde de s&amp;#039;interrompre&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>144.2.107.134</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1896</id>
		<title>CrowPanel-ESP32-E-Paper-HMI-1.54</title>
		<link rel="alternate" type="text/html" href="https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1896"/>
		<updated>2025-11-24T23:44:26Z</updated>

		<summary type="html">&lt;p&gt;144.2.107.134: /* Code wifi_http_openweather */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== E-Paper-HMI-1.54 (Elecrow) ==&lt;br /&gt;
&lt;br /&gt;
=== Liens externes ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_HMI_1.54-inch_Display.html Wiki&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_1.54-inch_Arduino_Tutorial.html Arduino Setup&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/crowpanel-esp32-1-54-e-paper-hmi-display-with-152-152-resolution-black-white-color-driven-by-spi-interface.html Shop&lt;br /&gt;
&lt;br /&gt;
 BLE debugging assistant&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/1-54-inch-152-152-e-paper-display-black-white-e-ink-display-with-spi-communication.html&lt;br /&gt;
&lt;br /&gt;
=== Caractéristiques ===&lt;br /&gt;
&lt;br /&gt;
Driver Chip : &amp;lt;b&amp;gt;SSD1680&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Résolution 152 x 152&amp;lt;br&amp;gt;&lt;br /&gt;
Couleur noir et blanc&amp;lt;br&amp;gt;&lt;br /&gt;
Pilote ESP32-S3 comme contrôleur principal&amp;lt;br&amp;gt;&lt;br /&gt;
PSRAM : 8MB&amp;lt;br&amp;gt;&lt;br /&gt;
Flash :	8MB&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Images ===&lt;br /&gt;
[[File:E-Paper-HMI-1.54-1.png|300px]]&lt;br /&gt;
&lt;br /&gt;
[[File:E-Paper-HMI-1.54-2.png|300px]]&lt;br /&gt;
[[File:E-Paper-HMI-1.54-3.png|300px]]&lt;br /&gt;
&lt;br /&gt;
=== Ressources ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/download/product/CrowPanel/E-paper/Image2Lcd_v2.9.zip Image2Lcd_v2.9&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152 GitHub&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152/archive/refs/heads/master.zip GitHub ZIP&lt;br /&gt;
&lt;br /&gt;
=== Arduine Mise en route (Setup) ===&lt;br /&gt;
&lt;br /&gt;
Click &amp;quot;Tools&amp;quot;-&amp;gt;&amp;quot;Board&amp;quot;-&amp;gt;&amp;quot;esp32&amp;quot;-&amp;gt;&amp;quot;ESP32S3 Dev Module&amp;quot;, &lt;br /&gt;
&lt;br /&gt;
and the &amp;quot;Partition Scheme&amp;quot; select &lt;br /&gt;
&amp;quot;Huge APP (3MB No OTA/1MB SPIFFS)&amp;quot;, &lt;br /&gt;
&amp;quot;PSRAM&amp;quot; select &amp;quot;OPI PSRAM&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[File:Setup-Arduino-1.png|300px]]&lt;br /&gt;
&lt;br /&gt;
=== Librairies ===&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;Arduino.h&amp;gt;   // Inclure la bibliothèque principale Arduino&lt;br /&gt;
 #include &amp;quot;EPD_GUI.h&amp;quot;   // Inclure la bibliothèque pour l&amp;#039;écran à encre électronique&lt;br /&gt;
 #include &amp;quot;Pic.h&amp;quot;       // Inclure la bibliothèque de fonctions personnalisées&lt;br /&gt;
 #include &amp;quot;FS.h&amp;quot;        // Bibliothèque du système de fichiers pour les opérations sur les fichiers&lt;br /&gt;
 #include &amp;quot;SPIFFS.h&amp;quot;    // Bibliothèque du système de fichiers SPIFFS pour la lecture et l&amp;#039;écriture de fichiers&lt;br /&gt;
 #include &amp;lt;WiFi.h&amp;gt;      // Bibliothèque WiFi pour la création et la gestion des connexions WiFi&lt;br /&gt;
 #include &amp;lt;Ticker.h&amp;gt;    // Bibliothèque de chronométrage&lt;br /&gt;
 #include &amp;lt;WebServer.h&amp;gt; // Bibliothèque de serveur Web pour la création d&amp;#039;un serveur HTTP&lt;br /&gt;
&lt;br /&gt;
=== Code Exemples ===&lt;br /&gt;
&lt;br /&gt;
1.54_WIFI_refresh.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_ble_refresh.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_wifi_http_openweather.ino&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Code wifi_http_openweather ===&lt;br /&gt;
&lt;br /&gt;
https://openweathermap.org/ Veuillez vous enregistrer afin de vous procurer votre OpenWeatherMap API key&lt;br /&gt;
&lt;br /&gt;
http://bulk.openweathermap.org/sample/ on trouve ici : city.list.json.gz, le countryCode de votre ville (variable city)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;lt;HTTPClient.h&amp;gt;&lt;br /&gt;
#include &amp;lt;Arduino_JSON.h&amp;gt;&lt;br /&gt;
#include &amp;quot;EPD_GUI.h&amp;quot;&lt;br /&gt;
#include &amp;quot;Pic.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
// Define an array for black and white image data, which serves as the buffer for the e-paper display.&lt;br /&gt;
// The size of the buffer is determined according to the resolution of the e-paper display.&lt;br /&gt;
uint8_t ImageBW[2888];&lt;br /&gt;
&lt;br /&gt;
// WiFi network name // WiFi password&lt;br /&gt;
const char* ssid = &amp;quot;yanfa_software&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;yanfa-123456&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// OpenWeatherMap API key. This key is used to access weather data from the OpenWeatherMap API.&lt;br /&gt;
String openWeatherMapApiKey = &amp;quot;3c03d1f4e2dd3e14474a9a3a2f2299ff&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// City and country code for which weather data will be fetched.&lt;br /&gt;
String city = &amp;quot;London&amp;quot;;&lt;br /&gt;
String countryCode = &amp;quot;2643743&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Variables related to timing and API calls.&lt;br /&gt;
// lastTime keeps track of the last time the API was called.&lt;br /&gt;
unsigned long lastTime = 0;&lt;br /&gt;
// timerDelay determines the time interval between API calls. For testing, it&amp;#039;s set to 10 seconds (10000 milliseconds).&lt;br /&gt;
// In a final application, this should be set according to the API call limits per hour/minute.&lt;br /&gt;
unsigned long timerDelay = 10000;&lt;br /&gt;
&lt;br /&gt;
// Variables related to JSON data.&lt;br /&gt;
// jsonBuffer stores the raw JSON data received from the API.&lt;br /&gt;
String jsonBuffer;&lt;br /&gt;
// httpResponseCode holds the response code from the HTTP request.&lt;br /&gt;
int httpResponseCode;&lt;br /&gt;
// myObject is a JSON variable that will hold the parsed JSON data.&lt;br /&gt;
JSONVar myObject;&lt;br /&gt;
&lt;br /&gt;
// Variables related to weather information.&lt;br /&gt;
// weather stores the main weather description.&lt;br /&gt;
String weather;&lt;br /&gt;
// temperature stores the temperature value.&lt;br /&gt;
String temperature;&lt;br /&gt;
// humidity stores the humidity value.&lt;br /&gt;
String humidity;&lt;br /&gt;
// sea_level stores the sea level value.&lt;br /&gt;
String sea_level;&lt;br /&gt;
// wind_speed stores the wind speed value.&lt;br /&gt;
String wind_speed;&lt;br /&gt;
// city_js stores the name of the city.&lt;br /&gt;
String city_js;&lt;br /&gt;
// weather_flag is a flag that determines which weather icon to display based on the weather description.&lt;br /&gt;
int weather_flag = 0;&lt;br /&gt;
&lt;br /&gt;
// Function to display weather forecast on the e-paper display.&lt;br /&gt;
void UI_weather_forecast()&lt;br /&gt;
{&lt;br /&gt;
  char buffer[40];&lt;br /&gt;
&lt;br /&gt;
  EPD_HW_RESET();&lt;br /&gt;
&lt;br /&gt;
  // Display a background picture on the e-paper.&lt;br /&gt;
  EPD_ShowPicture(0, 0, 152, 152, pic, BLACK);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  //If you need to replace the display options,&lt;br /&gt;
  //open the following options: temp, wind, visit, hum&lt;br /&gt;
  //The following uses the hum option as an example&lt;br /&gt;
&lt;br /&gt;
  //Visit&lt;br /&gt;
  //EPD_ShowPicture(76, 92, 56, 72, gImage_visit, BLACK);&lt;br /&gt;
  //Wind&lt;br /&gt;
  //EPD_ShowPicture(76, 92, 56, 72, gImage_wind, BLACK);&lt;br /&gt;
  //Temp&lt;br /&gt;
  //  EPD_ShowPicture(92, 0, 56, 72, gImage_temp, BLACK);&lt;br /&gt;
  //Hum&lt;br /&gt;
&lt;br /&gt;
  EPD_Display(ImageBW);&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_DeepSleep();&lt;br /&gt;
&lt;br /&gt;
  EPD_GPIOInit();&lt;br /&gt;
  Paint_NewImage(ImageBW, EPD_W, EPD_H, 270, WHITE);&lt;br /&gt;
  // Paint_Clear(WHITE);&lt;br /&gt;
  EPD_FastMode1Init();&lt;br /&gt;
  // EPD_Display_Clear();&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_Clear_R26H();&lt;br /&gt;
&lt;br /&gt;
  // Display the update time (it seems to be mislabeled as city_js here, might need to be corrected depending on the actual intention).&lt;br /&gt;
  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, city_js);&lt;br /&gt;
  EPD_ShowString(20, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //If you need to replace the display options,&lt;br /&gt;
  //open the following options: temp, wind, visit, hum&lt;br /&gt;
  //The following uses the hum option as an example&lt;br /&gt;
&lt;br /&gt;
  //Hum&lt;br /&gt;
  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, humidity);&lt;br /&gt;
  EPD_ShowString(105, 140, buffer,  12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //Temp&lt;br /&gt;
  //       memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  //       snprintf(buffer, sizeof(buffer), &amp;quot;%s C&amp;quot;, temperature);&lt;br /&gt;
  //       EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //Wind&lt;br /&gt;
  // memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  // snprintf(buffer, sizeof(buffer), &amp;quot;%s m/s&amp;quot;, wind_speed);&lt;br /&gt;
  // EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //visit&lt;br /&gt;
  //  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  //  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, sea_level);&lt;br /&gt;
  //  EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  // Update the e-paper display with the new content.&lt;br /&gt;
  EPD_Display(ImageBW);&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_DeepSleep();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200); // Initialize the serial communication.&lt;br /&gt;
&lt;br /&gt;
  // Connect to the WiFi network.&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  Serial.println(&amp;quot;Connecting&amp;quot;);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot;&amp;quot;);&lt;br /&gt;
  Serial.print(&amp;quot;Connected to WiFi network with IP Address: &amp;quot;);&lt;br /&gt;
  Serial.println(WiFi.localIP()); // Print the IP address of the device after successful connection.&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Timer set to 10 seconds (timerDelay variable), it will take 10 seconds before publishing the first reading.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Set pin 7 as an output pin to control the power of the e-paper display.&lt;br /&gt;
  pinMode(7, OUTPUT);&lt;br /&gt;
  digitalWrite(7, HIGH);&lt;br /&gt;
&lt;br /&gt;
  EPD_GPIOInit();&lt;br /&gt;
  Paint_NewImage(ImageBW, EPD_W, EPD_H, 0, WHITE);&lt;br /&gt;
  Paint_Clear(WHITE);&lt;br /&gt;
  EPD_FastMode1Init();&lt;br /&gt;
  EPD_Display_Clear();&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_Clear_R26H();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  js_analysis();&lt;br /&gt;
  UI_weather_forecast();&lt;br /&gt;
  delay(1000 * 60 * 60);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void js_analysis()&lt;br /&gt;
{&lt;br /&gt;
  // Check if the device is connected to the WiFi network.&lt;br /&gt;
  if (WiFi.status() == WL_CONNECTED) {&lt;br /&gt;
    // Construct the URL for the OpenWeatherMap API request.&lt;br /&gt;
    String serverPath = &amp;quot;http://api.openweathermap.org/data/2.5/weather?q=&amp;quot; + city + &amp;quot;,&amp;quot; + countryCode + &amp;quot;&amp;amp;APPID=&amp;quot; + openWeatherMapApiKey + &amp;quot;&amp;amp;units=metric&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    // Keep trying until a successful response (status code 200) is received.&lt;br /&gt;
    while (httpResponseCode != 200) {&lt;br /&gt;
      // Make an HTTP GET request to the API and store the response in jsonBuffer.&lt;br /&gt;
      jsonBuffer = httpGETRequest(serverPath.c_str());&lt;br /&gt;
      Serial.println(jsonBuffer);&lt;br /&gt;
      myObject = JSON.parse(jsonBuffer);&lt;br /&gt;
&lt;br /&gt;
      // Check if the JSON parsing was successful.&lt;br /&gt;
      if (JSON.typeof(myObject) == &amp;quot;undefined&amp;quot;) {&lt;br /&gt;
        Serial.println(&amp;quot;Parsing input failed!&amp;quot;);&lt;br /&gt;
        return;&lt;br /&gt;
      }&lt;br /&gt;
      delay(2000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Extract weather information from the parsed JSON data.&lt;br /&gt;
    weather = JSON.stringify(myObject[&amp;quot;weather&amp;quot;][0][&amp;quot;main&amp;quot;]);&lt;br /&gt;
    temperature = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;temp&amp;quot;]);&lt;br /&gt;
    humidity = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;humidity&amp;quot;]);&lt;br /&gt;
    sea_level = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;sea_level&amp;quot;]);&lt;br /&gt;
    wind_speed = JSON.stringify(myObject[&amp;quot;wind&amp;quot;][&amp;quot;speed&amp;quot;]);&lt;br /&gt;
    city_js = JSON.stringify(myObject[&amp;quot;name&amp;quot;]);&lt;br /&gt;
&lt;br /&gt;
    // Print the extracted weather information for debugging purposes.&lt;br /&gt;
    Serial.print(&amp;quot;String weather: &amp;quot;);&lt;br /&gt;
    Serial.println(weather);&lt;br /&gt;
    Serial.print(&amp;quot;String Temperature: &amp;quot;);&lt;br /&gt;
    Serial.println(temperature);&lt;br /&gt;
    Serial.print(&amp;quot;String humidity: &amp;quot;);&lt;br /&gt;
    Serial.println(humidity);&lt;br /&gt;
    Serial.print(&amp;quot;String sea_level: &amp;quot;);&lt;br /&gt;
    Serial.println(sea_level);&lt;br /&gt;
    Serial.print(&amp;quot;String wind_speed: &amp;quot;);&lt;br /&gt;
    Serial.println(wind_speed);&lt;br /&gt;
    Serial.print(&amp;quot;String city_js: &amp;quot;);&lt;br /&gt;
    Serial.println(city_js);&lt;br /&gt;
&lt;br /&gt;
    // Determine the weather icon based on the weather description.&lt;br /&gt;
    if (weather.indexOf(&amp;quot;clouds&amp;quot;) != -1 || weather.indexOf(&amp;quot;Clouds&amp;quot;) != -1 ) {&lt;br /&gt;
      weather_flag = 1;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;clear sky&amp;quot;) != -1 || weather.indexOf(&amp;quot;Clear sky&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 3;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;rain&amp;quot;) != -1 || weather.indexOf(&amp;quot;Rain&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 5;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;thunderstorm&amp;quot;) != -1 || weather.indexOf(&amp;quot;Thunderstorm&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 2;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;snow&amp;quot;) != -1 || weather.indexOf(&amp;quot;Snow&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 4;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;mist&amp;quot;) != -1 || weather.indexOf(&amp;quot;Mist&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 0;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
    // Print a message if the device is not connected to the WiFi network.&lt;br /&gt;
    Serial.println(&amp;quot;WiFi Disconnected&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Function to make an HTTP GET request and return the response.&lt;br /&gt;
String httpGETRequest(const char* serverName) {&lt;br /&gt;
  WiFiClient client;&lt;br /&gt;
  HTTPClient http;&lt;br /&gt;
&lt;br /&gt;
  // Initialize the HTTP client with the server name.&lt;br /&gt;
  http.begin(client, serverName);&lt;br /&gt;
&lt;br /&gt;
  // Send an HTTP GET request.&lt;br /&gt;
  httpResponseCode = http.GET();&lt;br /&gt;
&lt;br /&gt;
  // Initialize the response payload as an empty JSON object.&lt;br /&gt;
  String payload = &amp;quot;{}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  // Check if the response code is positive (indicating a successful request).&lt;br /&gt;
  if (httpResponseCode &amp;gt; 0) {&lt;br /&gt;
    Serial.print(&amp;quot;HTTP Response code: &amp;quot;);&lt;br /&gt;
    Serial.println(httpResponseCode);&lt;br /&gt;
    payload = http.getString();&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
    Serial.print(&amp;quot;Error code: &amp;quot;);&lt;br /&gt;
    Serial.println(httpResponseCode);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Close the HTTP connection.&lt;br /&gt;
  http.end();&lt;br /&gt;
&lt;br /&gt;
  return payload;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 Explications : Partie à modifier avec vos données, ssid, password, openWeatherMapApiKey, city, countryCode&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// WiFi network name // WiFi password&lt;br /&gt;
&lt;br /&gt;
const char* ssid = &amp;quot;yanfa_software&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;yanfa-123456&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// OpenWeatherMap API key. This key is used to access weather data from the OpenWeatherMap API.&lt;br /&gt;
String openWeatherMapApiKey = &amp;quot;3c03d1f4e2dd3e14474a9a3a2f2299ff&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// City and country code for which weather data will be fetched.&lt;br /&gt;
String city = &amp;quot;London&amp;quot;;&lt;br /&gt;
String countryCode = &amp;quot;2643743&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Code HelloWord ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
	* @file HelloWorld.ino&lt;br /&gt;
	* @author HalfSweet (Email:HalfSweet@HalfSweet.cn or QQ:2522182733)&lt;br /&gt;
	* @brief Ce fichier est un exemple de programme permettant d&amp;#039;afficher «Hello World» sur un écran à encre électronique. Il illustre uniquement la méthode la plus simple pour allumer l&amp;#039;écran. Veuillez consulter la documentation pour connaître l&amp;#039;utilisation des différentes fonctions.&lt;br /&gt;
	* @version 0.1&lt;br /&gt;
	* @date 2022-01-30&lt;br /&gt;
	*&lt;br /&gt;
	* @copyright Copyright (c) 2022&lt;br /&gt;
	*&lt;br /&gt;
*/ &lt;br /&gt;
#include &amp;lt;Arduino.h&amp;gt;&lt;br /&gt;
#include &amp;lt;EPaperDrive.h&amp;gt;&lt;br /&gt;
// Inclure le système de fichiers à utiliser, par exemple:&lt;br /&gt;
#include &amp;lt;LittleFS.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define BAUD_SPEED 74880 // Débit en bauds pour le débogage du port série, modifiable selon les besoins&lt;br /&gt;
&lt;br /&gt;
#define CS 15&lt;br /&gt;
#define RST 2&lt;br /&gt;
#define DC 0&lt;br /&gt;
#define BUSY 4&lt;br /&gt;
#define CLK 14&lt;br /&gt;
#define DIN 13&lt;br /&gt;
&lt;br /&gt;
EPaperDrive EPD(0, CS, RST, DC, BUSY, CLK, DIN); //Instanciation de la bibliothèque de pilotes, utilisant ici le protocole SPI logiciel&lt;br /&gt;
&lt;br /&gt;
const uint8_t city_icon[24] = {&lt;br /&gt;
	/* 0X01,0X01,0X0C,0X00,0X0C,0X00, */&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X1C,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X77,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X41,&lt;br /&gt;
	0X80,&lt;br /&gt;
	0X9C,&lt;br /&gt;
	0X60,&lt;br /&gt;
	0XA2,&lt;br /&gt;
	0X30,&lt;br /&gt;
	0XA2,&lt;br /&gt;
	0X30,&lt;br /&gt;
	0X9C,&lt;br /&gt;
	0XC0,&lt;br /&gt;
	0X41,&lt;br /&gt;
	0X80,&lt;br /&gt;
	0X77,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X1C,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
	0X00,&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
	void setup()&lt;br /&gt;
	{&lt;br /&gt;
	Serial.begin(BAUD_SPEED);&lt;br /&gt;
	LittleFS.begin(); 						// Veuillez initialiser manuellement le système de fichiers avant de passer le pointeur.&lt;br /&gt;
&lt;br /&gt;
	EPD.SetFS(&amp;amp;LittleFS); 					// Définit le système de fichiers pour le stockage des polices. La valeur passée est le pointeur d&amp;#039;opération pour ce système de fichiers. Vous pouvez la modifier.&lt;br /&gt;
	EPD.EPD_Set_Model(HINKE0266A15A0); 		// Définit le type d&amp;#039;écran. Consultez la documentation pour les modèles spécifiques.&lt;br /&gt;
	EPD.EPD_init_Full(); 					// Initialisation du rafraîchissement complet, en utilisant la forme d&amp;#039;onde de rafraîchissement complet.&lt;br /&gt;
	EPD.clearbuffer(); 						// Efface le tampon (écran blanc).&lt;br /&gt;
	EPD.fontscale = 2; 						// Facteur d&amp;#039;échelle des polices (1 et 2 pris en charge, également applicable aux images. N&amp;#039;oubliez pas de le remettre à 1 après utilisation).&lt;br /&gt;
	EPD.SetFont(FONT12); 					// Sélectionne la police. Consultez la documentation pour connaître les polices prises en charge.&lt;br /&gt;
	EPD.DrawUTF(0, 0, &amp;quot;Hello&amp;quot;); &amp;quot;World&amp;quot;); 	// Dessiner la chaîne&lt;br /&gt;
	EPD.DrawUTF(26, 0, &amp;quot;J&amp;#039;aime les écrans à encre électronique&amp;quot;); 	// Dessiner la chaîne&lt;br /&gt;
	EPD.fontscale = 1; 												// Rétablir le facteur d&amp;#039;échelle de la police à 1&lt;br /&gt;
	EPD.DrawXbm_P(60, 0, 12, 12, (uint8_t *)city_icon); 			// Dessiner l&amp;#039;image&lt;br /&gt;
&lt;br /&gt;
	Serial.printf(&amp;quot;Image tamponnée dessinée, prête pour un rafraîchissement complet\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_Dis_Full((uint8_t *)EPD.EPDbuffer, 1); // Transmettre l&amp;#039;image tamponnée à la puce de contrôle de l&amp;#039;écran pour un rafraîchissement complet&lt;br /&gt;
	EPD.deepsleep(); // Mettre l&amp;#039;écran en veille&lt;br /&gt;
	Serial.println(&amp;quot;Rafraîchissement complet terminé&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	delay(5000);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_init_Part(); // Initialiser la partie Actualisation&lt;br /&gt;
	EPD.clearbuffer();&lt;br /&gt;
	EPD.fontscale = 2;&lt;br /&gt;
	EPD.SetFont(FONT12); EPD.DrawUTF(0, 0, &amp;quot;Actualisation locale activée&amp;quot;);&lt;br /&gt;
	Serial.printf(&amp;quot;Actualisation locale en cours\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	EPD.EPD_Dis_Part(0, 23, 0, 199, (uint8_t *)EPD.EPDbuffer, 1); // Transfert de l&amp;#039;image du tampon vers la puce de contrôle d&amp;#039;écran pour l&amp;#039;actualisation locale sur le nouvel écran&lt;br /&gt;
	Serial.printf(&amp;quot;Actualisation locale terminée\n&amp;quot;);&lt;br /&gt;
	EPD.deepsleep();&lt;br /&gt;
&lt;br /&gt;
} void loop()&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
	delay(1); // Empêcher le chien de garde de s&amp;#039;interrompre&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>144.2.107.134</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1895</id>
		<title>CrowPanel-ESP32-E-Paper-HMI-1.54</title>
		<link rel="alternate" type="text/html" href="https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1895"/>
		<updated>2025-11-24T23:13:50Z</updated>

		<summary type="html">&lt;p&gt;144.2.107.134: /* Ressources */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== E-Paper-HMI-1.54 (Elecrow) ==&lt;br /&gt;
&lt;br /&gt;
=== Liens externes ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_HMI_1.54-inch_Display.html Wiki&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_1.54-inch_Arduino_Tutorial.html Arduino Setup&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/crowpanel-esp32-1-54-e-paper-hmi-display-with-152-152-resolution-black-white-color-driven-by-spi-interface.html Shop&lt;br /&gt;
&lt;br /&gt;
 BLE debugging assistant&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/1-54-inch-152-152-e-paper-display-black-white-e-ink-display-with-spi-communication.html&lt;br /&gt;
&lt;br /&gt;
=== Caractéristiques ===&lt;br /&gt;
&lt;br /&gt;
Driver Chip : &amp;lt;b&amp;gt;SSD1680&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Résolution 152 x 152&amp;lt;br&amp;gt;&lt;br /&gt;
Couleur noir et blanc&amp;lt;br&amp;gt;&lt;br /&gt;
Pilote ESP32-S3 comme contrôleur principal&amp;lt;br&amp;gt;&lt;br /&gt;
PSRAM : 8MB&amp;lt;br&amp;gt;&lt;br /&gt;
Flash :	8MB&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Images ===&lt;br /&gt;
[[File:E-Paper-HMI-1.54-1.png|300px]]&lt;br /&gt;
&lt;br /&gt;
[[File:E-Paper-HMI-1.54-2.png|300px]]&lt;br /&gt;
[[File:E-Paper-HMI-1.54-3.png|300px]]&lt;br /&gt;
&lt;br /&gt;
=== Ressources ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/download/product/CrowPanel/E-paper/Image2Lcd_v2.9.zip Image2Lcd_v2.9&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152 GitHub&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152/archive/refs/heads/master.zip GitHub ZIP&lt;br /&gt;
&lt;br /&gt;
=== Arduine Mise en route (Setup) ===&lt;br /&gt;
&lt;br /&gt;
Click &amp;quot;Tools&amp;quot;-&amp;gt;&amp;quot;Board&amp;quot;-&amp;gt;&amp;quot;esp32&amp;quot;-&amp;gt;&amp;quot;ESP32S3 Dev Module&amp;quot;, &lt;br /&gt;
&lt;br /&gt;
and the &amp;quot;Partition Scheme&amp;quot; select &lt;br /&gt;
&amp;quot;Huge APP (3MB No OTA/1MB SPIFFS)&amp;quot;, &lt;br /&gt;
&amp;quot;PSRAM&amp;quot; select &amp;quot;OPI PSRAM&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[File:Setup-Arduino-1.png|300px]]&lt;br /&gt;
&lt;br /&gt;
=== Librairies ===&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;Arduino.h&amp;gt;   // Inclure la bibliothèque principale Arduino&lt;br /&gt;
 #include &amp;quot;EPD_GUI.h&amp;quot;   // Inclure la bibliothèque pour l&amp;#039;écran à encre électronique&lt;br /&gt;
 #include &amp;quot;Pic.h&amp;quot;       // Inclure la bibliothèque de fonctions personnalisées&lt;br /&gt;
 #include &amp;quot;FS.h&amp;quot;        // Bibliothèque du système de fichiers pour les opérations sur les fichiers&lt;br /&gt;
 #include &amp;quot;SPIFFS.h&amp;quot;    // Bibliothèque du système de fichiers SPIFFS pour la lecture et l&amp;#039;écriture de fichiers&lt;br /&gt;
 #include &amp;lt;WiFi.h&amp;gt;      // Bibliothèque WiFi pour la création et la gestion des connexions WiFi&lt;br /&gt;
 #include &amp;lt;Ticker.h&amp;gt;    // Bibliothèque de chronométrage&lt;br /&gt;
 #include &amp;lt;WebServer.h&amp;gt; // Bibliothèque de serveur Web pour la création d&amp;#039;un serveur HTTP&lt;br /&gt;
&lt;br /&gt;
=== Code Exemples ===&lt;br /&gt;
&lt;br /&gt;
1.54_WIFI_refresh.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_ble_refresh.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_wifi_http_openweather.ino&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Code wifi_http_openweather ===&lt;br /&gt;
&lt;br /&gt;
https://openweathermap.org/ Veuillez vous enregistrer afin de vous procurer votre OpenWeatherMap API key&lt;br /&gt;
&lt;br /&gt;
http://bulk.openweathermap.org/sample/ on trouve ici : city.list.json.gz, le countryCode de votre ville (variable city)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;lt;HTTPClient.h&amp;gt;&lt;br /&gt;
#include &amp;lt;Arduino_JSON.h&amp;gt;&lt;br /&gt;
#include &amp;quot;EPD_GUI.h&amp;quot;&lt;br /&gt;
#include &amp;quot;Pic.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
// Define an array for black and white image data, which serves as the buffer for the e-paper display.&lt;br /&gt;
// The size of the buffer is determined according to the resolution of the e-paper display.&lt;br /&gt;
uint8_t ImageBW[2888];&lt;br /&gt;
&lt;br /&gt;
// WiFi network name // WiFi password&lt;br /&gt;
const char* ssid = &amp;quot;yanfa_software&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;yanfa-123456&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// OpenWeatherMap API key. This key is used to access weather data from the OpenWeatherMap API.&lt;br /&gt;
String openWeatherMapApiKey = &amp;quot;3c03d1f4e2dd3e14474a9a3a2f2299ff&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// City and country code for which weather data will be fetched.&lt;br /&gt;
String city = &amp;quot;London&amp;quot;;&lt;br /&gt;
String countryCode = &amp;quot;2643743&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Variables related to timing and API calls.&lt;br /&gt;
// lastTime keeps track of the last time the API was called.&lt;br /&gt;
unsigned long lastTime = 0;&lt;br /&gt;
// timerDelay determines the time interval between API calls. For testing, it&amp;#039;s set to 10 seconds (10000 milliseconds).&lt;br /&gt;
// In a final application, this should be set according to the API call limits per hour/minute.&lt;br /&gt;
unsigned long timerDelay = 10000;&lt;br /&gt;
&lt;br /&gt;
// Variables related to JSON data.&lt;br /&gt;
// jsonBuffer stores the raw JSON data received from the API.&lt;br /&gt;
String jsonBuffer;&lt;br /&gt;
// httpResponseCode holds the response code from the HTTP request.&lt;br /&gt;
int httpResponseCode;&lt;br /&gt;
// myObject is a JSON variable that will hold the parsed JSON data.&lt;br /&gt;
JSONVar myObject;&lt;br /&gt;
&lt;br /&gt;
// Variables related to weather information.&lt;br /&gt;
// weather stores the main weather description.&lt;br /&gt;
String weather;&lt;br /&gt;
// temperature stores the temperature value.&lt;br /&gt;
String temperature;&lt;br /&gt;
// humidity stores the humidity value.&lt;br /&gt;
String humidity;&lt;br /&gt;
// sea_level stores the sea level value.&lt;br /&gt;
String sea_level;&lt;br /&gt;
// wind_speed stores the wind speed value.&lt;br /&gt;
String wind_speed;&lt;br /&gt;
// city_js stores the name of the city.&lt;br /&gt;
String city_js;&lt;br /&gt;
// weather_flag is a flag that determines which weather icon to display based on the weather description.&lt;br /&gt;
int weather_flag = 0;&lt;br /&gt;
&lt;br /&gt;
// Function to display weather forecast on the e-paper display.&lt;br /&gt;
void UI_weather_forecast()&lt;br /&gt;
{&lt;br /&gt;
  char buffer[40];&lt;br /&gt;
&lt;br /&gt;
  EPD_HW_RESET();&lt;br /&gt;
&lt;br /&gt;
  // Display a background picture on the e-paper.&lt;br /&gt;
  EPD_ShowPicture(0, 0, 152, 152, pic, BLACK);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  //If you need to replace the display options,&lt;br /&gt;
  //open the following options: temp, wind, visit, hum&lt;br /&gt;
  //The following uses the hum option as an example&lt;br /&gt;
&lt;br /&gt;
  //Visit&lt;br /&gt;
  //EPD_ShowPicture(76, 92, 56, 72, gImage_visit, BLACK);&lt;br /&gt;
  //Wind&lt;br /&gt;
  //EPD_ShowPicture(76, 92, 56, 72, gImage_wind, BLACK);&lt;br /&gt;
  //Temp&lt;br /&gt;
  //  EPD_ShowPicture(92, 0, 56, 72, gImage_temp, BLACK);&lt;br /&gt;
  //Hum&lt;br /&gt;
&lt;br /&gt;
  EPD_Display(ImageBW);&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_DeepSleep();&lt;br /&gt;
&lt;br /&gt;
  EPD_GPIOInit();&lt;br /&gt;
  Paint_NewImage(ImageBW, EPD_W, EPD_H, 270, WHITE);&lt;br /&gt;
  // Paint_Clear(WHITE);&lt;br /&gt;
  EPD_FastMode1Init();&lt;br /&gt;
  // EPD_Display_Clear();&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_Clear_R26H();&lt;br /&gt;
&lt;br /&gt;
  // Display the update time (it seems to be mislabeled as city_js here, might need to be corrected depending on the actual intention).&lt;br /&gt;
  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, city_js);&lt;br /&gt;
  EPD_ShowString(20, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //If you need to replace the display options,&lt;br /&gt;
  //open the following options: temp, wind, visit, hum&lt;br /&gt;
  //The following uses the hum option as an example&lt;br /&gt;
&lt;br /&gt;
  //Hum&lt;br /&gt;
  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, humidity);&lt;br /&gt;
  EPD_ShowString(105, 140, buffer,  12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //Temp&lt;br /&gt;
  //       memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  //       snprintf(buffer, sizeof(buffer), &amp;quot;%s C&amp;quot;, temperature);&lt;br /&gt;
  //       EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //Wind&lt;br /&gt;
  // memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  // snprintf(buffer, sizeof(buffer), &amp;quot;%s m/s&amp;quot;, wind_speed);&lt;br /&gt;
  // EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //visit&lt;br /&gt;
  //  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  //  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, sea_level);&lt;br /&gt;
  //  EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  // Update the e-paper display with the new content.&lt;br /&gt;
  EPD_Display(ImageBW);&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_DeepSleep();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200); // Initialize the serial communication.&lt;br /&gt;
&lt;br /&gt;
  // Connect to the WiFi network.&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  Serial.println(&amp;quot;Connecting&amp;quot;);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot;&amp;quot;);&lt;br /&gt;
  Serial.print(&amp;quot;Connected to WiFi network with IP Address: &amp;quot;);&lt;br /&gt;
  Serial.println(WiFi.localIP()); // Print the IP address of the device after successful connection.&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Timer set to 10 seconds (timerDelay variable), it will take 10 seconds before publishing the first reading.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Set pin 7 as an output pin to control the power of the e-paper display.&lt;br /&gt;
  pinMode(7, OUTPUT);&lt;br /&gt;
  digitalWrite(7, HIGH);&lt;br /&gt;
&lt;br /&gt;
  EPD_GPIOInit();&lt;br /&gt;
  Paint_NewImage(ImageBW, EPD_W, EPD_H, 0, WHITE);&lt;br /&gt;
  Paint_Clear(WHITE);&lt;br /&gt;
  EPD_FastMode1Init();&lt;br /&gt;
  EPD_Display_Clear();&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_Clear_R26H();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  js_analysis();&lt;br /&gt;
  UI_weather_forecast();&lt;br /&gt;
  delay(1000 * 60 * 60);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void js_analysis()&lt;br /&gt;
{&lt;br /&gt;
  // Check if the device is connected to the WiFi network.&lt;br /&gt;
  if (WiFi.status() == WL_CONNECTED) {&lt;br /&gt;
    // Construct the URL for the OpenWeatherMap API request.&lt;br /&gt;
    String serverPath = &amp;quot;http://api.openweathermap.org/data/2.5/weather?q=&amp;quot; + city + &amp;quot;,&amp;quot; + countryCode + &amp;quot;&amp;amp;APPID=&amp;quot; + openWeatherMapApiKey + &amp;quot;&amp;amp;units=metric&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    // Keep trying until a successful response (status code 200) is received.&lt;br /&gt;
    while (httpResponseCode != 200) {&lt;br /&gt;
      // Make an HTTP GET request to the API and store the response in jsonBuffer.&lt;br /&gt;
      jsonBuffer = httpGETRequest(serverPath.c_str());&lt;br /&gt;
      Serial.println(jsonBuffer);&lt;br /&gt;
      myObject = JSON.parse(jsonBuffer);&lt;br /&gt;
&lt;br /&gt;
      // Check if the JSON parsing was successful.&lt;br /&gt;
      if (JSON.typeof(myObject) == &amp;quot;undefined&amp;quot;) {&lt;br /&gt;
        Serial.println(&amp;quot;Parsing input failed!&amp;quot;);&lt;br /&gt;
        return;&lt;br /&gt;
      }&lt;br /&gt;
      delay(2000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Extract weather information from the parsed JSON data.&lt;br /&gt;
    weather = JSON.stringify(myObject[&amp;quot;weather&amp;quot;][0][&amp;quot;main&amp;quot;]);&lt;br /&gt;
    temperature = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;temp&amp;quot;]);&lt;br /&gt;
    humidity = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;humidity&amp;quot;]);&lt;br /&gt;
    sea_level = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;sea_level&amp;quot;]);&lt;br /&gt;
    wind_speed = JSON.stringify(myObject[&amp;quot;wind&amp;quot;][&amp;quot;speed&amp;quot;]);&lt;br /&gt;
    city_js = JSON.stringify(myObject[&amp;quot;name&amp;quot;]);&lt;br /&gt;
&lt;br /&gt;
    // Print the extracted weather information for debugging purposes.&lt;br /&gt;
    Serial.print(&amp;quot;String weather: &amp;quot;);&lt;br /&gt;
    Serial.println(weather);&lt;br /&gt;
    Serial.print(&amp;quot;String Temperature: &amp;quot;);&lt;br /&gt;
    Serial.println(temperature);&lt;br /&gt;
    Serial.print(&amp;quot;String humidity: &amp;quot;);&lt;br /&gt;
    Serial.println(humidity);&lt;br /&gt;
    Serial.print(&amp;quot;String sea_level: &amp;quot;);&lt;br /&gt;
    Serial.println(sea_level);&lt;br /&gt;
    Serial.print(&amp;quot;String wind_speed: &amp;quot;);&lt;br /&gt;
    Serial.println(wind_speed);&lt;br /&gt;
    Serial.print(&amp;quot;String city_js: &amp;quot;);&lt;br /&gt;
    Serial.println(city_js);&lt;br /&gt;
&lt;br /&gt;
    // Determine the weather icon based on the weather description.&lt;br /&gt;
    if (weather.indexOf(&amp;quot;clouds&amp;quot;) != -1 || weather.indexOf(&amp;quot;Clouds&amp;quot;) != -1 ) {&lt;br /&gt;
      weather_flag = 1;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;clear sky&amp;quot;) != -1 || weather.indexOf(&amp;quot;Clear sky&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 3;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;rain&amp;quot;) != -1 || weather.indexOf(&amp;quot;Rain&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 5;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;thunderstorm&amp;quot;) != -1 || weather.indexOf(&amp;quot;Thunderstorm&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 2;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;snow&amp;quot;) != -1 || weather.indexOf(&amp;quot;Snow&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 4;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;mist&amp;quot;) != -1 || weather.indexOf(&amp;quot;Mist&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 0;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
    // Print a message if the device is not connected to the WiFi network.&lt;br /&gt;
    Serial.println(&amp;quot;WiFi Disconnected&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Function to make an HTTP GET request and return the response.&lt;br /&gt;
String httpGETRequest(const char* serverName) {&lt;br /&gt;
  WiFiClient client;&lt;br /&gt;
  HTTPClient http;&lt;br /&gt;
&lt;br /&gt;
  // Initialize the HTTP client with the server name.&lt;br /&gt;
  http.begin(client, serverName);&lt;br /&gt;
&lt;br /&gt;
  // Send an HTTP GET request.&lt;br /&gt;
  httpResponseCode = http.GET();&lt;br /&gt;
&lt;br /&gt;
  // Initialize the response payload as an empty JSON object.&lt;br /&gt;
  String payload = &amp;quot;{}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  // Check if the response code is positive (indicating a successful request).&lt;br /&gt;
  if (httpResponseCode &amp;gt; 0) {&lt;br /&gt;
    Serial.print(&amp;quot;HTTP Response code: &amp;quot;);&lt;br /&gt;
    Serial.println(httpResponseCode);&lt;br /&gt;
    payload = http.getString();&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
    Serial.print(&amp;quot;Error code: &amp;quot;);&lt;br /&gt;
    Serial.println(httpResponseCode);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Close the HTTP connection.&lt;br /&gt;
  http.end();&lt;br /&gt;
&lt;br /&gt;
  return payload;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 Explications : Partie à modifier avec vos données, ssid, password, openWeatherMapApiKey, city, countryCode&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// WiFi network name // WiFi password&lt;br /&gt;
&lt;br /&gt;
const char* ssid = &amp;quot;yanfa_software&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;yanfa-123456&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// OpenWeatherMap API key. This key is used to access weather data from the OpenWeatherMap API.&lt;br /&gt;
String openWeatherMapApiKey = &amp;quot;3c03d1f4e2dd3e14474a9a3a2f2299ff&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// City and country code for which weather data will be fetched.&lt;br /&gt;
String city = &amp;quot;London&amp;quot;;&lt;br /&gt;
String countryCode = &amp;quot;2643743&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>144.2.107.134</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1877</id>
		<title>CrowPanel-ESP32-E-Paper-HMI-1.54</title>
		<link rel="alternate" type="text/html" href="https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1877"/>
		<updated>2025-11-23T22:28:16Z</updated>

		<summary type="html">&lt;p&gt;144.2.107.134: /* Code wifi_http_openweather */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== E-Paper-HMI-1.54 (Elecrow) ==&lt;br /&gt;
&lt;br /&gt;
=== Liens externes ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_HMI_1.54-inch_Display.html Wiki&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_1.54-inch_Arduino_Tutorial.html Arduino Setup&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/crowpanel-esp32-1-54-e-paper-hmi-display-with-152-152-resolution-black-white-color-driven-by-spi-interface.html Shop&lt;br /&gt;
&lt;br /&gt;
 BLE debugging assistant&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/1-54-inch-152-152-e-paper-display-black-white-e-ink-display-with-spi-communication.html&lt;br /&gt;
&lt;br /&gt;
=== Caractéristiques ===&lt;br /&gt;
&lt;br /&gt;
Driver Chip : &amp;lt;b&amp;gt;SSD1680&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Résolution 152 x 152&amp;lt;br&amp;gt;&lt;br /&gt;
Couleur noir et blanc&amp;lt;br&amp;gt;&lt;br /&gt;
Pilote ESP32-S3 comme contrôleur principal&amp;lt;br&amp;gt;&lt;br /&gt;
PSRAM : 8MB&amp;lt;br&amp;gt;&lt;br /&gt;
Flash :	8MB&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Images ===&lt;br /&gt;
&lt;br /&gt;
=== Ressources ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/download/product/CrowPanel/E-paper/Image2Lcd_v2.9.zip Image2Lcd_v2.9&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152 GitHub&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152/archive/refs/heads/master.zip ZIP&lt;br /&gt;
&lt;br /&gt;
=== Arduine Mise en route (Setup) ===&lt;br /&gt;
&lt;br /&gt;
Click &amp;quot;Tools&amp;quot;-&amp;gt;&amp;quot;Board&amp;quot;-&amp;gt;&amp;quot;esp32&amp;quot;-&amp;gt;&amp;quot;ESP32S3 Dev Module&amp;quot;, &lt;br /&gt;
&lt;br /&gt;
and the &amp;quot;Partition Scheme&amp;quot; select &lt;br /&gt;
&amp;quot;Huge APP (3MB No OTA/1MB SPIFFS)&amp;quot;, &lt;br /&gt;
&amp;quot;PSRAM&amp;quot; select &amp;quot;OPI PSRAM&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Librairies ===&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;Arduino.h&amp;gt;   // Inclure la bibliothèque principale Arduino&lt;br /&gt;
 #include &amp;quot;EPD_GUI.h&amp;quot;   // Inclure la bibliothèque pour l&amp;#039;écran à encre électronique&lt;br /&gt;
 #include &amp;quot;Pic.h&amp;quot;       // Inclure la bibliothèque de fonctions personnalisées&lt;br /&gt;
 #include &amp;quot;FS.h&amp;quot;        // Bibliothèque du système de fichiers pour les opérations sur les fichiers&lt;br /&gt;
 #include &amp;quot;SPIFFS.h&amp;quot;    // Bibliothèque du système de fichiers SPIFFS pour la lecture et l&amp;#039;écriture de fichiers&lt;br /&gt;
 #include &amp;lt;WiFi.h&amp;gt;      // Bibliothèque WiFi pour la création et la gestion des connexions WiFi&lt;br /&gt;
 #include &amp;lt;Ticker.h&amp;gt;    // Bibliothèque de chronométrage&lt;br /&gt;
 #include &amp;lt;WebServer.h&amp;gt; // Bibliothèque de serveur Web pour la création d&amp;#039;un serveur HTTP&lt;br /&gt;
&lt;br /&gt;
=== Code Exemples ===&lt;br /&gt;
&lt;br /&gt;
1.54_WIFI_refresh.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_ble_refresh.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_wifi_http_openweather.ino&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Code wifi_http_openweather ===&lt;br /&gt;
&lt;br /&gt;
https://openweathermap.org/&lt;br /&gt;
&lt;br /&gt;
http://bulk.openweathermap.org/sample/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;lt;HTTPClient.h&amp;gt;&lt;br /&gt;
#include &amp;lt;Arduino_JSON.h&amp;gt;&lt;br /&gt;
#include &amp;quot;EPD_GUI.h&amp;quot;&lt;br /&gt;
#include &amp;quot;Pic.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
// Define an array for black and white image data, which serves as the buffer for the e-paper display.&lt;br /&gt;
// The size of the buffer is determined according to the resolution of the e-paper display.&lt;br /&gt;
uint8_t ImageBW[2888];&lt;br /&gt;
&lt;br /&gt;
// WiFi network name.&lt;br /&gt;
const char* ssid = &amp;quot;yanfa_software&amp;quot;;&lt;br /&gt;
// WiFi password.&lt;br /&gt;
const char* password = &amp;quot;yanfa-123456&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// OpenWeatherMap API key. This key is used to access weather data from the OpenWeatherMap API.&lt;br /&gt;
String openWeatherMapApiKey = &amp;quot;3c03d1f4e2dd3e14474a9a3a2f2299ff&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// City and country code for which weather data will be fetched.&lt;br /&gt;
String city = &amp;quot;London&amp;quot;;&lt;br /&gt;
String countryCode = &amp;quot;2643743&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Variables related to timing and API calls.&lt;br /&gt;
// lastTime keeps track of the last time the API was called.&lt;br /&gt;
unsigned long lastTime = 0;&lt;br /&gt;
// timerDelay determines the time interval between API calls. For testing, it&amp;#039;s set to 10 seconds (10000 milliseconds).&lt;br /&gt;
// In a final application, this should be set according to the API call limits per hour/minute.&lt;br /&gt;
unsigned long timerDelay = 10000;&lt;br /&gt;
&lt;br /&gt;
// Variables related to JSON data.&lt;br /&gt;
// jsonBuffer stores the raw JSON data received from the API.&lt;br /&gt;
String jsonBuffer;&lt;br /&gt;
// httpResponseCode holds the response code from the HTTP request.&lt;br /&gt;
int httpResponseCode;&lt;br /&gt;
// myObject is a JSON variable that will hold the parsed JSON data.&lt;br /&gt;
JSONVar myObject;&lt;br /&gt;
&lt;br /&gt;
// Variables related to weather information.&lt;br /&gt;
// weather stores the main weather description.&lt;br /&gt;
String weather;&lt;br /&gt;
// temperature stores the temperature value.&lt;br /&gt;
String temperature;&lt;br /&gt;
// humidity stores the humidity value.&lt;br /&gt;
String humidity;&lt;br /&gt;
// sea_level stores the sea level value.&lt;br /&gt;
String sea_level;&lt;br /&gt;
// wind_speed stores the wind speed value.&lt;br /&gt;
String wind_speed;&lt;br /&gt;
// city_js stores the name of the city.&lt;br /&gt;
String city_js;&lt;br /&gt;
// weather_flag is a flag that determines which weather icon to display based on the weather description.&lt;br /&gt;
int weather_flag = 0;&lt;br /&gt;
&lt;br /&gt;
// Function to display weather forecast on the e-paper display.&lt;br /&gt;
void UI_weather_forecast()&lt;br /&gt;
{&lt;br /&gt;
  char buffer[40];&lt;br /&gt;
&lt;br /&gt;
  EPD_HW_RESET();&lt;br /&gt;
&lt;br /&gt;
  // Display a background picture on the e-paper.&lt;br /&gt;
  EPD_ShowPicture(0, 0, 152, 152, pic, BLACK);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  //If you need to replace the display options,&lt;br /&gt;
  //open the following options: temp, wind, visit, hum&lt;br /&gt;
  //The following uses the hum option as an example&lt;br /&gt;
&lt;br /&gt;
  //Visit&lt;br /&gt;
  //EPD_ShowPicture(76, 92, 56, 72, gImage_visit, BLACK);&lt;br /&gt;
  //Wind&lt;br /&gt;
  //EPD_ShowPicture(76, 92, 56, 72, gImage_wind, BLACK);&lt;br /&gt;
  //Temp&lt;br /&gt;
  //  EPD_ShowPicture(92, 0, 56, 72, gImage_temp, BLACK);&lt;br /&gt;
  //Hum&lt;br /&gt;
&lt;br /&gt;
  EPD_Display(ImageBW);&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_DeepSleep();&lt;br /&gt;
&lt;br /&gt;
  EPD_GPIOInit();&lt;br /&gt;
  Paint_NewImage(ImageBW, EPD_W, EPD_H, 270, WHITE);&lt;br /&gt;
  // Paint_Clear(WHITE);&lt;br /&gt;
  EPD_FastMode1Init();&lt;br /&gt;
  // EPD_Display_Clear();&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_Clear_R26H();&lt;br /&gt;
&lt;br /&gt;
  // Display the update time (it seems to be mislabeled as city_js here, might need to be corrected depending on the actual intention).&lt;br /&gt;
  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, city_js);&lt;br /&gt;
  EPD_ShowString(20, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //If you need to replace the display options,&lt;br /&gt;
  //open the following options: temp, wind, visit, hum&lt;br /&gt;
  //The following uses the hum option as an example&lt;br /&gt;
&lt;br /&gt;
  //Hum&lt;br /&gt;
  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, humidity);&lt;br /&gt;
  EPD_ShowString(105, 140, buffer,  12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //Temp&lt;br /&gt;
  //       memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  //       snprintf(buffer, sizeof(buffer), &amp;quot;%s C&amp;quot;, temperature);&lt;br /&gt;
  //       EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //Wind&lt;br /&gt;
  // memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  // snprintf(buffer, sizeof(buffer), &amp;quot;%s m/s&amp;quot;, wind_speed);&lt;br /&gt;
  // EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  //visit&lt;br /&gt;
  //  memset(buffer, 0, sizeof(buffer));&lt;br /&gt;
  //  snprintf(buffer, sizeof(buffer), &amp;quot;%s &amp;quot;, sea_level);&lt;br /&gt;
  //  EPD_ShowString(105, 140, buffer, 12, BLACK);&lt;br /&gt;
&lt;br /&gt;
  // Update the e-paper display with the new content.&lt;br /&gt;
  EPD_Display(ImageBW);&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_DeepSleep();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200); // Initialize the serial communication.&lt;br /&gt;
&lt;br /&gt;
  // Connect to the WiFi network.&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  Serial.println(&amp;quot;Connecting&amp;quot;);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot;&amp;quot;);&lt;br /&gt;
  Serial.print(&amp;quot;Connected to WiFi network with IP Address: &amp;quot;);&lt;br /&gt;
  Serial.println(WiFi.localIP()); // Print the IP address of the device after successful connection.&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Timer set to 10 seconds (timerDelay variable), it will take 10 seconds before publishing the first reading.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Set pin 7 as an output pin to control the power of the e-paper display.&lt;br /&gt;
  pinMode(7, OUTPUT);&lt;br /&gt;
  digitalWrite(7, HIGH);&lt;br /&gt;
&lt;br /&gt;
  EPD_GPIOInit();&lt;br /&gt;
  Paint_NewImage(ImageBW, EPD_W, EPD_H, 0, WHITE);&lt;br /&gt;
  Paint_Clear(WHITE);&lt;br /&gt;
  EPD_FastMode1Init();&lt;br /&gt;
  EPD_Display_Clear();&lt;br /&gt;
  EPD_FastUpdate();&lt;br /&gt;
  EPD_Clear_R26H();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  js_analysis();&lt;br /&gt;
  UI_weather_forecast();&lt;br /&gt;
  delay(1000 * 60 * 60);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void js_analysis()&lt;br /&gt;
{&lt;br /&gt;
  // Check if the device is connected to the WiFi network.&lt;br /&gt;
  if (WiFi.status() == WL_CONNECTED) {&lt;br /&gt;
    // Construct the URL for the OpenWeatherMap API request.&lt;br /&gt;
    String serverPath = &amp;quot;http://api.openweathermap.org/data/2.5/weather?q=&amp;quot; + city + &amp;quot;,&amp;quot; + countryCode + &amp;quot;&amp;amp;APPID=&amp;quot; + openWeatherMapApiKey + &amp;quot;&amp;amp;units=metric&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    // Keep trying until a successful response (status code 200) is received.&lt;br /&gt;
    while (httpResponseCode != 200) {&lt;br /&gt;
      // Make an HTTP GET request to the API and store the response in jsonBuffer.&lt;br /&gt;
      jsonBuffer = httpGETRequest(serverPath.c_str());&lt;br /&gt;
      Serial.println(jsonBuffer);&lt;br /&gt;
      myObject = JSON.parse(jsonBuffer);&lt;br /&gt;
&lt;br /&gt;
      // Check if the JSON parsing was successful.&lt;br /&gt;
      if (JSON.typeof(myObject) == &amp;quot;undefined&amp;quot;) {&lt;br /&gt;
        Serial.println(&amp;quot;Parsing input failed!&amp;quot;);&lt;br /&gt;
        return;&lt;br /&gt;
      }&lt;br /&gt;
      delay(2000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Extract weather information from the parsed JSON data.&lt;br /&gt;
    weather = JSON.stringify(myObject[&amp;quot;weather&amp;quot;][0][&amp;quot;main&amp;quot;]);&lt;br /&gt;
    temperature = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;temp&amp;quot;]);&lt;br /&gt;
    humidity = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;humidity&amp;quot;]);&lt;br /&gt;
    sea_level = JSON.stringify(myObject[&amp;quot;main&amp;quot;][&amp;quot;sea_level&amp;quot;]);&lt;br /&gt;
    wind_speed = JSON.stringify(myObject[&amp;quot;wind&amp;quot;][&amp;quot;speed&amp;quot;]);&lt;br /&gt;
    city_js = JSON.stringify(myObject[&amp;quot;name&amp;quot;]);&lt;br /&gt;
&lt;br /&gt;
    // Print the extracted weather information for debugging purposes.&lt;br /&gt;
    Serial.print(&amp;quot;String weather: &amp;quot;);&lt;br /&gt;
    Serial.println(weather);&lt;br /&gt;
    Serial.print(&amp;quot;String Temperature: &amp;quot;);&lt;br /&gt;
    Serial.println(temperature);&lt;br /&gt;
    Serial.print(&amp;quot;String humidity: &amp;quot;);&lt;br /&gt;
    Serial.println(humidity);&lt;br /&gt;
    Serial.print(&amp;quot;String sea_level: &amp;quot;);&lt;br /&gt;
    Serial.println(sea_level);&lt;br /&gt;
    Serial.print(&amp;quot;String wind_speed: &amp;quot;);&lt;br /&gt;
    Serial.println(wind_speed);&lt;br /&gt;
    Serial.print(&amp;quot;String city_js: &amp;quot;);&lt;br /&gt;
    Serial.println(city_js);&lt;br /&gt;
&lt;br /&gt;
    // Determine the weather icon based on the weather description.&lt;br /&gt;
    if (weather.indexOf(&amp;quot;clouds&amp;quot;) != -1 || weather.indexOf(&amp;quot;Clouds&amp;quot;) != -1 ) {&lt;br /&gt;
      weather_flag = 1;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;clear sky&amp;quot;) != -1 || weather.indexOf(&amp;quot;Clear sky&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 3;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;rain&amp;quot;) != -1 || weather.indexOf(&amp;quot;Rain&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 5;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;thunderstorm&amp;quot;) != -1 || weather.indexOf(&amp;quot;Thunderstorm&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 2;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;snow&amp;quot;) != -1 || weather.indexOf(&amp;quot;Snow&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 4;&lt;br /&gt;
    } else if (weather.indexOf(&amp;quot;mist&amp;quot;) != -1 || weather.indexOf(&amp;quot;Mist&amp;quot;) != -1) {&lt;br /&gt;
      weather_flag = 0;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
    // Print a message if the device is not connected to the WiFi network.&lt;br /&gt;
    Serial.println(&amp;quot;WiFi Disconnected&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Function to make an HTTP GET request and return the response.&lt;br /&gt;
String httpGETRequest(const char* serverName) {&lt;br /&gt;
  WiFiClient client;&lt;br /&gt;
  HTTPClient http;&lt;br /&gt;
&lt;br /&gt;
  // Initialize the HTTP client with the server name.&lt;br /&gt;
  http.begin(client, serverName);&lt;br /&gt;
&lt;br /&gt;
  // Send an HTTP GET request.&lt;br /&gt;
  httpResponseCode = http.GET();&lt;br /&gt;
&lt;br /&gt;
  // Initialize the response payload as an empty JSON object.&lt;br /&gt;
  String payload = &amp;quot;{}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  // Check if the response code is positive (indicating a successful request).&lt;br /&gt;
  if (httpResponseCode &amp;gt; 0) {&lt;br /&gt;
    Serial.print(&amp;quot;HTTP Response code: &amp;quot;);&lt;br /&gt;
    Serial.println(httpResponseCode);&lt;br /&gt;
    payload = http.getString();&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
    Serial.print(&amp;quot;Error code: &amp;quot;);&lt;br /&gt;
    Serial.println(httpResponseCode);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Close the HTTP connection.&lt;br /&gt;
  http.end();&lt;br /&gt;
&lt;br /&gt;
  return payload;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>144.2.107.134</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1876</id>
		<title>CrowPanel-ESP32-E-Paper-HMI-1.54</title>
		<link rel="alternate" type="text/html" href="https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1876"/>
		<updated>2025-11-23T22:13:46Z</updated>

		<summary type="html">&lt;p&gt;144.2.107.134: /* E-Paper-HMI-1.54 (Elecrow) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== E-Paper-HMI-1.54 (Elecrow) ==&lt;br /&gt;
&lt;br /&gt;
=== Liens externes ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_HMI_1.54-inch_Display.html Wiki&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_1.54-inch_Arduino_Tutorial.html Arduino Setup&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/crowpanel-esp32-1-54-e-paper-hmi-display-with-152-152-resolution-black-white-color-driven-by-spi-interface.html Shop&lt;br /&gt;
&lt;br /&gt;
 BLE debugging assistant&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/1-54-inch-152-152-e-paper-display-black-white-e-ink-display-with-spi-communication.html&lt;br /&gt;
&lt;br /&gt;
=== Caractéristiques ===&lt;br /&gt;
&lt;br /&gt;
Driver Chip : &amp;lt;b&amp;gt;SSD1680&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Résolution 152 x 152&amp;lt;br&amp;gt;&lt;br /&gt;
Couleur noir et blanc&amp;lt;br&amp;gt;&lt;br /&gt;
Pilote ESP32-S3 comme contrôleur principal&amp;lt;br&amp;gt;&lt;br /&gt;
PSRAM : 8MB&amp;lt;br&amp;gt;&lt;br /&gt;
Flash :	8MB&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Images ===&lt;br /&gt;
&lt;br /&gt;
=== Ressources ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/download/product/CrowPanel/E-paper/Image2Lcd_v2.9.zip Image2Lcd_v2.9&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152 GitHub&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152/archive/refs/heads/master.zip ZIP&lt;br /&gt;
&lt;br /&gt;
=== Arduine Mise en route (Setup) ===&lt;br /&gt;
&lt;br /&gt;
Click &amp;quot;Tools&amp;quot;-&amp;gt;&amp;quot;Board&amp;quot;-&amp;gt;&amp;quot;esp32&amp;quot;-&amp;gt;&amp;quot;ESP32S3 Dev Module&amp;quot;, &lt;br /&gt;
&lt;br /&gt;
and the &amp;quot;Partition Scheme&amp;quot; select &lt;br /&gt;
&amp;quot;Huge APP (3MB No OTA/1MB SPIFFS)&amp;quot;, &lt;br /&gt;
&amp;quot;PSRAM&amp;quot; select &amp;quot;OPI PSRAM&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Librairies ===&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;Arduino.h&amp;gt;   // Inclure la bibliothèque principale Arduino&lt;br /&gt;
 #include &amp;quot;EPD_GUI.h&amp;quot;   // Inclure la bibliothèque pour l&amp;#039;écran à encre électronique&lt;br /&gt;
 #include &amp;quot;Pic.h&amp;quot;       // Inclure la bibliothèque de fonctions personnalisées&lt;br /&gt;
 #include &amp;quot;FS.h&amp;quot;        // Bibliothèque du système de fichiers pour les opérations sur les fichiers&lt;br /&gt;
 #include &amp;quot;SPIFFS.h&amp;quot;    // Bibliothèque du système de fichiers SPIFFS pour la lecture et l&amp;#039;écriture de fichiers&lt;br /&gt;
 #include &amp;lt;WiFi.h&amp;gt;      // Bibliothèque WiFi pour la création et la gestion des connexions WiFi&lt;br /&gt;
 #include &amp;lt;Ticker.h&amp;gt;    // Bibliothèque de chronométrage&lt;br /&gt;
 #include &amp;lt;WebServer.h&amp;gt; // Bibliothèque de serveur Web pour la création d&amp;#039;un serveur HTTP&lt;br /&gt;
&lt;br /&gt;
=== Code Exemples ===&lt;br /&gt;
&lt;br /&gt;
1.54_WIFI_refresh.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_ble_refresh.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_wifi_http_openweather.ino&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Code wifi_http_openweather ===&lt;br /&gt;
&lt;br /&gt;
https://openweathermap.org/&lt;br /&gt;
&lt;br /&gt;
http://bulk.openweathermap.org/sample/&lt;/div&gt;</summary>
		<author><name>144.2.107.134</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1875</id>
		<title>CrowPanel-ESP32-E-Paper-HMI-1.54</title>
		<link rel="alternate" type="text/html" href="https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1875"/>
		<updated>2025-11-23T22:10:57Z</updated>

		<summary type="html">&lt;p&gt;144.2.107.134: /* Code Exemples */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== E-Paper-HMI-1.54 (Elecrow) ==&lt;br /&gt;
&lt;br /&gt;
=== Liens externes ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_HMI_1.54-inch_Display.html Wiki&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_1.54-inch_Arduino_Tutorial.html Arduino Setup&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/crowpanel-esp32-1-54-e-paper-hmi-display-with-152-152-resolution-black-white-color-driven-by-spi-interface.html Shop&lt;br /&gt;
&lt;br /&gt;
 BLE debugging assistant&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/1-54-inch-152-152-e-paper-display-black-white-e-ink-display-with-spi-communication.html&lt;br /&gt;
&lt;br /&gt;
=== Caractéristiques ===&lt;br /&gt;
&lt;br /&gt;
Driver Chip : &amp;lt;b&amp;gt;SSD1680&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Résolution 152 x 152&amp;lt;br&amp;gt;&lt;br /&gt;
Couleur noir et blanc&amp;lt;br&amp;gt;&lt;br /&gt;
Pilote ESP32-S3 comme contrôleur principal&amp;lt;br&amp;gt;&lt;br /&gt;
PSRAM : 8MB&amp;lt;br&amp;gt;&lt;br /&gt;
Flash :	8MB&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Images ===&lt;br /&gt;
&lt;br /&gt;
=== Ressources ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/download/product/CrowPanel/E-paper/Image2Lcd_v2.9.zip Image2Lcd_v2.9&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152 GitHub&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152/archive/refs/heads/master.zip ZIP&lt;br /&gt;
&lt;br /&gt;
=== Arduine Mise en route (Setup) ===&lt;br /&gt;
&lt;br /&gt;
Click &amp;quot;Tools&amp;quot;-&amp;gt;&amp;quot;Board&amp;quot;-&amp;gt;&amp;quot;esp32&amp;quot;-&amp;gt;&amp;quot;ESP32S3 Dev Module&amp;quot;, &lt;br /&gt;
&lt;br /&gt;
and the &amp;quot;Partition Scheme&amp;quot; select &lt;br /&gt;
&amp;quot;Huge APP (3MB No OTA/1MB SPIFFS)&amp;quot;, &lt;br /&gt;
&amp;quot;PSRAM&amp;quot; select &amp;quot;OPI PSRAM&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Librairies ===&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;Arduino.h&amp;gt;   // Inclure la bibliothèque principale Arduino&lt;br /&gt;
 #include &amp;quot;EPD_GUI.h&amp;quot;   // Inclure la bibliothèque pour l&amp;#039;écran à encre électronique&lt;br /&gt;
 #include &amp;quot;Pic.h&amp;quot;       // Inclure la bibliothèque de fonctions personnalisées&lt;br /&gt;
 #include &amp;quot;FS.h&amp;quot;        // Bibliothèque du système de fichiers pour les opérations sur les fichiers&lt;br /&gt;
 #include &amp;quot;SPIFFS.h&amp;quot;    // Bibliothèque du système de fichiers SPIFFS pour la lecture et l&amp;#039;écriture de fichiers&lt;br /&gt;
 #include &amp;lt;WiFi.h&amp;gt;      // Bibliothèque WiFi pour la création et la gestion des connexions WiFi&lt;br /&gt;
 #include &amp;lt;Ticker.h&amp;gt;    // Bibliothèque de chronométrage&lt;br /&gt;
 #include &amp;lt;WebServer.h&amp;gt; // Bibliothèque de serveur Web pour la création d&amp;#039;un serveur HTTP&lt;br /&gt;
&lt;br /&gt;
=== Code Exemples ===&lt;br /&gt;
&lt;br /&gt;
1.54_WIFI_refresh.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_ble_refresh.ino&amp;lt;br&amp;gt;&lt;br /&gt;
1.54_wifi_http_openweather.ino&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>144.2.107.134</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1874</id>
		<title>CrowPanel-ESP32-E-Paper-HMI-1.54</title>
		<link rel="alternate" type="text/html" href="https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1874"/>
		<updated>2025-11-23T22:03:27Z</updated>

		<summary type="html">&lt;p&gt;144.2.107.134: /* Ressources */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== E-Paper-HMI-1.54 (Elecrow) ==&lt;br /&gt;
&lt;br /&gt;
=== Liens externes ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_HMI_1.54-inch_Display.html Wiki&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_1.54-inch_Arduino_Tutorial.html Arduino Setup&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/crowpanel-esp32-1-54-e-paper-hmi-display-with-152-152-resolution-black-white-color-driven-by-spi-interface.html Shop&lt;br /&gt;
&lt;br /&gt;
 BLE debugging assistant&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/1-54-inch-152-152-e-paper-display-black-white-e-ink-display-with-spi-communication.html&lt;br /&gt;
&lt;br /&gt;
=== Caractéristiques ===&lt;br /&gt;
&lt;br /&gt;
Driver Chip : &amp;lt;b&amp;gt;SSD1680&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Résolution 152 x 152&amp;lt;br&amp;gt;&lt;br /&gt;
Couleur noir et blanc&amp;lt;br&amp;gt;&lt;br /&gt;
Pilote ESP32-S3 comme contrôleur principal&amp;lt;br&amp;gt;&lt;br /&gt;
PSRAM : 8MB&amp;lt;br&amp;gt;&lt;br /&gt;
Flash :	8MB&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Images ===&lt;br /&gt;
&lt;br /&gt;
=== Ressources ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/download/product/CrowPanel/E-paper/Image2Lcd_v2.9.zip Image2Lcd_v2.9&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152 GitHub&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152/archive/refs/heads/master.zip ZIP&lt;br /&gt;
&lt;br /&gt;
=== Arduine Mise en route (Setup) ===&lt;br /&gt;
&lt;br /&gt;
Click &amp;quot;Tools&amp;quot;-&amp;gt;&amp;quot;Board&amp;quot;-&amp;gt;&amp;quot;esp32&amp;quot;-&amp;gt;&amp;quot;ESP32S3 Dev Module&amp;quot;, &lt;br /&gt;
&lt;br /&gt;
and the &amp;quot;Partition Scheme&amp;quot; select &lt;br /&gt;
&amp;quot;Huge APP (3MB No OTA/1MB SPIFFS)&amp;quot;, &lt;br /&gt;
&amp;quot;PSRAM&amp;quot; select &amp;quot;OPI PSRAM&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Librairies ===&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;Arduino.h&amp;gt;   // Inclure la bibliothèque principale Arduino&lt;br /&gt;
 #include &amp;quot;EPD_GUI.h&amp;quot;   // Inclure la bibliothèque pour l&amp;#039;écran à encre électronique&lt;br /&gt;
 #include &amp;quot;Pic.h&amp;quot;       // Inclure la bibliothèque de fonctions personnalisées&lt;br /&gt;
 #include &amp;quot;FS.h&amp;quot;        // Bibliothèque du système de fichiers pour les opérations sur les fichiers&lt;br /&gt;
 #include &amp;quot;SPIFFS.h&amp;quot;    // Bibliothèque du système de fichiers SPIFFS pour la lecture et l&amp;#039;écriture de fichiers&lt;br /&gt;
 #include &amp;lt;WiFi.h&amp;gt;      // Bibliothèque WiFi pour la création et la gestion des connexions WiFi&lt;br /&gt;
 #include &amp;lt;Ticker.h&amp;gt;    // Bibliothèque de chronométrage&lt;br /&gt;
 #include &amp;lt;WebServer.h&amp;gt; // Bibliothèque de serveur Web pour la création d&amp;#039;un serveur HTTP&lt;br /&gt;
&lt;br /&gt;
=== Code Exemples ===&lt;/div&gt;</summary>
		<author><name>144.2.107.134</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1873</id>
		<title>CrowPanel-ESP32-E-Paper-HMI-1.54</title>
		<link rel="alternate" type="text/html" href="https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1873"/>
		<updated>2025-11-23T21:58:27Z</updated>

		<summary type="html">&lt;p&gt;144.2.107.134: /* Ressources */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== E-Paper-HMI-1.54 (Elecrow) ==&lt;br /&gt;
&lt;br /&gt;
=== Liens externes ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_HMI_1.54-inch_Display.html Wiki&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_1.54-inch_Arduino_Tutorial.html Arduino Setup&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/crowpanel-esp32-1-54-e-paper-hmi-display-with-152-152-resolution-black-white-color-driven-by-spi-interface.html Shop&lt;br /&gt;
&lt;br /&gt;
 BLE debugging assistant&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/1-54-inch-152-152-e-paper-display-black-white-e-ink-display-with-spi-communication.html&lt;br /&gt;
&lt;br /&gt;
=== Caractéristiques ===&lt;br /&gt;
&lt;br /&gt;
Driver Chip : &amp;lt;b&amp;gt;SSD1680&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Résolution 152 x 152&amp;lt;br&amp;gt;&lt;br /&gt;
Couleur noir et blanc&amp;lt;br&amp;gt;&lt;br /&gt;
Pilote ESP32-S3 comme contrôleur principal&amp;lt;br&amp;gt;&lt;br /&gt;
PSRAM : 8MB&amp;lt;br&amp;gt;&lt;br /&gt;
Flash :	8MB&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Images ===&lt;br /&gt;
&lt;br /&gt;
=== Ressources ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/download/product/CrowPanel/E-paper/Image2Lcd_v2.9.zip&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152 GitHub&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152/archive/refs/heads/master.zip ZIP&lt;br /&gt;
&lt;br /&gt;
=== Arduine Mise en route (Setup) ===&lt;br /&gt;
&lt;br /&gt;
Click &amp;quot;Tools&amp;quot;-&amp;gt;&amp;quot;Board&amp;quot;-&amp;gt;&amp;quot;esp32&amp;quot;-&amp;gt;&amp;quot;ESP32S3 Dev Module&amp;quot;, &lt;br /&gt;
&lt;br /&gt;
and the &amp;quot;Partition Scheme&amp;quot; select &lt;br /&gt;
&amp;quot;Huge APP (3MB No OTA/1MB SPIFFS)&amp;quot;, &lt;br /&gt;
&amp;quot;PSRAM&amp;quot; select &amp;quot;OPI PSRAM&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Librairies ===&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;Arduino.h&amp;gt;   // Inclure la bibliothèque principale Arduino&lt;br /&gt;
 #include &amp;quot;EPD_GUI.h&amp;quot;   // Inclure la bibliothèque pour l&amp;#039;écran à encre électronique&lt;br /&gt;
 #include &amp;quot;Pic.h&amp;quot;       // Inclure la bibliothèque de fonctions personnalisées&lt;br /&gt;
 #include &amp;quot;FS.h&amp;quot;        // Bibliothèque du système de fichiers pour les opérations sur les fichiers&lt;br /&gt;
 #include &amp;quot;SPIFFS.h&amp;quot;    // Bibliothèque du système de fichiers SPIFFS pour la lecture et l&amp;#039;écriture de fichiers&lt;br /&gt;
 #include &amp;lt;WiFi.h&amp;gt;      // Bibliothèque WiFi pour la création et la gestion des connexions WiFi&lt;br /&gt;
 #include &amp;lt;Ticker.h&amp;gt;    // Bibliothèque de chronométrage&lt;br /&gt;
 #include &amp;lt;WebServer.h&amp;gt; // Bibliothèque de serveur Web pour la création d&amp;#039;un serveur HTTP&lt;br /&gt;
&lt;br /&gt;
=== Code Exemples ===&lt;/div&gt;</summary>
		<author><name>144.2.107.134</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1872</id>
		<title>CrowPanel-ESP32-E-Paper-HMI-1.54</title>
		<link rel="alternate" type="text/html" href="https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1872"/>
		<updated>2025-11-23T21:55:01Z</updated>

		<summary type="html">&lt;p&gt;144.2.107.134: /* Ressources */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== E-Paper-HMI-1.54 (Elecrow) ==&lt;br /&gt;
&lt;br /&gt;
=== Liens externes ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_HMI_1.54-inch_Display.html Wiki&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_1.54-inch_Arduino_Tutorial.html Arduino Setup&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/crowpanel-esp32-1-54-e-paper-hmi-display-with-152-152-resolution-black-white-color-driven-by-spi-interface.html Shop&lt;br /&gt;
&lt;br /&gt;
 BLE debugging assistant&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/1-54-inch-152-152-e-paper-display-black-white-e-ink-display-with-spi-communication.html&lt;br /&gt;
&lt;br /&gt;
=== Caractéristiques ===&lt;br /&gt;
&lt;br /&gt;
Driver Chip : &amp;lt;b&amp;gt;SSD1680&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Résolution 152 x 152&amp;lt;br&amp;gt;&lt;br /&gt;
Couleur noir et blanc&amp;lt;br&amp;gt;&lt;br /&gt;
Pilote ESP32-S3 comme contrôleur principal&amp;lt;br&amp;gt;&lt;br /&gt;
PSRAM : 8MB&amp;lt;br&amp;gt;&lt;br /&gt;
Flash :	8MB&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Images ===&lt;br /&gt;
&lt;br /&gt;
=== Ressources ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/download/product/CrowPanel/E-paper/Image2Lcd_v2.9.zip&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152 GitHub&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152.git ZIP&lt;br /&gt;
&lt;br /&gt;
=== Arduine Mise en route (Setup) ===&lt;br /&gt;
&lt;br /&gt;
Click &amp;quot;Tools&amp;quot;-&amp;gt;&amp;quot;Board&amp;quot;-&amp;gt;&amp;quot;esp32&amp;quot;-&amp;gt;&amp;quot;ESP32S3 Dev Module&amp;quot;, &lt;br /&gt;
&lt;br /&gt;
and the &amp;quot;Partition Scheme&amp;quot; select &lt;br /&gt;
&amp;quot;Huge APP (3MB No OTA/1MB SPIFFS)&amp;quot;, &lt;br /&gt;
&amp;quot;PSRAM&amp;quot; select &amp;quot;OPI PSRAM&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Librairies ===&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;Arduino.h&amp;gt;   // Inclure la bibliothèque principale Arduino&lt;br /&gt;
 #include &amp;quot;EPD_GUI.h&amp;quot;   // Inclure la bibliothèque pour l&amp;#039;écran à encre électronique&lt;br /&gt;
 #include &amp;quot;Pic.h&amp;quot;       // Inclure la bibliothèque de fonctions personnalisées&lt;br /&gt;
 #include &amp;quot;FS.h&amp;quot;        // Bibliothèque du système de fichiers pour les opérations sur les fichiers&lt;br /&gt;
 #include &amp;quot;SPIFFS.h&amp;quot;    // Bibliothèque du système de fichiers SPIFFS pour la lecture et l&amp;#039;écriture de fichiers&lt;br /&gt;
 #include &amp;lt;WiFi.h&amp;gt;      // Bibliothèque WiFi pour la création et la gestion des connexions WiFi&lt;br /&gt;
 #include &amp;lt;Ticker.h&amp;gt;    // Bibliothèque de chronométrage&lt;br /&gt;
 #include &amp;lt;WebServer.h&amp;gt; // Bibliothèque de serveur Web pour la création d&amp;#039;un serveur HTTP&lt;br /&gt;
&lt;br /&gt;
=== Code Exemples ===&lt;/div&gt;</summary>
		<author><name>144.2.107.134</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1871</id>
		<title>CrowPanel-ESP32-E-Paper-HMI-1.54</title>
		<link rel="alternate" type="text/html" href="https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1871"/>
		<updated>2025-11-23T21:53:59Z</updated>

		<summary type="html">&lt;p&gt;144.2.107.134: /* Ressources */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== E-Paper-HMI-1.54 (Elecrow) ==&lt;br /&gt;
&lt;br /&gt;
=== Liens externes ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_HMI_1.54-inch_Display.html Wiki&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_1.54-inch_Arduino_Tutorial.html Arduino Setup&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/crowpanel-esp32-1-54-e-paper-hmi-display-with-152-152-resolution-black-white-color-driven-by-spi-interface.html Shop&lt;br /&gt;
&lt;br /&gt;
 BLE debugging assistant&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/1-54-inch-152-152-e-paper-display-black-white-e-ink-display-with-spi-communication.html&lt;br /&gt;
&lt;br /&gt;
=== Caractéristiques ===&lt;br /&gt;
&lt;br /&gt;
Driver Chip : &amp;lt;b&amp;gt;SSD1680&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Résolution 152 x 152&amp;lt;br&amp;gt;&lt;br /&gt;
Couleur noir et blanc&amp;lt;br&amp;gt;&lt;br /&gt;
Pilote ESP32-S3 comme contrôleur principal&amp;lt;br&amp;gt;&lt;br /&gt;
PSRAM : 8MB&amp;lt;br&amp;gt;&lt;br /&gt;
Flash :	8MB&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Images ===&lt;br /&gt;
&lt;br /&gt;
=== Ressources ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/download/product/CrowPanel/E-paper/Image2Lcd_v2.9.zip&lt;br /&gt;
&lt;br /&gt;
https://github.com/Elecrow-RD/CrowPanel-ESP32-1.54-E-paper-HMI-Display-with-152-152 GitHub&lt;br /&gt;
&lt;br /&gt;
=== Arduine Mise en route (Setup) ===&lt;br /&gt;
&lt;br /&gt;
Click &amp;quot;Tools&amp;quot;-&amp;gt;&amp;quot;Board&amp;quot;-&amp;gt;&amp;quot;esp32&amp;quot;-&amp;gt;&amp;quot;ESP32S3 Dev Module&amp;quot;, &lt;br /&gt;
&lt;br /&gt;
and the &amp;quot;Partition Scheme&amp;quot; select &lt;br /&gt;
&amp;quot;Huge APP (3MB No OTA/1MB SPIFFS)&amp;quot;, &lt;br /&gt;
&amp;quot;PSRAM&amp;quot; select &amp;quot;OPI PSRAM&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Librairies ===&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;Arduino.h&amp;gt;   // Inclure la bibliothèque principale Arduino&lt;br /&gt;
 #include &amp;quot;EPD_GUI.h&amp;quot;   // Inclure la bibliothèque pour l&amp;#039;écran à encre électronique&lt;br /&gt;
 #include &amp;quot;Pic.h&amp;quot;       // Inclure la bibliothèque de fonctions personnalisées&lt;br /&gt;
 #include &amp;quot;FS.h&amp;quot;        // Bibliothèque du système de fichiers pour les opérations sur les fichiers&lt;br /&gt;
 #include &amp;quot;SPIFFS.h&amp;quot;    // Bibliothèque du système de fichiers SPIFFS pour la lecture et l&amp;#039;écriture de fichiers&lt;br /&gt;
 #include &amp;lt;WiFi.h&amp;gt;      // Bibliothèque WiFi pour la création et la gestion des connexions WiFi&lt;br /&gt;
 #include &amp;lt;Ticker.h&amp;gt;    // Bibliothèque de chronométrage&lt;br /&gt;
 #include &amp;lt;WebServer.h&amp;gt; // Bibliothèque de serveur Web pour la création d&amp;#039;un serveur HTTP&lt;br /&gt;
&lt;br /&gt;
=== Code Exemples ===&lt;/div&gt;</summary>
		<author><name>144.2.107.134</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1870</id>
		<title>CrowPanel-ESP32-E-Paper-HMI-1.54</title>
		<link rel="alternate" type="text/html" href="https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1870"/>
		<updated>2025-11-23T21:52:49Z</updated>

		<summary type="html">&lt;p&gt;144.2.107.134: /* E-Paper-HMI-1.54 (Elecrow) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== E-Paper-HMI-1.54 (Elecrow) ==&lt;br /&gt;
&lt;br /&gt;
=== Liens externes ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_HMI_1.54-inch_Display.html Wiki&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_1.54-inch_Arduino_Tutorial.html Arduino Setup&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/crowpanel-esp32-1-54-e-paper-hmi-display-with-152-152-resolution-black-white-color-driven-by-spi-interface.html Shop&lt;br /&gt;
&lt;br /&gt;
 BLE debugging assistant&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/1-54-inch-152-152-e-paper-display-black-white-e-ink-display-with-spi-communication.html&lt;br /&gt;
&lt;br /&gt;
=== Caractéristiques ===&lt;br /&gt;
&lt;br /&gt;
Driver Chip : &amp;lt;b&amp;gt;SSD1680&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Résolution 152 x 152&amp;lt;br&amp;gt;&lt;br /&gt;
Couleur noir et blanc&amp;lt;br&amp;gt;&lt;br /&gt;
Pilote ESP32-S3 comme contrôleur principal&amp;lt;br&amp;gt;&lt;br /&gt;
PSRAM : 8MB&amp;lt;br&amp;gt;&lt;br /&gt;
Flash :	8MB&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Images ===&lt;br /&gt;
&lt;br /&gt;
=== Ressources ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/download/product/CrowPanel/E-paper/Image2Lcd_v2.9.zip&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Arduine Mise en route (Setup) ===&lt;br /&gt;
&lt;br /&gt;
Click &amp;quot;Tools&amp;quot;-&amp;gt;&amp;quot;Board&amp;quot;-&amp;gt;&amp;quot;esp32&amp;quot;-&amp;gt;&amp;quot;ESP32S3 Dev Module&amp;quot;, &lt;br /&gt;
&lt;br /&gt;
and the &amp;quot;Partition Scheme&amp;quot; select &lt;br /&gt;
&amp;quot;Huge APP (3MB No OTA/1MB SPIFFS)&amp;quot;, &lt;br /&gt;
&amp;quot;PSRAM&amp;quot; select &amp;quot;OPI PSRAM&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Librairies ===&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;Arduino.h&amp;gt;   // Inclure la bibliothèque principale Arduino&lt;br /&gt;
 #include &amp;quot;EPD_GUI.h&amp;quot;   // Inclure la bibliothèque pour l&amp;#039;écran à encre électronique&lt;br /&gt;
 #include &amp;quot;Pic.h&amp;quot;       // Inclure la bibliothèque de fonctions personnalisées&lt;br /&gt;
 #include &amp;quot;FS.h&amp;quot;        // Bibliothèque du système de fichiers pour les opérations sur les fichiers&lt;br /&gt;
 #include &amp;quot;SPIFFS.h&amp;quot;    // Bibliothèque du système de fichiers SPIFFS pour la lecture et l&amp;#039;écriture de fichiers&lt;br /&gt;
 #include &amp;lt;WiFi.h&amp;gt;      // Bibliothèque WiFi pour la création et la gestion des connexions WiFi&lt;br /&gt;
 #include &amp;lt;Ticker.h&amp;gt;    // Bibliothèque de chronométrage&lt;br /&gt;
 #include &amp;lt;WebServer.h&amp;gt; // Bibliothèque de serveur Web pour la création d&amp;#039;un serveur HTTP&lt;br /&gt;
&lt;br /&gt;
=== Code Exemples ===&lt;/div&gt;</summary>
		<author><name>144.2.107.134</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1869</id>
		<title>CrowPanel-ESP32-E-Paper-HMI-1.54</title>
		<link rel="alternate" type="text/html" href="https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1869"/>
		<updated>2025-11-23T21:47:04Z</updated>

		<summary type="html">&lt;p&gt;144.2.107.134: /* Arduine Mise en route (Setup) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== E-Paper-HMI-1.54 (Elecrow) ==&lt;br /&gt;
&lt;br /&gt;
=== Liens externes ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_HMI_1.54-inch_Display.html Wiki&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_1.54-inch_Arduino_Tutorial.html Arduino Setup&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/crowpanel-esp32-1-54-e-paper-hmi-display-with-152-152-resolution-black-white-color-driven-by-spi-interface.html Shop&lt;br /&gt;
&lt;br /&gt;
 BLE debugging assistant&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/1-54-inch-152-152-e-paper-display-black-white-e-ink-display-with-spi-communication.html&lt;br /&gt;
&lt;br /&gt;
=== Caractéristiques ===&lt;br /&gt;
&lt;br /&gt;
Driver Chip : &amp;lt;b&amp;gt;SSD1680&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Résolution 152 x 152&amp;lt;br&amp;gt;&lt;br /&gt;
Couleur noir et blanc&amp;lt;br&amp;gt;&lt;br /&gt;
Pilote ESP32-S3 comme contrôleur principal&amp;lt;br&amp;gt;&lt;br /&gt;
PSRAM : 8MB&amp;lt;br&amp;gt;&lt;br /&gt;
Flash :	8MB&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Images ===&lt;br /&gt;
=== Arduine Mise en route (Setup) ===&lt;br /&gt;
&lt;br /&gt;
Click &amp;quot;Tools&amp;quot;-&amp;gt;&amp;quot;Board&amp;quot;-&amp;gt;&amp;quot;esp32&amp;quot;-&amp;gt;&amp;quot;ESP32S3 Dev Module&amp;quot;, &lt;br /&gt;
&lt;br /&gt;
and the &amp;quot;Partition Scheme&amp;quot; select &lt;br /&gt;
&amp;quot;Huge APP (3MB No OTA/1MB SPIFFS)&amp;quot;, &lt;br /&gt;
&amp;quot;PSRAM&amp;quot; select &amp;quot;OPI PSRAM&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Librairies ===&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;Arduino.h&amp;gt;   // Inclure la bibliothèque principale Arduino&lt;br /&gt;
 #include &amp;quot;EPD_GUI.h&amp;quot;   // Inclure la bibliothèque pour l&amp;#039;écran à encre électronique&lt;br /&gt;
 #include &amp;quot;Pic.h&amp;quot;       // Inclure la bibliothèque de fonctions personnalisées&lt;br /&gt;
 #include &amp;quot;FS.h&amp;quot;        // Bibliothèque du système de fichiers pour les opérations sur les fichiers&lt;br /&gt;
 #include &amp;quot;SPIFFS.h&amp;quot;    // Bibliothèque du système de fichiers SPIFFS pour la lecture et l&amp;#039;écriture de fichiers&lt;br /&gt;
 #include &amp;lt;WiFi.h&amp;gt;      // Bibliothèque WiFi pour la création et la gestion des connexions WiFi&lt;br /&gt;
 #include &amp;lt;Ticker.h&amp;gt;    // Bibliothèque de chronométrage&lt;br /&gt;
 #include &amp;lt;WebServer.h&amp;gt; // Bibliothèque de serveur Web pour la création d&amp;#039;un serveur HTTP&lt;br /&gt;
&lt;br /&gt;
=== Code Exemples ===&lt;/div&gt;</summary>
		<author><name>144.2.107.134</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1868</id>
		<title>CrowPanel-ESP32-E-Paper-HMI-1.54</title>
		<link rel="alternate" type="text/html" href="https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1868"/>
		<updated>2025-11-23T21:45:36Z</updated>

		<summary type="html">&lt;p&gt;144.2.107.134: /* Librairies */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== E-Paper-HMI-1.54 (Elecrow) ==&lt;br /&gt;
&lt;br /&gt;
=== Liens externes ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_HMI_1.54-inch_Display.html Wiki&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_1.54-inch_Arduino_Tutorial.html Arduino Setup&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/crowpanel-esp32-1-54-e-paper-hmi-display-with-152-152-resolution-black-white-color-driven-by-spi-interface.html Shop&lt;br /&gt;
&lt;br /&gt;
 BLE debugging assistant&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/1-54-inch-152-152-e-paper-display-black-white-e-ink-display-with-spi-communication.html&lt;br /&gt;
&lt;br /&gt;
=== Caractéristiques ===&lt;br /&gt;
&lt;br /&gt;
Driver Chip : &amp;lt;b&amp;gt;SSD1680&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Résolution 152 x 152&amp;lt;br&amp;gt;&lt;br /&gt;
Couleur noir et blanc&amp;lt;br&amp;gt;&lt;br /&gt;
Pilote ESP32-S3 comme contrôleur principal&amp;lt;br&amp;gt;&lt;br /&gt;
PSRAM : 8MB&amp;lt;br&amp;gt;&lt;br /&gt;
Flash :	8MB&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Images ===&lt;br /&gt;
=== Arduine Mise en route (Setup) ===&lt;br /&gt;
=== Librairies ===&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;Arduino.h&amp;gt;   // Inclure la bibliothèque principale Arduino&lt;br /&gt;
 #include &amp;quot;EPD_GUI.h&amp;quot;   // Inclure la bibliothèque pour l&amp;#039;écran à encre électronique&lt;br /&gt;
 #include &amp;quot;Pic.h&amp;quot;       // Inclure la bibliothèque de fonctions personnalisées&lt;br /&gt;
 #include &amp;quot;FS.h&amp;quot;        // Bibliothèque du système de fichiers pour les opérations sur les fichiers&lt;br /&gt;
 #include &amp;quot;SPIFFS.h&amp;quot;    // Bibliothèque du système de fichiers SPIFFS pour la lecture et l&amp;#039;écriture de fichiers&lt;br /&gt;
 #include &amp;lt;WiFi.h&amp;gt;      // Bibliothèque WiFi pour la création et la gestion des connexions WiFi&lt;br /&gt;
 #include &amp;lt;Ticker.h&amp;gt;    // Bibliothèque de chronométrage&lt;br /&gt;
 #include &amp;lt;WebServer.h&amp;gt; // Bibliothèque de serveur Web pour la création d&amp;#039;un serveur HTTP&lt;br /&gt;
&lt;br /&gt;
=== Code Exemples ===&lt;/div&gt;</summary>
		<author><name>144.2.107.134</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1867</id>
		<title>CrowPanel-ESP32-E-Paper-HMI-1.54</title>
		<link rel="alternate" type="text/html" href="https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1867"/>
		<updated>2025-11-23T21:43:17Z</updated>

		<summary type="html">&lt;p&gt;144.2.107.134: /* Librairies */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== E-Paper-HMI-1.54 (Elecrow) ==&lt;br /&gt;
&lt;br /&gt;
=== Liens externes ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_HMI_1.54-inch_Display.html Wiki&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_1.54-inch_Arduino_Tutorial.html Arduino Setup&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/crowpanel-esp32-1-54-e-paper-hmi-display-with-152-152-resolution-black-white-color-driven-by-spi-interface.html Shop&lt;br /&gt;
&lt;br /&gt;
 BLE debugging assistant&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/1-54-inch-152-152-e-paper-display-black-white-e-ink-display-with-spi-communication.html&lt;br /&gt;
&lt;br /&gt;
=== Caractéristiques ===&lt;br /&gt;
&lt;br /&gt;
Driver Chip : &amp;lt;b&amp;gt;SSD1680&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Résolution 152 x 152&amp;lt;br&amp;gt;&lt;br /&gt;
Couleur noir et blanc&amp;lt;br&amp;gt;&lt;br /&gt;
Pilote ESP32-S3 comme contrôleur principal&amp;lt;br&amp;gt;&lt;br /&gt;
PSRAM : 8MB&amp;lt;br&amp;gt;&lt;br /&gt;
Flash :	8MB&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Images ===&lt;br /&gt;
=== Arduine Mise en route (Setup) ===&lt;br /&gt;
=== Librairies ===&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;Arduino.h&amp;gt; // Inclure la bibliothèque principale Arduino&lt;br /&gt;
 #include &amp;quot;EPD_GUI.h&amp;quot; // Inclure la bibliothèque pour l&amp;#039;écran à encre électronique&lt;br /&gt;
 #include &amp;quot;Pic.h&amp;quot; // Inclure la bibliothèque de fonctions personnalisées&lt;br /&gt;
 #include &amp;quot;FS.h&amp;quot; // Bibliothèque du système de fichiers pour les opérations sur les fichiers&lt;br /&gt;
 #include &amp;quot;SPIFFS.h&amp;quot; // Bibliothèque du système de fichiers SPIFFS pour la lecture et l&amp;#039;écriture de fichiers&lt;br /&gt;
 #include &amp;lt;WiFi.h&amp;gt; // Bibliothèque WiFi pour la création et la gestion des connexions WiFi&lt;br /&gt;
 #include &amp;lt;Ticker.h&amp;gt; // Bibliothèque de chronométrage&lt;br /&gt;
 #include &amp;lt;WebServer.h&amp;gt; // Bibliothèque de serveur Web pour la création d&amp;#039;un serveur HTTP&lt;br /&gt;
&lt;br /&gt;
=== Code Exemples ===&lt;/div&gt;</summary>
		<author><name>144.2.107.134</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1866</id>
		<title>CrowPanel-ESP32-E-Paper-HMI-1.54</title>
		<link rel="alternate" type="text/html" href="https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1866"/>
		<updated>2025-11-23T21:39:44Z</updated>

		<summary type="html">&lt;p&gt;144.2.107.134: /* Caractéristiques */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== E-Paper-HMI-1.54 (Elecrow) ==&lt;br /&gt;
&lt;br /&gt;
=== Liens externes ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_HMI_1.54-inch_Display.html Wiki&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_1.54-inch_Arduino_Tutorial.html Arduino Setup&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/crowpanel-esp32-1-54-e-paper-hmi-display-with-152-152-resolution-black-white-color-driven-by-spi-interface.html Shop&lt;br /&gt;
&lt;br /&gt;
 BLE debugging assistant&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/1-54-inch-152-152-e-paper-display-black-white-e-ink-display-with-spi-communication.html&lt;br /&gt;
&lt;br /&gt;
=== Caractéristiques ===&lt;br /&gt;
&lt;br /&gt;
Driver Chip : &amp;lt;b&amp;gt;SSD1680&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Résolution 152 x 152&amp;lt;br&amp;gt;&lt;br /&gt;
Couleur noir et blanc&amp;lt;br&amp;gt;&lt;br /&gt;
Pilote ESP32-S3 comme contrôleur principal&amp;lt;br&amp;gt;&lt;br /&gt;
PSRAM : 8MB&amp;lt;br&amp;gt;&lt;br /&gt;
Flash :	8MB&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Images ===&lt;br /&gt;
=== Arduine Mise en route (Setup) ===&lt;br /&gt;
=== Librairies ===&lt;br /&gt;
=== Code Exemples ===&lt;/div&gt;</summary>
		<author><name>144.2.107.134</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1865</id>
		<title>CrowPanel-ESP32-E-Paper-HMI-1.54</title>
		<link rel="alternate" type="text/html" href="https://wiki.myows.top/index.php?title=CrowPanel-ESP32-E-Paper-HMI-1.54&amp;diff=1865"/>
		<updated>2025-11-23T21:39:17Z</updated>

		<summary type="html">&lt;p&gt;144.2.107.134: /* Caractéristiques */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== E-Paper-HMI-1.54 (Elecrow) ==&lt;br /&gt;
&lt;br /&gt;
=== Liens externes ===&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_HMI_1.54-inch_Display.html Wiki&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/wiki/CrowPanel_ESP32_E-Paper_1.54-inch_Arduino_Tutorial.html Arduino Setup&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/crowpanel-esp32-1-54-e-paper-hmi-display-with-152-152-resolution-black-white-color-driven-by-spi-interface.html Shop&lt;br /&gt;
&lt;br /&gt;
 BLE debugging assistant&lt;br /&gt;
&lt;br /&gt;
https://www.elecrow.com/1-54-inch-152-152-e-paper-display-black-white-e-ink-display-with-spi-communication.html&lt;br /&gt;
&lt;br /&gt;
=== Caractéristiques ===&lt;br /&gt;
&lt;br /&gt;
Driver Chip : SSD1680&amp;lt;br&amp;gt;&lt;br /&gt;
Résolution 152 x 152&amp;lt;br&amp;gt;&lt;br /&gt;
Couleur noir et blanc&amp;lt;br&amp;gt;&lt;br /&gt;
Pilote ESP32-S3 comme contrôleur principal&amp;lt;br&amp;gt;&lt;br /&gt;
PSRAM : 8MB&amp;lt;br&amp;gt;&lt;br /&gt;
Flash :	8MB&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Images ===&lt;br /&gt;
=== Arduine Mise en route (Setup) ===&lt;br /&gt;
=== Librairies ===&lt;br /&gt;
=== Code Exemples ===&lt;/div&gt;</summary>
		<author><name>144.2.107.134</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.myows.top/index.php?title=Analog_Clock_OLED&amp;diff=1849</id>
		<title>Analog Clock OLED</title>
		<link rel="alternate" type="text/html" href="https://wiki.myows.top/index.php?title=Analog_Clock_OLED&amp;diff=1849"/>
		<updated>2025-11-14T23:47:06Z</updated>

		<summary type="html">&lt;p&gt;144.2.107.134: /* Analog Clock 128X128 OLED 2.2 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Analog Clock 128X128 OLED 1 ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED Grove 1.12&amp;quot; SH1107 ----&lt;br /&gt;
// U8G2_SH1107_PIMAR_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);&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;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
// ---- Cadran ----&lt;br /&gt;
const int CENTER_X = 64;   // centre écran&lt;br /&gt;
const int CENTER_Y = 64;&lt;br /&gt;
const int RADIUS   = 55;   // grand rayon pour 128x128&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse) avec gestion automatique du DST&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  // ---- Calcul des angles ----&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  // ---- Positions des aiguilles ----&lt;br /&gt;
  int hrX = CENTER_X + (RADIUS - 20) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY = CENTER_Y + (RADIUS - 20) * sin((hrAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 10) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 10) * sin((minAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage jour + date en haut ----&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 45, 12, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  // Cadran principal&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  // Chiffres 12-3-6-9&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 5, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 10, CENTER_Y + 4, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 12, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 12, CENTER_Y + 4, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Aiguilles&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, hrX, hrY);   // heures&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, minX, minY); // minutes&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, secX, secY); // secondes&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage digital en bas ----&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB14_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 30, 120, bufferTime);&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;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1; // tm_mon commence à 0&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;    // jour de la semaine (0 = dimanche)&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X128 OLED 2 ===&lt;br /&gt;
&lt;br /&gt;
Ajout de const int Y_OFFSET = 16;&amp;lt;br&amp;gt;&lt;br /&gt;
Application de + Y_OFFSET sur toutes les coordonnées Y (drawStr, drawLine, drawCircle, calcul des aiguilles).&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;pas vraiment, il semble avoir un problème avec l&amp;#039;offset négatif ou positif, on a légèrement un affichage.&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;Wire.h&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED Grove 1.12&amp;quot; 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;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
// ---- Cadran ----&lt;br /&gt;
const int CENTER_X = 64;   // centre écran&lt;br /&gt;
const int CENTER_Y = 64;&lt;br /&gt;
const int RADIUS   = 55;   // grand rayon pour 128x128&lt;br /&gt;
&lt;br /&gt;
// ---- Correction Y pour SH1107 ----&lt;br /&gt;
const int Y_OFFSET = 16;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse) avec gestion automatique du DST&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  // ---- Calcul des angles ----&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  // ---- Positions des aiguilles ----&lt;br /&gt;
  int hrX = CENTER_X + (RADIUS - 20) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY = CENTER_Y + (RADIUS - 20) * sin((hrAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 10) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 10) * sin((minAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage jour + date en haut ----&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 45, 12 + Y_OFFSET, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  // Cadran principal&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y + Y_OFFSET, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  // Chiffres 12-3-6-9&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 5 + Y_OFFSET, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 10, CENTER_Y + 4 + Y_OFFSET, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 12 + Y_OFFSET, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 12, CENTER_Y + 4 + Y_OFFSET, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Aiguilles&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, hrX, hrY);   // heures&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, minX, minY); // minutes&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, secX, secY); // secondes&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage digital en bas ----&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB14_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 30, 120 + Y_OFFSET, bufferTime);&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;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1; // tm_mon commence à 0&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;    // jour de la semaine (0 = dimanche)&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X64 OLED 2.1 Tool ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;Wire.h&amp;gt;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED 128x64 SSD1315 ----&lt;br /&gt;
U8G2_SSD1315_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);&lt;br /&gt;
&lt;br /&gt;
// ---- Variables temps ----&lt;br /&gt;
int hrs = 10, mins = 15, secs = 30; // exemple fixe pour test&lt;br /&gt;
&lt;br /&gt;
// ---- Paramètres écran ----&lt;br /&gt;
const int LARGEUR_ECRAN = 128;&lt;br /&gt;
const int HAUTEUR_ECRAN = 64;&lt;br /&gt;
&lt;br /&gt;
// ---- Marges en % ----&lt;br /&gt;
const float MARGE_HAUT_PCT   = 0.10; // 10% haut&lt;br /&gt;
const float MARGE_BAS_PCT    = 0.10; // 10% bas&lt;br /&gt;
const float MARGE_GAUCHE_PCT = 0.10; // 10% gauche&lt;br /&gt;
const float MARGE_DROITE_PCT = 0.10; // 10% droite&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  // ---- Calcul des marges en pixels ----&lt;br /&gt;
  int margeHaut   = (int)(HAUTEUR_ECRAN * MARGE_HAUT_PCT);&lt;br /&gt;
  int margeBas    = (int)(HAUTEUR_ECRAN * MARGE_BAS_PCT);&lt;br /&gt;
  int margeGauche = (int)(LARGEUR_ECRAN * MARGE_GAUCHE_PCT);&lt;br /&gt;
  int margeDroite = (int)(LARGEUR_ECRAN * MARGE_DROITE_PCT);&lt;br /&gt;
&lt;br /&gt;
  // ---- Dimensions utiles ----&lt;br /&gt;
  int largeurUtile = LARGEUR_ECRAN - (margeGauche + margeDroite);&lt;br /&gt;
  int hauteurUtile = HAUTEUR_ECRAN - (margeHaut + margeBas);&lt;br /&gt;
&lt;br /&gt;
  // ---- Centre du cercle ----&lt;br /&gt;
  const int CENTER_X = margeGauche + largeurUtile / 2;&lt;br /&gt;
  const int CENTER_Y = margeHaut + hauteurUtile / 2;&lt;br /&gt;
&lt;br /&gt;
  // ---- Rayon adapté (prendre le plus petit côté utile / 2) ----&lt;br /&gt;
  const int RADIUS = min(largeurUtile, hauteurUtile) / 2 - 5;&lt;br /&gt;
&lt;br /&gt;
  // ---- Calcul des angles ----&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  // ---- Positions des aiguilles ----&lt;br /&gt;
  int hrX  = CENTER_X + (RADIUS - 8) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY  = CENTER_Y + (RADIUS - 8) * sin((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 4) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 4) * sin((minAngle - 90) * PI / 180);&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // Cercle principal&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  // Chiffres 12-3-6-9&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 2, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 6, CENTER_Y + 4, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 10, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 10, CENTER_Y + 4, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Aiguilles&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, hrX, hrY);&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, minX, minY);&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, secX, secY);&lt;br /&gt;
&lt;br /&gt;
  u8g2.sendBuffer();&lt;br /&gt;
  delay(1000);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X128 OLED 2.2 ===&lt;br /&gt;
&lt;br /&gt;
Code pour &amp;lt;b&amp;gt;SH1107&amp;lt;/b&amp;gt; avec offset&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED 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;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
&lt;br /&gt;
// ---- Paramètres écran ----&lt;br /&gt;
const int LARGEUR_ECRAN = 128;&lt;br /&gt;
const int HAUTEUR_ECRAN = 128;&lt;br /&gt;
&lt;br /&gt;
// ---- Offset spécifique SH1107 ----&lt;br /&gt;
const int Y_OFFSET = 16; // décalage vertical typique&lt;br /&gt;
&lt;br /&gt;
// ---- Marges en % ----&lt;br /&gt;
const float MARGE_HAUT_PCT   = 0.10; // 10% haut&lt;br /&gt;
const float MARGE_BAS_PCT    = 0.10; // 10% bas&lt;br /&gt;
const float MARGE_GAUCHE_PCT = 0.10; // 10% gauche&lt;br /&gt;
const float MARGE_DROITE_PCT = 0.10; // 10% droite&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse)&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  // ---- Calcul des marges en pixels ----&lt;br /&gt;
  int margeHaut   = (int)(HAUTEUR_ECRAN * MARGE_HAUT_PCT);&lt;br /&gt;
  int margeBas    = (int)(HAUTEUR_ECRAN * MARGE_BAS_PCT);&lt;br /&gt;
  int margeGauche = (int)(LARGEUR_ECRAN * MARGE_GAUCHE_PCT);&lt;br /&gt;
  int margeDroite = (int)(LARGEUR_ECRAN * MARGE_DROITE_PCT);&lt;br /&gt;
&lt;br /&gt;
  // ---- Dimensions utiles ----&lt;br /&gt;
  int largeurUtile = LARGEUR_ECRAN - (margeGauche + margeDroite);&lt;br /&gt;
  int hauteurUtile = HAUTEUR_ECRAN - (margeHaut + margeBas);&lt;br /&gt;
&lt;br /&gt;
  // ---- Centre du cercle (avec offset) ----&lt;br /&gt;
  const int CENTER_X = margeGauche + largeurUtile / 2;&lt;br /&gt;
  const int CENTER_Y = margeHaut + hauteurUtile / 2 + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  // ---- Rayon adapté ----&lt;br /&gt;
  const int RADIUS = min(largeurUtile, hauteurUtile) / 2 - 5;&lt;br /&gt;
&lt;br /&gt;
  // ---- Calcul des angles ----&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  // ---- Positions des aiguilles ----&lt;br /&gt;
  int hrX  = CENTER_X + (RADIUS - 20) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY  = CENTER_Y + (RADIUS - 20) * sin((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 10) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 10) * sin((minAngle - 90) * PI / 180);&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // Cercle principal&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  // Chiffres 12-3-6-9&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 2, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 6, CENTER_Y + 4, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 12, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 12, CENTER_Y + 4, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Aiguilles&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, hrX, hrY);&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, minX, minY);&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, secX, secY);&lt;br /&gt;
&lt;br /&gt;
  u8g2.sendBuffer();&lt;br /&gt;
  delay(1000);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%02d:%02d:%02d\n&amp;quot;, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X128 OLED 3 ===&lt;br /&gt;
&lt;br /&gt;
Si tu utilises SH1107, laisse #define SCREEN_SH1107 actif → offset = 16.&amp;lt;br&amp;gt;&lt;br /&gt;
Si tu passes à SSD1327, commente SCREEN_SH1107 et décommente SCREEN_SSD1327 → offset = 0.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- Sélection écran ----&lt;br /&gt;
// Décommente la ligne correspondant à ton écran&lt;br /&gt;
#define SCREEN_SH1107&lt;br /&gt;
// #define SCREEN_SSD1327&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED Grove 1.12&amp;quot; SH1107 ----&lt;br /&gt;
// (Même constructeur pour SSD1327, mais offset différent)&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;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
// ---- Cadran ----&lt;br /&gt;
const int CENTER_X = 64;   // centre écran&lt;br /&gt;
const int CENTER_Y = 64;&lt;br /&gt;
const int RADIUS   = 55;   // grand rayon pour 128x128&lt;br /&gt;
&lt;br /&gt;
// ---- Correction Y selon écran ----&lt;br /&gt;
int Y_OFFSET = 0;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Choix offset selon écran&lt;br /&gt;
  #ifdef SCREEN_SH1107&lt;br /&gt;
    Y_OFFSET = 16;   // correction typique pour SH1107&lt;br /&gt;
  #endif&lt;br /&gt;
&lt;br /&gt;
  #ifdef SCREEN_SSD1327&lt;br /&gt;
    Y_OFFSET = 0;    // pas besoin de correction&lt;br /&gt;
  #endif&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse) avec gestion automatique du DST&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  // ---- Calcul des angles ----&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  // ---- Positions des aiguilles ----&lt;br /&gt;
  int hrX = CENTER_X + (RADIUS - 20) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY = CENTER_Y + (RADIUS - 20) * sin((hrAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 10) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 10) * sin((minAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage jour + date en haut ----&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 45, 12 + Y_OFFSET, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  // Cadran principal&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y + Y_OFFSET, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  // Chiffres 12-3-6-9&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 5 + Y_OFFSET, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 10, CENTER_Y + 4 + Y_OFFSET, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 12 + Y_OFFSET, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 12, CENTER_Y + 4 + Y_OFFSET, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Aiguilles&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, hrX, hrY);   // heures&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, minX, minY); // minutes&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, secX, secY); // secondes&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage digital en bas ----&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB14_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 30, 120 + Y_OFFSET, bufferTime);&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;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1; // tm_mon commence à 0&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;    // jour de la semaine (0 = dimanche)&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X128 OLED 4 ===&lt;br /&gt;
&lt;br /&gt;
Au démarrage → attend 10 secondes une commande série.&amp;lt;br&amp;gt;&lt;br /&gt;
Si tu tapes t → mode test offset (lignes horizontales).&amp;lt;br&amp;gt;&lt;br /&gt;
Si tu tapes h → mode horloge.&amp;lt;br&amp;gt;&lt;br /&gt;
Si rien n’est tapé → après 10 secondes → mode horloge par défaut.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- Sélection écran ----&lt;br /&gt;
#define SCREEN_SH1107&lt;br /&gt;
// #define SCREEN_SSD1327&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED Grove 1.12&amp;quot; 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;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
// ---- Cadran ----&lt;br /&gt;
const int CENTER_X = 64;&lt;br /&gt;
const int CENTER_Y = 64;&lt;br /&gt;
const int RADIUS   = 55;&lt;br /&gt;
&lt;br /&gt;
// ---- Correction Y selon écran ----&lt;br /&gt;
int Y_OFFSET = 0;&lt;br /&gt;
&lt;br /&gt;
// ---- Mode ----&lt;br /&gt;
bool modeTest = false;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Choix offset selon écran&lt;br /&gt;
  #ifdef SCREEN_SH1107&lt;br /&gt;
    Y_OFFSET = 16;&lt;br /&gt;
  #endif&lt;br /&gt;
  #ifdef SCREEN_SSD1327&lt;br /&gt;
    Y_OFFSET = 0;&lt;br /&gt;
  #endif&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse)&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
&lt;br /&gt;
  // ---- Attente commande série pendant 10s ----&lt;br /&gt;
  Serial.println(&amp;quot;Tapez &amp;#039;t&amp;#039; pour mode test offset, &amp;#039;h&amp;#039; pour horloge. Sinon horloge par défaut après 10s.&amp;quot;);&lt;br /&gt;
  unsigned long start = millis();&lt;br /&gt;
  while (millis() - start &amp;lt; 10000) {&lt;br /&gt;
    if (Serial.available()) {&lt;br /&gt;
      char c = Serial.read();&lt;br /&gt;
      if (c == &amp;#039;t&amp;#039;) {&lt;br /&gt;
        modeTest = true;&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
      if (c == &amp;#039;h&amp;#039;) {&lt;br /&gt;
        modeTest = false;&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  if (modeTest) {&lt;br /&gt;
    testOffset();&lt;br /&gt;
  } else {&lt;br /&gt;
    afficherHorloge();&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ---- Fonction horloge ----&lt;br /&gt;
void afficherHorloge() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  int hrX = CENTER_X + (RADIUS - 20) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY = CENTER_Y + (RADIUS - 20) * sin((hrAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 10) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 10) * sin((minAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 45, 12 + Y_OFFSET, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y + Y_OFFSET, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 5 + Y_OFFSET, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 10, CENTER_Y + 4 + Y_OFFSET, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 12 + Y_OFFSET, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 12, CENTER_Y + 4 + Y_OFFSET, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, hrX, hrY);&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, minX, minY);&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, secX, secY);&lt;br /&gt;
&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB14_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 30, 120 + Y_OFFSET, bufferTime);&lt;br /&gt;
&lt;br /&gt;
  u8g2.sendBuffer();&lt;br /&gt;
  delay(1000);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ---- Fonction utilitaire test offset ----&lt;br /&gt;
void testOffset() {&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
&lt;br /&gt;
  u8g2.drawLine(0, CENTER_Y, 128, CENTER_Y);             // sans offset&lt;br /&gt;
  u8g2.drawLine(0, CENTER_Y + Y_OFFSET, 128, CENTER_Y + Y_OFFSET); // avec offset&lt;br /&gt;
&lt;br /&gt;
  u8g2.drawStr(10, CENTER_Y - 5, &amp;quot;Sans offset&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(10, CENTER_Y + Y_OFFSET - 5, &amp;quot;Avec offset&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  u8g2.sendBuffer();&lt;br /&gt;
  delay(1000);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ---- Récupération heure locale ----&lt;br /&gt;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1;&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X128 OLED 5 Tool ===&lt;br /&gt;
&lt;br /&gt;
Tu verras deux lignes horizontales sur ton écran :&amp;lt;br&amp;gt;&lt;br /&gt;
Une ligne au centre (sans correction).&amp;lt;br&amp;gt;&lt;br /&gt;
Une ligne décalée de Y_OFFSET pixels (avec correction).&amp;lt;br&amp;gt;&lt;br /&gt;
Les textes « Sans offset » et « Avec offset » t’indiquent quelle ligne correspond à quoi.&amp;lt;br&amp;gt;&lt;br /&gt;
Si la ligne corrigée est bien alignée avec ce que tu attends, tu sais que ton Y_OFFSET est correct.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;Wire.h&amp;gt;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- Sélection écran ----&lt;br /&gt;
#define SCREEN_SH1107&lt;br /&gt;
// #define SCREEN_SSD1327&lt;br /&gt;
&lt;br /&gt;
// ---- OLED Grove 1.12&amp;quot; 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;
// ---- Correction Y selon écran ----&lt;br /&gt;
int Y_OFFSET = 0;&lt;br /&gt;
&lt;br /&gt;
// ---- Centre écran ----&lt;br /&gt;
const int CENTER_X = 64;&lt;br /&gt;
const int CENTER_Y = 64;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Choix offset selon écran&lt;br /&gt;
  #ifdef SCREEN_SH1107&lt;br /&gt;
    Y_OFFSET = 16;   // correction typique pour SH1107&lt;br /&gt;
  #endif&lt;br /&gt;
  #ifdef SCREEN_SSD1327&lt;br /&gt;
    Y_OFFSET = 0;    // pas besoin de correction&lt;br /&gt;
  #endif&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
&lt;br /&gt;
  // Ligne horizontale sans offset&lt;br /&gt;
  u8g2.drawLine(0, CENTER_Y, 128, CENTER_Y);&lt;br /&gt;
  u8g2.drawStr(10, CENTER_Y - 5, &amp;quot;Sans offset&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Ligne horizontale avec offset&lt;br /&gt;
  u8g2.drawLine(0, CENTER_Y + Y_OFFSET, 128, CENTER_Y + Y_OFFSET);&lt;br /&gt;
  u8g2.drawStr(10, CENTER_Y + Y_OFFSET - 5, &amp;quot;Avec offset&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  u8g2.sendBuffer();&lt;br /&gt;
&lt;br /&gt;
  delay(1000);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128×64 OLED 6 ===&lt;br /&gt;
&lt;br /&gt;
Centre déplacé à (64, 32) pour un écran 128×64.&amp;lt;br&amp;gt;&lt;br /&gt;
Rayon réduit à 28 pour que le cadran tienne bien.&amp;lt;br&amp;gt;&lt;br /&gt;
Positions des textes ajustées (y=10 pour la date, y=58 pour l’heure digitale).&amp;lt;br&amp;gt;&lt;br /&gt;
Constructeur U8g2 changé pour SSD1308/SSD1315.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED 128x64 SSD1308/SSD1315 ----&lt;br /&gt;
// Choisis le constructeur selon ton écran&lt;br /&gt;
U8G2_SSD1315_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);&lt;br /&gt;
&lt;br /&gt;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
// ---- Cadran ----&lt;br /&gt;
const int CENTER_X = 64;   // centre écran&lt;br /&gt;
const int CENTER_Y = 32;   // moitié de 64&lt;br /&gt;
const int RADIUS   = 28;   // adapté à la hauteur&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse)&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  // ---- Calcul des angles ----&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  // ---- Positions des aiguilles ----&lt;br /&gt;
  int hrX = CENTER_X + (RADIUS - 8) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY = CENTER_Y + (RADIUS - 8) * sin((hrAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 4) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 4) * sin((minAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage jour + date en haut ----&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(5, 10, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  // Cadran principal&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  // Chiffres 12-3-6-9&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 2, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 6, CENTER_Y + 4, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 10, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 10, CENTER_Y + 4, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Aiguilles&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, hrX, hrY);&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, minX, minY);&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, secX, secY);&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage digital en bas ----&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB14_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 30, 58, bufferTime);&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;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1;&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128×64 OLED 7 ===&lt;br /&gt;
&lt;br /&gt;
💻 Code compact (SSD1308/SSD1315, 128×64)&lt;br /&gt;
&lt;br /&gt;
Dans cette version, on supprime le cadran analogique et on affiche uniquement la date en haut et l’heure digitale bien centrée en bas. Cela exploite mieux la petite hauteur de l’écran.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Date + jour en haut (petite police).&amp;lt;br&amp;gt;&lt;br /&gt;
Heure digitale en bas, bien grande et centrée (u8g2_font_ncenB24_tr).&amp;lt;br&amp;gt;&lt;br /&gt;
Pas de cadran analogique → affichage clair et lisible sur un petit écran.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;ceci fonctionne mais le jours est superposé avec l&amp;#039;heure&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;Wire.h&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED 128x64 SSD1308/SSD1315 ----&lt;br /&gt;
// Choisis le constructeur selon ton écran&lt;br /&gt;
U8G2_SSD1315_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);&lt;br /&gt;
&lt;br /&gt;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse)&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // Affichage jour + date en haut&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(5, 12, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  // Affichage digital centré en bas&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB24_tr); // grande police pour l&amp;#039;heure&lt;br /&gt;
  u8g2.drawStr(20, 55, bufferTime);&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;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1;&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X64 OLED 7.1 Tool ===&lt;br /&gt;
&lt;br /&gt;
Calcul de la hauteur et largeur d&amp;#039;un texte avec une sortie du résultat sur le &amp;lt;b&amp;gt;port série&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Police 6x13 -&amp;gt; Hauteur=13 px, Largeur max char=6 px, &amp;lt;br&amp;gt;&lt;br /&gt;
Largeur &amp;#039;12:34:56&amp;#039;=48 px, Largeur &amp;#039;Vendredi, 14/11/2025&amp;#039;=114 px&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Police ncenB14 -&amp;gt; Hauteur=14 px, Largeur max char=14 px, &amp;lt;br&amp;gt;&lt;br /&gt;
Largeur &amp;#039;12:34:56&amp;#039;=84 px, Largeur &amp;#039;Vendredi, 14/11/2025&amp;#039;=168 px&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Police ncenB18 -&amp;gt; Hauteur=18 px, Largeur max char=18 px, &amp;lt;br&amp;gt;&lt;br /&gt;
Largeur &amp;#039;12:34:56&amp;#039;=108 px, Largeur &amp;#039;Vendredi, 14/11/2025&amp;#039;=216 px&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Police ncenB24 -&amp;gt; Hauteur=24 px, Largeur max char=24 px, &amp;lt;br&amp;gt;&lt;br /&gt;
Largeur &amp;#039;12:34:56&amp;#039;=144 px, Largeur &amp;#039;Vendredi, 14/11/2025&amp;#039;=288 px&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
🖥️ Exemple de code de test (heure + date)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;Wire.h&amp;gt;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
U8G2_SSD1315_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
&lt;br /&gt;
  // Test avec plusieurs polices&lt;br /&gt;
  testFont(u8g2_font_6x13_tr, &amp;quot;6x13&amp;quot;);&lt;br /&gt;
  testFont(u8g2_font_ncenB14_tr, &amp;quot;ncenB14&amp;quot;);&lt;br /&gt;
  testFont(u8g2_font_ncenB18_tr, &amp;quot;ncenB18&amp;quot;);&lt;br /&gt;
  testFont(u8g2_font_ncenB24_tr, &amp;quot;ncenB24&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  // rien à faire en boucle&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void testFont(const uint8_t* font, const char* name) {&lt;br /&gt;
  u8g2.setFont(font);&lt;br /&gt;
&lt;br /&gt;
  // Hauteur et largeur max d’un caractère&lt;br /&gt;
  int h = u8g2.getMaxCharHeight();&lt;br /&gt;
  int wChar = u8g2.getMaxCharWidth();&lt;br /&gt;
&lt;br /&gt;
  // Largeur d’un exemple d’heure&lt;br /&gt;
  int wTime = u8g2.getStrWidth(&amp;quot;12:34:56&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Largeur d’un exemple de jour + date&lt;br /&gt;
  int wDate = u8g2.getStrWidth(&amp;quot;Vendredi, 14/11/2025&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;Police %s -&amp;gt; Hauteur=%d px, Largeur max char=%d px, Largeur &amp;#039;12:34:56&amp;#039;=%d px, Largeur &amp;#039;Vendredi, 14/11/2025&amp;#039;=%d px\n&amp;quot;,&lt;br /&gt;
                name, h, wChar, wTime, wDate);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X64 OLED 7.2 ===&lt;br /&gt;
&lt;br /&gt;
Les marges hautes et basses en % de la hauteur de l’écran.&amp;lt;br&amp;gt;&lt;br /&gt;
Le choix automatique de la police pour l’heure en fonction de l’espace disponible.&amp;lt;br&amp;gt;&lt;br /&gt;
Le centrage horizontal de l’heure.&amp;lt;br&amp;gt;&lt;br /&gt;
La date en haut avec une police adaptée.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED 128x64 SSD1308/SSD1315 ----&lt;br /&gt;
U8G2_SSD1315_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);&lt;br /&gt;
&lt;br /&gt;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
// ---- Paramètres écran ----&lt;br /&gt;
const int LARGEUR_ECRAN = 128;&lt;br /&gt;
const int HAUTEUR_ECRAN = 64;&lt;br /&gt;
&lt;br /&gt;
// ---- Marges en % ----&lt;br /&gt;
const float MARGE_HAUT_PCT = 0.10; // 10%&lt;br /&gt;
const float MARGE_BAS_PCT  = 0.10; // 10%&lt;br /&gt;
&lt;br /&gt;
// ---- Polices disponibles pour l&amp;#039;heure ----&lt;br /&gt;
const uint8_t* FONT_SMALL  = u8g2_font_ncenB14_tr; // ~14 px&lt;br /&gt;
const uint8_t* FONT_MEDIUM = u8g2_font_ncenB18_tr; // ~18 px&lt;br /&gt;
const uint8_t* FONT_LARGE  = u8g2_font_ncenB24_tr; // ~24 px&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse)&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // Calcul des marges en pixels&lt;br /&gt;
  int margeHaut = (int)(HAUTEUR_ECRAN * MARGE_HAUT_PCT);&lt;br /&gt;
  int margeBas  = (int)(HAUTEUR_ECRAN * MARGE_BAS_PCT);&lt;br /&gt;
  int hauteurUtile = HAUTEUR_ECRAN - (margeHaut + margeBas);&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage jour + date en haut ----&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(5, margeHaut + 12, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  // ---- Choix automatique de la police pour l&amp;#039;heure ----&lt;br /&gt;
  const uint8_t* fontChoisie;&lt;br /&gt;
  if (hauteurUtile &amp;gt;= 24) {&lt;br /&gt;
    fontChoisie = FONT_LARGE;   // assez de place pour 24 px&lt;br /&gt;
  } else if (hauteurUtile &amp;gt;= 18) {&lt;br /&gt;
    fontChoisie = FONT_MEDIUM;  // assez de place pour 18 px&lt;br /&gt;
  } else {&lt;br /&gt;
    fontChoisie = FONT_SMALL;   // sinon police plus petite&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage digital centré en bas ----&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(fontChoisie);&lt;br /&gt;
&lt;br /&gt;
  // Centrage horizontal&lt;br /&gt;
  int largeur = u8g2.getStrWidth(bufferTime);&lt;br /&gt;
  int x = (LARGEUR_ECRAN - largeur) / 2;&lt;br /&gt;
&lt;br /&gt;
  // Ligne de base juste avant la marge basse&lt;br /&gt;
  int y = HAUTEUR_ECRAN - margeBas;&lt;br /&gt;
&lt;br /&gt;
  u8g2.drawStr(x, y, bufferTime);&lt;br /&gt;
&lt;br /&gt;
  u8g2.sendBuffer();&lt;br /&gt;
  delay(1000);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1;&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X64 OLED 8 ===&lt;br /&gt;
&lt;br /&gt;
💻 Code : seulement le cadran analogique&amp;lt;br&amp;gt; fonctionne mais illisible on dirait 2 ovales ! mais on peut voir les aguilles &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Un cadran analogique avec les chiffres 12‑3‑6‑9.&amp;lt;br&amp;gt;&lt;br /&gt;
Trois aiguilles (heures, minutes, secondes).&amp;lt;br&amp;gt;&lt;br /&gt;
Pas de date ni d’heure digitale → affichage épuré.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED 128x64 SSD1308/SSD1315 ----&lt;br /&gt;
U8G2_SSD1315_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);&lt;br /&gt;
&lt;br /&gt;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
&lt;br /&gt;
// ---- Cadran ----&lt;br /&gt;
const int CENTER_X = 64;   // centre écran&lt;br /&gt;
const int CENTER_Y = 32;   // moitié de 64&lt;br /&gt;
const int RADIUS   = 28;   // adapté à la hauteur&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse)&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  // ---- Calcul des angles ----&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  // ---- Positions des aiguilles ----&lt;br /&gt;
  int hrX = CENTER_X + (RADIUS - 8) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY = CENTER_Y + (RADIUS - 8) * sin((hrAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 4) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 4) * sin((minAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // Cadran principal&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  // Chiffres 12-3-6-9&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 2, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 6, CENTER_Y + 4, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 10, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 10, CENTER_Y + 4, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Aiguilles&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, hrX, hrY);   // heures&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, minX, minY); // minutes&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, secX, secY); // secondes&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;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%02d:%02d:%02d\n&amp;quot;, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>144.2.107.134</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.myows.top/index.php?title=Analog_Clock_OLED&amp;diff=1848</id>
		<title>Analog Clock OLED</title>
		<link rel="alternate" type="text/html" href="https://wiki.myows.top/index.php?title=Analog_Clock_OLED&amp;diff=1848"/>
		<updated>2025-11-14T23:45:34Z</updated>

		<summary type="html">&lt;p&gt;144.2.107.134: /* Analog Clock 128X128 OLED 2.1 Tool */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Analog Clock 128X128 OLED 1 ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED Grove 1.12&amp;quot; SH1107 ----&lt;br /&gt;
// U8G2_SH1107_PIMAR_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);&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;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
// ---- Cadran ----&lt;br /&gt;
const int CENTER_X = 64;   // centre écran&lt;br /&gt;
const int CENTER_Y = 64;&lt;br /&gt;
const int RADIUS   = 55;   // grand rayon pour 128x128&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse) avec gestion automatique du DST&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  // ---- Calcul des angles ----&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  // ---- Positions des aiguilles ----&lt;br /&gt;
  int hrX = CENTER_X + (RADIUS - 20) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY = CENTER_Y + (RADIUS - 20) * sin((hrAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 10) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 10) * sin((minAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage jour + date en haut ----&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 45, 12, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  // Cadran principal&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  // Chiffres 12-3-6-9&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 5, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 10, CENTER_Y + 4, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 12, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 12, CENTER_Y + 4, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Aiguilles&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, hrX, hrY);   // heures&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, minX, minY); // minutes&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, secX, secY); // secondes&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage digital en bas ----&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB14_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 30, 120, bufferTime);&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;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1; // tm_mon commence à 0&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;    // jour de la semaine (0 = dimanche)&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X128 OLED 2 ===&lt;br /&gt;
&lt;br /&gt;
Ajout de const int Y_OFFSET = 16;&amp;lt;br&amp;gt;&lt;br /&gt;
Application de + Y_OFFSET sur toutes les coordonnées Y (drawStr, drawLine, drawCircle, calcul des aiguilles).&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;pas vraiment, il semble avoir un problème avec l&amp;#039;offset négatif ou positif, on a légèrement un affichage.&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;Wire.h&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED Grove 1.12&amp;quot; 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;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
// ---- Cadran ----&lt;br /&gt;
const int CENTER_X = 64;   // centre écran&lt;br /&gt;
const int CENTER_Y = 64;&lt;br /&gt;
const int RADIUS   = 55;   // grand rayon pour 128x128&lt;br /&gt;
&lt;br /&gt;
// ---- Correction Y pour SH1107 ----&lt;br /&gt;
const int Y_OFFSET = 16;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse) avec gestion automatique du DST&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  // ---- Calcul des angles ----&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  // ---- Positions des aiguilles ----&lt;br /&gt;
  int hrX = CENTER_X + (RADIUS - 20) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY = CENTER_Y + (RADIUS - 20) * sin((hrAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 10) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 10) * sin((minAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage jour + date en haut ----&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 45, 12 + Y_OFFSET, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  // Cadran principal&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y + Y_OFFSET, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  // Chiffres 12-3-6-9&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 5 + Y_OFFSET, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 10, CENTER_Y + 4 + Y_OFFSET, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 12 + Y_OFFSET, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 12, CENTER_Y + 4 + Y_OFFSET, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Aiguilles&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, hrX, hrY);   // heures&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, minX, minY); // minutes&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, secX, secY); // secondes&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage digital en bas ----&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB14_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 30, 120 + Y_OFFSET, bufferTime);&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;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1; // tm_mon commence à 0&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;    // jour de la semaine (0 = dimanche)&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X64 OLED 2.1 Tool ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;Wire.h&amp;gt;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED 128x64 SSD1315 ----&lt;br /&gt;
U8G2_SSD1315_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);&lt;br /&gt;
&lt;br /&gt;
// ---- Variables temps ----&lt;br /&gt;
int hrs = 10, mins = 15, secs = 30; // exemple fixe pour test&lt;br /&gt;
&lt;br /&gt;
// ---- Paramètres écran ----&lt;br /&gt;
const int LARGEUR_ECRAN = 128;&lt;br /&gt;
const int HAUTEUR_ECRAN = 64;&lt;br /&gt;
&lt;br /&gt;
// ---- Marges en % ----&lt;br /&gt;
const float MARGE_HAUT_PCT   = 0.10; // 10% haut&lt;br /&gt;
const float MARGE_BAS_PCT    = 0.10; // 10% bas&lt;br /&gt;
const float MARGE_GAUCHE_PCT = 0.10; // 10% gauche&lt;br /&gt;
const float MARGE_DROITE_PCT = 0.10; // 10% droite&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  // ---- Calcul des marges en pixels ----&lt;br /&gt;
  int margeHaut   = (int)(HAUTEUR_ECRAN * MARGE_HAUT_PCT);&lt;br /&gt;
  int margeBas    = (int)(HAUTEUR_ECRAN * MARGE_BAS_PCT);&lt;br /&gt;
  int margeGauche = (int)(LARGEUR_ECRAN * MARGE_GAUCHE_PCT);&lt;br /&gt;
  int margeDroite = (int)(LARGEUR_ECRAN * MARGE_DROITE_PCT);&lt;br /&gt;
&lt;br /&gt;
  // ---- Dimensions utiles ----&lt;br /&gt;
  int largeurUtile = LARGEUR_ECRAN - (margeGauche + margeDroite);&lt;br /&gt;
  int hauteurUtile = HAUTEUR_ECRAN - (margeHaut + margeBas);&lt;br /&gt;
&lt;br /&gt;
  // ---- Centre du cercle ----&lt;br /&gt;
  const int CENTER_X = margeGauche + largeurUtile / 2;&lt;br /&gt;
  const int CENTER_Y = margeHaut + hauteurUtile / 2;&lt;br /&gt;
&lt;br /&gt;
  // ---- Rayon adapté (prendre le plus petit côté utile / 2) ----&lt;br /&gt;
  const int RADIUS = min(largeurUtile, hauteurUtile) / 2 - 5;&lt;br /&gt;
&lt;br /&gt;
  // ---- Calcul des angles ----&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  // ---- Positions des aiguilles ----&lt;br /&gt;
  int hrX  = CENTER_X + (RADIUS - 8) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY  = CENTER_Y + (RADIUS - 8) * sin((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 4) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 4) * sin((minAngle - 90) * PI / 180);&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // Cercle principal&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  // Chiffres 12-3-6-9&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 2, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 6, CENTER_Y + 4, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 10, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 10, CENTER_Y + 4, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Aiguilles&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, hrX, hrY);&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, minX, minY);&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, secX, secY);&lt;br /&gt;
&lt;br /&gt;
  u8g2.sendBuffer();&lt;br /&gt;
  delay(1000);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X128 OLED 2.2 ===&lt;br /&gt;
&lt;br /&gt;
Code pour SH1107 avec offset&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED 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;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
&lt;br /&gt;
// ---- Paramètres écran ----&lt;br /&gt;
const int LARGEUR_ECRAN = 128;&lt;br /&gt;
const int HAUTEUR_ECRAN = 128;&lt;br /&gt;
&lt;br /&gt;
// ---- Offset spécifique SH1107 ----&lt;br /&gt;
const int Y_OFFSET = 16; // décalage vertical typique&lt;br /&gt;
&lt;br /&gt;
// ---- Marges en % ----&lt;br /&gt;
const float MARGE_HAUT_PCT   = 0.10; // 10% haut&lt;br /&gt;
const float MARGE_BAS_PCT    = 0.10; // 10% bas&lt;br /&gt;
const float MARGE_GAUCHE_PCT = 0.10; // 10% gauche&lt;br /&gt;
const float MARGE_DROITE_PCT = 0.10; // 10% droite&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse)&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  // ---- Calcul des marges en pixels ----&lt;br /&gt;
  int margeHaut   = (int)(HAUTEUR_ECRAN * MARGE_HAUT_PCT);&lt;br /&gt;
  int margeBas    = (int)(HAUTEUR_ECRAN * MARGE_BAS_PCT);&lt;br /&gt;
  int margeGauche = (int)(LARGEUR_ECRAN * MARGE_GAUCHE_PCT);&lt;br /&gt;
  int margeDroite = (int)(LARGEUR_ECRAN * MARGE_DROITE_PCT);&lt;br /&gt;
&lt;br /&gt;
  // ---- Dimensions utiles ----&lt;br /&gt;
  int largeurUtile = LARGEUR_ECRAN - (margeGauche + margeDroite);&lt;br /&gt;
  int hauteurUtile = HAUTEUR_ECRAN - (margeHaut + margeBas);&lt;br /&gt;
&lt;br /&gt;
  // ---- Centre du cercle (avec offset) ----&lt;br /&gt;
  const int CENTER_X = margeGauche + largeurUtile / 2;&lt;br /&gt;
  const int CENTER_Y = margeHaut + hauteurUtile / 2 + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  // ---- Rayon adapté ----&lt;br /&gt;
  const int RADIUS = min(largeurUtile, hauteurUtile) / 2 - 5;&lt;br /&gt;
&lt;br /&gt;
  // ---- Calcul des angles ----&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  // ---- Positions des aiguilles ----&lt;br /&gt;
  int hrX  = CENTER_X + (RADIUS - 20) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY  = CENTER_Y + (RADIUS - 20) * sin((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 10) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 10) * sin((minAngle - 90) * PI / 180);&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // Cercle principal&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  // Chiffres 12-3-6-9&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 2, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 6, CENTER_Y + 4, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 12, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 12, CENTER_Y + 4, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Aiguilles&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, hrX, hrY);&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, minX, minY);&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, secX, secY);&lt;br /&gt;
&lt;br /&gt;
  u8g2.sendBuffer();&lt;br /&gt;
  delay(1000);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%02d:%02d:%02d\n&amp;quot;, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X128 OLED 3 ===&lt;br /&gt;
&lt;br /&gt;
Si tu utilises SH1107, laisse #define SCREEN_SH1107 actif → offset = 16.&amp;lt;br&amp;gt;&lt;br /&gt;
Si tu passes à SSD1327, commente SCREEN_SH1107 et décommente SCREEN_SSD1327 → offset = 0.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- Sélection écran ----&lt;br /&gt;
// Décommente la ligne correspondant à ton écran&lt;br /&gt;
#define SCREEN_SH1107&lt;br /&gt;
// #define SCREEN_SSD1327&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED Grove 1.12&amp;quot; SH1107 ----&lt;br /&gt;
// (Même constructeur pour SSD1327, mais offset différent)&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;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
// ---- Cadran ----&lt;br /&gt;
const int CENTER_X = 64;   // centre écran&lt;br /&gt;
const int CENTER_Y = 64;&lt;br /&gt;
const int RADIUS   = 55;   // grand rayon pour 128x128&lt;br /&gt;
&lt;br /&gt;
// ---- Correction Y selon écran ----&lt;br /&gt;
int Y_OFFSET = 0;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Choix offset selon écran&lt;br /&gt;
  #ifdef SCREEN_SH1107&lt;br /&gt;
    Y_OFFSET = 16;   // correction typique pour SH1107&lt;br /&gt;
  #endif&lt;br /&gt;
&lt;br /&gt;
  #ifdef SCREEN_SSD1327&lt;br /&gt;
    Y_OFFSET = 0;    // pas besoin de correction&lt;br /&gt;
  #endif&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse) avec gestion automatique du DST&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  // ---- Calcul des angles ----&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  // ---- Positions des aiguilles ----&lt;br /&gt;
  int hrX = CENTER_X + (RADIUS - 20) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY = CENTER_Y + (RADIUS - 20) * sin((hrAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 10) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 10) * sin((minAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage jour + date en haut ----&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 45, 12 + Y_OFFSET, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  // Cadran principal&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y + Y_OFFSET, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  // Chiffres 12-3-6-9&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 5 + Y_OFFSET, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 10, CENTER_Y + 4 + Y_OFFSET, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 12 + Y_OFFSET, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 12, CENTER_Y + 4 + Y_OFFSET, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Aiguilles&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, hrX, hrY);   // heures&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, minX, minY); // minutes&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, secX, secY); // secondes&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage digital en bas ----&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB14_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 30, 120 + Y_OFFSET, bufferTime);&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;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1; // tm_mon commence à 0&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;    // jour de la semaine (0 = dimanche)&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X128 OLED 4 ===&lt;br /&gt;
&lt;br /&gt;
Au démarrage → attend 10 secondes une commande série.&amp;lt;br&amp;gt;&lt;br /&gt;
Si tu tapes t → mode test offset (lignes horizontales).&amp;lt;br&amp;gt;&lt;br /&gt;
Si tu tapes h → mode horloge.&amp;lt;br&amp;gt;&lt;br /&gt;
Si rien n’est tapé → après 10 secondes → mode horloge par défaut.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- Sélection écran ----&lt;br /&gt;
#define SCREEN_SH1107&lt;br /&gt;
// #define SCREEN_SSD1327&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED Grove 1.12&amp;quot; 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;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
// ---- Cadran ----&lt;br /&gt;
const int CENTER_X = 64;&lt;br /&gt;
const int CENTER_Y = 64;&lt;br /&gt;
const int RADIUS   = 55;&lt;br /&gt;
&lt;br /&gt;
// ---- Correction Y selon écran ----&lt;br /&gt;
int Y_OFFSET = 0;&lt;br /&gt;
&lt;br /&gt;
// ---- Mode ----&lt;br /&gt;
bool modeTest = false;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Choix offset selon écran&lt;br /&gt;
  #ifdef SCREEN_SH1107&lt;br /&gt;
    Y_OFFSET = 16;&lt;br /&gt;
  #endif&lt;br /&gt;
  #ifdef SCREEN_SSD1327&lt;br /&gt;
    Y_OFFSET = 0;&lt;br /&gt;
  #endif&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse)&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
&lt;br /&gt;
  // ---- Attente commande série pendant 10s ----&lt;br /&gt;
  Serial.println(&amp;quot;Tapez &amp;#039;t&amp;#039; pour mode test offset, &amp;#039;h&amp;#039; pour horloge. Sinon horloge par défaut après 10s.&amp;quot;);&lt;br /&gt;
  unsigned long start = millis();&lt;br /&gt;
  while (millis() - start &amp;lt; 10000) {&lt;br /&gt;
    if (Serial.available()) {&lt;br /&gt;
      char c = Serial.read();&lt;br /&gt;
      if (c == &amp;#039;t&amp;#039;) {&lt;br /&gt;
        modeTest = true;&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
      if (c == &amp;#039;h&amp;#039;) {&lt;br /&gt;
        modeTest = false;&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  if (modeTest) {&lt;br /&gt;
    testOffset();&lt;br /&gt;
  } else {&lt;br /&gt;
    afficherHorloge();&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ---- Fonction horloge ----&lt;br /&gt;
void afficherHorloge() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  int hrX = CENTER_X + (RADIUS - 20) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY = CENTER_Y + (RADIUS - 20) * sin((hrAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 10) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 10) * sin((minAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 45, 12 + Y_OFFSET, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y + Y_OFFSET, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 5 + Y_OFFSET, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 10, CENTER_Y + 4 + Y_OFFSET, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 12 + Y_OFFSET, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 12, CENTER_Y + 4 + Y_OFFSET, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, hrX, hrY);&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, minX, minY);&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, secX, secY);&lt;br /&gt;
&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB14_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 30, 120 + Y_OFFSET, bufferTime);&lt;br /&gt;
&lt;br /&gt;
  u8g2.sendBuffer();&lt;br /&gt;
  delay(1000);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ---- Fonction utilitaire test offset ----&lt;br /&gt;
void testOffset() {&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
&lt;br /&gt;
  u8g2.drawLine(0, CENTER_Y, 128, CENTER_Y);             // sans offset&lt;br /&gt;
  u8g2.drawLine(0, CENTER_Y + Y_OFFSET, 128, CENTER_Y + Y_OFFSET); // avec offset&lt;br /&gt;
&lt;br /&gt;
  u8g2.drawStr(10, CENTER_Y - 5, &amp;quot;Sans offset&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(10, CENTER_Y + Y_OFFSET - 5, &amp;quot;Avec offset&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  u8g2.sendBuffer();&lt;br /&gt;
  delay(1000);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ---- Récupération heure locale ----&lt;br /&gt;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1;&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X128 OLED 5 Tool ===&lt;br /&gt;
&lt;br /&gt;
Tu verras deux lignes horizontales sur ton écran :&amp;lt;br&amp;gt;&lt;br /&gt;
Une ligne au centre (sans correction).&amp;lt;br&amp;gt;&lt;br /&gt;
Une ligne décalée de Y_OFFSET pixels (avec correction).&amp;lt;br&amp;gt;&lt;br /&gt;
Les textes « Sans offset » et « Avec offset » t’indiquent quelle ligne correspond à quoi.&amp;lt;br&amp;gt;&lt;br /&gt;
Si la ligne corrigée est bien alignée avec ce que tu attends, tu sais que ton Y_OFFSET est correct.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;Wire.h&amp;gt;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- Sélection écran ----&lt;br /&gt;
#define SCREEN_SH1107&lt;br /&gt;
// #define SCREEN_SSD1327&lt;br /&gt;
&lt;br /&gt;
// ---- OLED Grove 1.12&amp;quot; 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;
// ---- Correction Y selon écran ----&lt;br /&gt;
int Y_OFFSET = 0;&lt;br /&gt;
&lt;br /&gt;
// ---- Centre écran ----&lt;br /&gt;
const int CENTER_X = 64;&lt;br /&gt;
const int CENTER_Y = 64;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Choix offset selon écran&lt;br /&gt;
  #ifdef SCREEN_SH1107&lt;br /&gt;
    Y_OFFSET = 16;   // correction typique pour SH1107&lt;br /&gt;
  #endif&lt;br /&gt;
  #ifdef SCREEN_SSD1327&lt;br /&gt;
    Y_OFFSET = 0;    // pas besoin de correction&lt;br /&gt;
  #endif&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
&lt;br /&gt;
  // Ligne horizontale sans offset&lt;br /&gt;
  u8g2.drawLine(0, CENTER_Y, 128, CENTER_Y);&lt;br /&gt;
  u8g2.drawStr(10, CENTER_Y - 5, &amp;quot;Sans offset&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Ligne horizontale avec offset&lt;br /&gt;
  u8g2.drawLine(0, CENTER_Y + Y_OFFSET, 128, CENTER_Y + Y_OFFSET);&lt;br /&gt;
  u8g2.drawStr(10, CENTER_Y + Y_OFFSET - 5, &amp;quot;Avec offset&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  u8g2.sendBuffer();&lt;br /&gt;
&lt;br /&gt;
  delay(1000);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128×64 OLED 6 ===&lt;br /&gt;
&lt;br /&gt;
Centre déplacé à (64, 32) pour un écran 128×64.&amp;lt;br&amp;gt;&lt;br /&gt;
Rayon réduit à 28 pour que le cadran tienne bien.&amp;lt;br&amp;gt;&lt;br /&gt;
Positions des textes ajustées (y=10 pour la date, y=58 pour l’heure digitale).&amp;lt;br&amp;gt;&lt;br /&gt;
Constructeur U8g2 changé pour SSD1308/SSD1315.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED 128x64 SSD1308/SSD1315 ----&lt;br /&gt;
// Choisis le constructeur selon ton écran&lt;br /&gt;
U8G2_SSD1315_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);&lt;br /&gt;
&lt;br /&gt;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
// ---- Cadran ----&lt;br /&gt;
const int CENTER_X = 64;   // centre écran&lt;br /&gt;
const int CENTER_Y = 32;   // moitié de 64&lt;br /&gt;
const int RADIUS   = 28;   // adapté à la hauteur&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse)&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  // ---- Calcul des angles ----&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  // ---- Positions des aiguilles ----&lt;br /&gt;
  int hrX = CENTER_X + (RADIUS - 8) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY = CENTER_Y + (RADIUS - 8) * sin((hrAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 4) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 4) * sin((minAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage jour + date en haut ----&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(5, 10, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  // Cadran principal&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  // Chiffres 12-3-6-9&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 2, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 6, CENTER_Y + 4, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 10, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 10, CENTER_Y + 4, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Aiguilles&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, hrX, hrY);&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, minX, minY);&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, secX, secY);&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage digital en bas ----&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB14_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 30, 58, bufferTime);&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;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1;&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128×64 OLED 7 ===&lt;br /&gt;
&lt;br /&gt;
💻 Code compact (SSD1308/SSD1315, 128×64)&lt;br /&gt;
&lt;br /&gt;
Dans cette version, on supprime le cadran analogique et on affiche uniquement la date en haut et l’heure digitale bien centrée en bas. Cela exploite mieux la petite hauteur de l’écran.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Date + jour en haut (petite police).&amp;lt;br&amp;gt;&lt;br /&gt;
Heure digitale en bas, bien grande et centrée (u8g2_font_ncenB24_tr).&amp;lt;br&amp;gt;&lt;br /&gt;
Pas de cadran analogique → affichage clair et lisible sur un petit écran.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;ceci fonctionne mais le jours est superposé avec l&amp;#039;heure&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;Wire.h&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED 128x64 SSD1308/SSD1315 ----&lt;br /&gt;
// Choisis le constructeur selon ton écran&lt;br /&gt;
U8G2_SSD1315_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);&lt;br /&gt;
&lt;br /&gt;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse)&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // Affichage jour + date en haut&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(5, 12, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  // Affichage digital centré en bas&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB24_tr); // grande police pour l&amp;#039;heure&lt;br /&gt;
  u8g2.drawStr(20, 55, bufferTime);&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;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1;&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X64 OLED 7.1 Tool ===&lt;br /&gt;
&lt;br /&gt;
Calcul de la hauteur et largeur d&amp;#039;un texte avec une sortie du résultat sur le &amp;lt;b&amp;gt;port série&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Police 6x13 -&amp;gt; Hauteur=13 px, Largeur max char=6 px, &amp;lt;br&amp;gt;&lt;br /&gt;
Largeur &amp;#039;12:34:56&amp;#039;=48 px, Largeur &amp;#039;Vendredi, 14/11/2025&amp;#039;=114 px&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Police ncenB14 -&amp;gt; Hauteur=14 px, Largeur max char=14 px, &amp;lt;br&amp;gt;&lt;br /&gt;
Largeur &amp;#039;12:34:56&amp;#039;=84 px, Largeur &amp;#039;Vendredi, 14/11/2025&amp;#039;=168 px&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Police ncenB18 -&amp;gt; Hauteur=18 px, Largeur max char=18 px, &amp;lt;br&amp;gt;&lt;br /&gt;
Largeur &amp;#039;12:34:56&amp;#039;=108 px, Largeur &amp;#039;Vendredi, 14/11/2025&amp;#039;=216 px&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Police ncenB24 -&amp;gt; Hauteur=24 px, Largeur max char=24 px, &amp;lt;br&amp;gt;&lt;br /&gt;
Largeur &amp;#039;12:34:56&amp;#039;=144 px, Largeur &amp;#039;Vendredi, 14/11/2025&amp;#039;=288 px&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
🖥️ Exemple de code de test (heure + date)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;Wire.h&amp;gt;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
U8G2_SSD1315_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
&lt;br /&gt;
  // Test avec plusieurs polices&lt;br /&gt;
  testFont(u8g2_font_6x13_tr, &amp;quot;6x13&amp;quot;);&lt;br /&gt;
  testFont(u8g2_font_ncenB14_tr, &amp;quot;ncenB14&amp;quot;);&lt;br /&gt;
  testFont(u8g2_font_ncenB18_tr, &amp;quot;ncenB18&amp;quot;);&lt;br /&gt;
  testFont(u8g2_font_ncenB24_tr, &amp;quot;ncenB24&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  // rien à faire en boucle&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void testFont(const uint8_t* font, const char* name) {&lt;br /&gt;
  u8g2.setFont(font);&lt;br /&gt;
&lt;br /&gt;
  // Hauteur et largeur max d’un caractère&lt;br /&gt;
  int h = u8g2.getMaxCharHeight();&lt;br /&gt;
  int wChar = u8g2.getMaxCharWidth();&lt;br /&gt;
&lt;br /&gt;
  // Largeur d’un exemple d’heure&lt;br /&gt;
  int wTime = u8g2.getStrWidth(&amp;quot;12:34:56&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Largeur d’un exemple de jour + date&lt;br /&gt;
  int wDate = u8g2.getStrWidth(&amp;quot;Vendredi, 14/11/2025&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;Police %s -&amp;gt; Hauteur=%d px, Largeur max char=%d px, Largeur &amp;#039;12:34:56&amp;#039;=%d px, Largeur &amp;#039;Vendredi, 14/11/2025&amp;#039;=%d px\n&amp;quot;,&lt;br /&gt;
                name, h, wChar, wTime, wDate);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X64 OLED 7.2 ===&lt;br /&gt;
&lt;br /&gt;
Les marges hautes et basses en % de la hauteur de l’écran.&amp;lt;br&amp;gt;&lt;br /&gt;
Le choix automatique de la police pour l’heure en fonction de l’espace disponible.&amp;lt;br&amp;gt;&lt;br /&gt;
Le centrage horizontal de l’heure.&amp;lt;br&amp;gt;&lt;br /&gt;
La date en haut avec une police adaptée.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED 128x64 SSD1308/SSD1315 ----&lt;br /&gt;
U8G2_SSD1315_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);&lt;br /&gt;
&lt;br /&gt;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
// ---- Paramètres écran ----&lt;br /&gt;
const int LARGEUR_ECRAN = 128;&lt;br /&gt;
const int HAUTEUR_ECRAN = 64;&lt;br /&gt;
&lt;br /&gt;
// ---- Marges en % ----&lt;br /&gt;
const float MARGE_HAUT_PCT = 0.10; // 10%&lt;br /&gt;
const float MARGE_BAS_PCT  = 0.10; // 10%&lt;br /&gt;
&lt;br /&gt;
// ---- Polices disponibles pour l&amp;#039;heure ----&lt;br /&gt;
const uint8_t* FONT_SMALL  = u8g2_font_ncenB14_tr; // ~14 px&lt;br /&gt;
const uint8_t* FONT_MEDIUM = u8g2_font_ncenB18_tr; // ~18 px&lt;br /&gt;
const uint8_t* FONT_LARGE  = u8g2_font_ncenB24_tr; // ~24 px&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse)&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // Calcul des marges en pixels&lt;br /&gt;
  int margeHaut = (int)(HAUTEUR_ECRAN * MARGE_HAUT_PCT);&lt;br /&gt;
  int margeBas  = (int)(HAUTEUR_ECRAN * MARGE_BAS_PCT);&lt;br /&gt;
  int hauteurUtile = HAUTEUR_ECRAN - (margeHaut + margeBas);&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage jour + date en haut ----&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(5, margeHaut + 12, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  // ---- Choix automatique de la police pour l&amp;#039;heure ----&lt;br /&gt;
  const uint8_t* fontChoisie;&lt;br /&gt;
  if (hauteurUtile &amp;gt;= 24) {&lt;br /&gt;
    fontChoisie = FONT_LARGE;   // assez de place pour 24 px&lt;br /&gt;
  } else if (hauteurUtile &amp;gt;= 18) {&lt;br /&gt;
    fontChoisie = FONT_MEDIUM;  // assez de place pour 18 px&lt;br /&gt;
  } else {&lt;br /&gt;
    fontChoisie = FONT_SMALL;   // sinon police plus petite&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage digital centré en bas ----&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(fontChoisie);&lt;br /&gt;
&lt;br /&gt;
  // Centrage horizontal&lt;br /&gt;
  int largeur = u8g2.getStrWidth(bufferTime);&lt;br /&gt;
  int x = (LARGEUR_ECRAN - largeur) / 2;&lt;br /&gt;
&lt;br /&gt;
  // Ligne de base juste avant la marge basse&lt;br /&gt;
  int y = HAUTEUR_ECRAN - margeBas;&lt;br /&gt;
&lt;br /&gt;
  u8g2.drawStr(x, y, bufferTime);&lt;br /&gt;
&lt;br /&gt;
  u8g2.sendBuffer();&lt;br /&gt;
  delay(1000);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1;&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X64 OLED 8 ===&lt;br /&gt;
&lt;br /&gt;
💻 Code : seulement le cadran analogique&amp;lt;br&amp;gt; fonctionne mais illisible on dirait 2 ovales ! mais on peut voir les aguilles &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Un cadran analogique avec les chiffres 12‑3‑6‑9.&amp;lt;br&amp;gt;&lt;br /&gt;
Trois aiguilles (heures, minutes, secondes).&amp;lt;br&amp;gt;&lt;br /&gt;
Pas de date ni d’heure digitale → affichage épuré.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED 128x64 SSD1308/SSD1315 ----&lt;br /&gt;
U8G2_SSD1315_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);&lt;br /&gt;
&lt;br /&gt;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
&lt;br /&gt;
// ---- Cadran ----&lt;br /&gt;
const int CENTER_X = 64;   // centre écran&lt;br /&gt;
const int CENTER_Y = 32;   // moitié de 64&lt;br /&gt;
const int RADIUS   = 28;   // adapté à la hauteur&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse)&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  // ---- Calcul des angles ----&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  // ---- Positions des aiguilles ----&lt;br /&gt;
  int hrX = CENTER_X + (RADIUS - 8) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY = CENTER_Y + (RADIUS - 8) * sin((hrAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 4) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 4) * sin((minAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // Cadran principal&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  // Chiffres 12-3-6-9&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 2, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 6, CENTER_Y + 4, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 10, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 10, CENTER_Y + 4, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Aiguilles&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, hrX, hrY);   // heures&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, minX, minY); // minutes&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, secX, secY); // secondes&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;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%02d:%02d:%02d\n&amp;quot;, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>144.2.107.134</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.myows.top/index.php?title=Analog_Clock_OLED&amp;diff=1847</id>
		<title>Analog Clock OLED</title>
		<link rel="alternate" type="text/html" href="https://wiki.myows.top/index.php?title=Analog_Clock_OLED&amp;diff=1847"/>
		<updated>2025-11-14T23:44:34Z</updated>

		<summary type="html">&lt;p&gt;144.2.107.134: /* Analog Clock 128X128 OLED 2.1 Tool */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Analog Clock 128X128 OLED 1 ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED Grove 1.12&amp;quot; SH1107 ----&lt;br /&gt;
// U8G2_SH1107_PIMAR_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);&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;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
// ---- Cadran ----&lt;br /&gt;
const int CENTER_X = 64;   // centre écran&lt;br /&gt;
const int CENTER_Y = 64;&lt;br /&gt;
const int RADIUS   = 55;   // grand rayon pour 128x128&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse) avec gestion automatique du DST&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  // ---- Calcul des angles ----&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  // ---- Positions des aiguilles ----&lt;br /&gt;
  int hrX = CENTER_X + (RADIUS - 20) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY = CENTER_Y + (RADIUS - 20) * sin((hrAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 10) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 10) * sin((minAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage jour + date en haut ----&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 45, 12, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  // Cadran principal&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  // Chiffres 12-3-6-9&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 5, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 10, CENTER_Y + 4, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 12, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 12, CENTER_Y + 4, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Aiguilles&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, hrX, hrY);   // heures&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, minX, minY); // minutes&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, secX, secY); // secondes&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage digital en bas ----&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB14_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 30, 120, bufferTime);&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;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1; // tm_mon commence à 0&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;    // jour de la semaine (0 = dimanche)&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X128 OLED 2 ===&lt;br /&gt;
&lt;br /&gt;
Ajout de const int Y_OFFSET = 16;&amp;lt;br&amp;gt;&lt;br /&gt;
Application de + Y_OFFSET sur toutes les coordonnées Y (drawStr, drawLine, drawCircle, calcul des aiguilles).&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;pas vraiment, il semble avoir un problème avec l&amp;#039;offset négatif ou positif, on a légèrement un affichage.&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;Wire.h&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED Grove 1.12&amp;quot; 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;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
// ---- Cadran ----&lt;br /&gt;
const int CENTER_X = 64;   // centre écran&lt;br /&gt;
const int CENTER_Y = 64;&lt;br /&gt;
const int RADIUS   = 55;   // grand rayon pour 128x128&lt;br /&gt;
&lt;br /&gt;
// ---- Correction Y pour SH1107 ----&lt;br /&gt;
const int Y_OFFSET = 16;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse) avec gestion automatique du DST&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  // ---- Calcul des angles ----&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  // ---- Positions des aiguilles ----&lt;br /&gt;
  int hrX = CENTER_X + (RADIUS - 20) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY = CENTER_Y + (RADIUS - 20) * sin((hrAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 10) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 10) * sin((minAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage jour + date en haut ----&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 45, 12 + Y_OFFSET, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  // Cadran principal&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y + Y_OFFSET, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  // Chiffres 12-3-6-9&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 5 + Y_OFFSET, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 10, CENTER_Y + 4 + Y_OFFSET, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 12 + Y_OFFSET, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 12, CENTER_Y + 4 + Y_OFFSET, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Aiguilles&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, hrX, hrY);   // heures&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, minX, minY); // minutes&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, secX, secY); // secondes&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage digital en bas ----&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB14_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 30, 120 + Y_OFFSET, bufferTime);&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;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1; // tm_mon commence à 0&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;    // jour de la semaine (0 = dimanche)&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X128 OLED 2.1 Tool ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;Wire.h&amp;gt;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED 128x64 SSD1315 ----&lt;br /&gt;
U8G2_SSD1315_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);&lt;br /&gt;
&lt;br /&gt;
// ---- Variables temps ----&lt;br /&gt;
int hrs = 10, mins = 15, secs = 30; // exemple fixe pour test&lt;br /&gt;
&lt;br /&gt;
// ---- Paramètres écran ----&lt;br /&gt;
const int LARGEUR_ECRAN = 128;&lt;br /&gt;
const int HAUTEUR_ECRAN = 64;&lt;br /&gt;
&lt;br /&gt;
// ---- Marges en % ----&lt;br /&gt;
const float MARGE_HAUT_PCT   = 0.10; // 10% haut&lt;br /&gt;
const float MARGE_BAS_PCT    = 0.10; // 10% bas&lt;br /&gt;
const float MARGE_GAUCHE_PCT = 0.10; // 10% gauche&lt;br /&gt;
const float MARGE_DROITE_PCT = 0.10; // 10% droite&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  // ---- Calcul des marges en pixels ----&lt;br /&gt;
  int margeHaut   = (int)(HAUTEUR_ECRAN * MARGE_HAUT_PCT);&lt;br /&gt;
  int margeBas    = (int)(HAUTEUR_ECRAN * MARGE_BAS_PCT);&lt;br /&gt;
  int margeGauche = (int)(LARGEUR_ECRAN * MARGE_GAUCHE_PCT);&lt;br /&gt;
  int margeDroite = (int)(LARGEUR_ECRAN * MARGE_DROITE_PCT);&lt;br /&gt;
&lt;br /&gt;
  // ---- Dimensions utiles ----&lt;br /&gt;
  int largeurUtile = LARGEUR_ECRAN - (margeGauche + margeDroite);&lt;br /&gt;
  int hauteurUtile = HAUTEUR_ECRAN - (margeHaut + margeBas);&lt;br /&gt;
&lt;br /&gt;
  // ---- Centre du cercle ----&lt;br /&gt;
  const int CENTER_X = margeGauche + largeurUtile / 2;&lt;br /&gt;
  const int CENTER_Y = margeHaut + hauteurUtile / 2;&lt;br /&gt;
&lt;br /&gt;
  // ---- Rayon adapté (prendre le plus petit côté utile / 2) ----&lt;br /&gt;
  const int RADIUS = min(largeurUtile, hauteurUtile) / 2 - 5;&lt;br /&gt;
&lt;br /&gt;
  // ---- Calcul des angles ----&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  // ---- Positions des aiguilles ----&lt;br /&gt;
  int hrX  = CENTER_X + (RADIUS - 8) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY  = CENTER_Y + (RADIUS - 8) * sin((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 4) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 4) * sin((minAngle - 90) * PI / 180);&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // Cercle principal&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  // Chiffres 12-3-6-9&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 2, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 6, CENTER_Y + 4, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 10, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 10, CENTER_Y + 4, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Aiguilles&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, hrX, hrY);&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, minX, minY);&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, secX, secY);&lt;br /&gt;
&lt;br /&gt;
  u8g2.sendBuffer();&lt;br /&gt;
  delay(1000);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X128 OLED 2.2 ===&lt;br /&gt;
&lt;br /&gt;
Code pour SH1107 avec offset&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED 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;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
&lt;br /&gt;
// ---- Paramètres écran ----&lt;br /&gt;
const int LARGEUR_ECRAN = 128;&lt;br /&gt;
const int HAUTEUR_ECRAN = 128;&lt;br /&gt;
&lt;br /&gt;
// ---- Offset spécifique SH1107 ----&lt;br /&gt;
const int Y_OFFSET = 16; // décalage vertical typique&lt;br /&gt;
&lt;br /&gt;
// ---- Marges en % ----&lt;br /&gt;
const float MARGE_HAUT_PCT   = 0.10; // 10% haut&lt;br /&gt;
const float MARGE_BAS_PCT    = 0.10; // 10% bas&lt;br /&gt;
const float MARGE_GAUCHE_PCT = 0.10; // 10% gauche&lt;br /&gt;
const float MARGE_DROITE_PCT = 0.10; // 10% droite&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse)&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  // ---- Calcul des marges en pixels ----&lt;br /&gt;
  int margeHaut   = (int)(HAUTEUR_ECRAN * MARGE_HAUT_PCT);&lt;br /&gt;
  int margeBas    = (int)(HAUTEUR_ECRAN * MARGE_BAS_PCT);&lt;br /&gt;
  int margeGauche = (int)(LARGEUR_ECRAN * MARGE_GAUCHE_PCT);&lt;br /&gt;
  int margeDroite = (int)(LARGEUR_ECRAN * MARGE_DROITE_PCT);&lt;br /&gt;
&lt;br /&gt;
  // ---- Dimensions utiles ----&lt;br /&gt;
  int largeurUtile = LARGEUR_ECRAN - (margeGauche + margeDroite);&lt;br /&gt;
  int hauteurUtile = HAUTEUR_ECRAN - (margeHaut + margeBas);&lt;br /&gt;
&lt;br /&gt;
  // ---- Centre du cercle (avec offset) ----&lt;br /&gt;
  const int CENTER_X = margeGauche + largeurUtile / 2;&lt;br /&gt;
  const int CENTER_Y = margeHaut + hauteurUtile / 2 + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  // ---- Rayon adapté ----&lt;br /&gt;
  const int RADIUS = min(largeurUtile, hauteurUtile) / 2 - 5;&lt;br /&gt;
&lt;br /&gt;
  // ---- Calcul des angles ----&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  // ---- Positions des aiguilles ----&lt;br /&gt;
  int hrX  = CENTER_X + (RADIUS - 20) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY  = CENTER_Y + (RADIUS - 20) * sin((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 10) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 10) * sin((minAngle - 90) * PI / 180);&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // Cercle principal&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  // Chiffres 12-3-6-9&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 2, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 6, CENTER_Y + 4, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 12, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 12, CENTER_Y + 4, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Aiguilles&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, hrX, hrY);&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, minX, minY);&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, secX, secY);&lt;br /&gt;
&lt;br /&gt;
  u8g2.sendBuffer();&lt;br /&gt;
  delay(1000);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%02d:%02d:%02d\n&amp;quot;, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X128 OLED 3 ===&lt;br /&gt;
&lt;br /&gt;
Si tu utilises SH1107, laisse #define SCREEN_SH1107 actif → offset = 16.&amp;lt;br&amp;gt;&lt;br /&gt;
Si tu passes à SSD1327, commente SCREEN_SH1107 et décommente SCREEN_SSD1327 → offset = 0.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- Sélection écran ----&lt;br /&gt;
// Décommente la ligne correspondant à ton écran&lt;br /&gt;
#define SCREEN_SH1107&lt;br /&gt;
// #define SCREEN_SSD1327&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED Grove 1.12&amp;quot; SH1107 ----&lt;br /&gt;
// (Même constructeur pour SSD1327, mais offset différent)&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;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
// ---- Cadran ----&lt;br /&gt;
const int CENTER_X = 64;   // centre écran&lt;br /&gt;
const int CENTER_Y = 64;&lt;br /&gt;
const int RADIUS   = 55;   // grand rayon pour 128x128&lt;br /&gt;
&lt;br /&gt;
// ---- Correction Y selon écran ----&lt;br /&gt;
int Y_OFFSET = 0;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Choix offset selon écran&lt;br /&gt;
  #ifdef SCREEN_SH1107&lt;br /&gt;
    Y_OFFSET = 16;   // correction typique pour SH1107&lt;br /&gt;
  #endif&lt;br /&gt;
&lt;br /&gt;
  #ifdef SCREEN_SSD1327&lt;br /&gt;
    Y_OFFSET = 0;    // pas besoin de correction&lt;br /&gt;
  #endif&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse) avec gestion automatique du DST&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  // ---- Calcul des angles ----&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  // ---- Positions des aiguilles ----&lt;br /&gt;
  int hrX = CENTER_X + (RADIUS - 20) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY = CENTER_Y + (RADIUS - 20) * sin((hrAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 10) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 10) * sin((minAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage jour + date en haut ----&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 45, 12 + Y_OFFSET, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  // Cadran principal&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y + Y_OFFSET, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  // Chiffres 12-3-6-9&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 5 + Y_OFFSET, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 10, CENTER_Y + 4 + Y_OFFSET, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 12 + Y_OFFSET, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 12, CENTER_Y + 4 + Y_OFFSET, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Aiguilles&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, hrX, hrY);   // heures&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, minX, minY); // minutes&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, secX, secY); // secondes&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage digital en bas ----&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB14_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 30, 120 + Y_OFFSET, bufferTime);&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;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1; // tm_mon commence à 0&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;    // jour de la semaine (0 = dimanche)&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X128 OLED 4 ===&lt;br /&gt;
&lt;br /&gt;
Au démarrage → attend 10 secondes une commande série.&amp;lt;br&amp;gt;&lt;br /&gt;
Si tu tapes t → mode test offset (lignes horizontales).&amp;lt;br&amp;gt;&lt;br /&gt;
Si tu tapes h → mode horloge.&amp;lt;br&amp;gt;&lt;br /&gt;
Si rien n’est tapé → après 10 secondes → mode horloge par défaut.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- Sélection écran ----&lt;br /&gt;
#define SCREEN_SH1107&lt;br /&gt;
// #define SCREEN_SSD1327&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED Grove 1.12&amp;quot; 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;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
// ---- Cadran ----&lt;br /&gt;
const int CENTER_X = 64;&lt;br /&gt;
const int CENTER_Y = 64;&lt;br /&gt;
const int RADIUS   = 55;&lt;br /&gt;
&lt;br /&gt;
// ---- Correction Y selon écran ----&lt;br /&gt;
int Y_OFFSET = 0;&lt;br /&gt;
&lt;br /&gt;
// ---- Mode ----&lt;br /&gt;
bool modeTest = false;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Choix offset selon écran&lt;br /&gt;
  #ifdef SCREEN_SH1107&lt;br /&gt;
    Y_OFFSET = 16;&lt;br /&gt;
  #endif&lt;br /&gt;
  #ifdef SCREEN_SSD1327&lt;br /&gt;
    Y_OFFSET = 0;&lt;br /&gt;
  #endif&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse)&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
&lt;br /&gt;
  // ---- Attente commande série pendant 10s ----&lt;br /&gt;
  Serial.println(&amp;quot;Tapez &amp;#039;t&amp;#039; pour mode test offset, &amp;#039;h&amp;#039; pour horloge. Sinon horloge par défaut après 10s.&amp;quot;);&lt;br /&gt;
  unsigned long start = millis();&lt;br /&gt;
  while (millis() - start &amp;lt; 10000) {&lt;br /&gt;
    if (Serial.available()) {&lt;br /&gt;
      char c = Serial.read();&lt;br /&gt;
      if (c == &amp;#039;t&amp;#039;) {&lt;br /&gt;
        modeTest = true;&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
      if (c == &amp;#039;h&amp;#039;) {&lt;br /&gt;
        modeTest = false;&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  if (modeTest) {&lt;br /&gt;
    testOffset();&lt;br /&gt;
  } else {&lt;br /&gt;
    afficherHorloge();&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ---- Fonction horloge ----&lt;br /&gt;
void afficherHorloge() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  int hrX = CENTER_X + (RADIUS - 20) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY = CENTER_Y + (RADIUS - 20) * sin((hrAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 10) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 10) * sin((minAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 45, 12 + Y_OFFSET, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y + Y_OFFSET, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 5 + Y_OFFSET, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 10, CENTER_Y + 4 + Y_OFFSET, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 12 + Y_OFFSET, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 12, CENTER_Y + 4 + Y_OFFSET, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, hrX, hrY);&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, minX, minY);&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, secX, secY);&lt;br /&gt;
&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB14_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 30, 120 + Y_OFFSET, bufferTime);&lt;br /&gt;
&lt;br /&gt;
  u8g2.sendBuffer();&lt;br /&gt;
  delay(1000);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ---- Fonction utilitaire test offset ----&lt;br /&gt;
void testOffset() {&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
&lt;br /&gt;
  u8g2.drawLine(0, CENTER_Y, 128, CENTER_Y);             // sans offset&lt;br /&gt;
  u8g2.drawLine(0, CENTER_Y + Y_OFFSET, 128, CENTER_Y + Y_OFFSET); // avec offset&lt;br /&gt;
&lt;br /&gt;
  u8g2.drawStr(10, CENTER_Y - 5, &amp;quot;Sans offset&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(10, CENTER_Y + Y_OFFSET - 5, &amp;quot;Avec offset&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  u8g2.sendBuffer();&lt;br /&gt;
  delay(1000);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ---- Récupération heure locale ----&lt;br /&gt;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1;&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X128 OLED 5 Tool ===&lt;br /&gt;
&lt;br /&gt;
Tu verras deux lignes horizontales sur ton écran :&amp;lt;br&amp;gt;&lt;br /&gt;
Une ligne au centre (sans correction).&amp;lt;br&amp;gt;&lt;br /&gt;
Une ligne décalée de Y_OFFSET pixels (avec correction).&amp;lt;br&amp;gt;&lt;br /&gt;
Les textes « Sans offset » et « Avec offset » t’indiquent quelle ligne correspond à quoi.&amp;lt;br&amp;gt;&lt;br /&gt;
Si la ligne corrigée est bien alignée avec ce que tu attends, tu sais que ton Y_OFFSET est correct.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;Wire.h&amp;gt;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- Sélection écran ----&lt;br /&gt;
#define SCREEN_SH1107&lt;br /&gt;
// #define SCREEN_SSD1327&lt;br /&gt;
&lt;br /&gt;
// ---- OLED Grove 1.12&amp;quot; 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;
// ---- Correction Y selon écran ----&lt;br /&gt;
int Y_OFFSET = 0;&lt;br /&gt;
&lt;br /&gt;
// ---- Centre écran ----&lt;br /&gt;
const int CENTER_X = 64;&lt;br /&gt;
const int CENTER_Y = 64;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Choix offset selon écran&lt;br /&gt;
  #ifdef SCREEN_SH1107&lt;br /&gt;
    Y_OFFSET = 16;   // correction typique pour SH1107&lt;br /&gt;
  #endif&lt;br /&gt;
  #ifdef SCREEN_SSD1327&lt;br /&gt;
    Y_OFFSET = 0;    // pas besoin de correction&lt;br /&gt;
  #endif&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
&lt;br /&gt;
  // Ligne horizontale sans offset&lt;br /&gt;
  u8g2.drawLine(0, CENTER_Y, 128, CENTER_Y);&lt;br /&gt;
  u8g2.drawStr(10, CENTER_Y - 5, &amp;quot;Sans offset&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Ligne horizontale avec offset&lt;br /&gt;
  u8g2.drawLine(0, CENTER_Y + Y_OFFSET, 128, CENTER_Y + Y_OFFSET);&lt;br /&gt;
  u8g2.drawStr(10, CENTER_Y + Y_OFFSET - 5, &amp;quot;Avec offset&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  u8g2.sendBuffer();&lt;br /&gt;
&lt;br /&gt;
  delay(1000);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128×64 OLED 6 ===&lt;br /&gt;
&lt;br /&gt;
Centre déplacé à (64, 32) pour un écran 128×64.&amp;lt;br&amp;gt;&lt;br /&gt;
Rayon réduit à 28 pour que le cadran tienne bien.&amp;lt;br&amp;gt;&lt;br /&gt;
Positions des textes ajustées (y=10 pour la date, y=58 pour l’heure digitale).&amp;lt;br&amp;gt;&lt;br /&gt;
Constructeur U8g2 changé pour SSD1308/SSD1315.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED 128x64 SSD1308/SSD1315 ----&lt;br /&gt;
// Choisis le constructeur selon ton écran&lt;br /&gt;
U8G2_SSD1315_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);&lt;br /&gt;
&lt;br /&gt;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
// ---- Cadran ----&lt;br /&gt;
const int CENTER_X = 64;   // centre écran&lt;br /&gt;
const int CENTER_Y = 32;   // moitié de 64&lt;br /&gt;
const int RADIUS   = 28;   // adapté à la hauteur&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse)&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  // ---- Calcul des angles ----&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  // ---- Positions des aiguilles ----&lt;br /&gt;
  int hrX = CENTER_X + (RADIUS - 8) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY = CENTER_Y + (RADIUS - 8) * sin((hrAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 4) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 4) * sin((minAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage jour + date en haut ----&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(5, 10, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  // Cadran principal&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  // Chiffres 12-3-6-9&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 2, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 6, CENTER_Y + 4, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 10, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 10, CENTER_Y + 4, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Aiguilles&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, hrX, hrY);&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, minX, minY);&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, secX, secY);&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage digital en bas ----&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB14_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 30, 58, bufferTime);&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;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1;&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128×64 OLED 7 ===&lt;br /&gt;
&lt;br /&gt;
💻 Code compact (SSD1308/SSD1315, 128×64)&lt;br /&gt;
&lt;br /&gt;
Dans cette version, on supprime le cadran analogique et on affiche uniquement la date en haut et l’heure digitale bien centrée en bas. Cela exploite mieux la petite hauteur de l’écran.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Date + jour en haut (petite police).&amp;lt;br&amp;gt;&lt;br /&gt;
Heure digitale en bas, bien grande et centrée (u8g2_font_ncenB24_tr).&amp;lt;br&amp;gt;&lt;br /&gt;
Pas de cadran analogique → affichage clair et lisible sur un petit écran.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;ceci fonctionne mais le jours est superposé avec l&amp;#039;heure&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;Wire.h&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED 128x64 SSD1308/SSD1315 ----&lt;br /&gt;
// Choisis le constructeur selon ton écran&lt;br /&gt;
U8G2_SSD1315_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);&lt;br /&gt;
&lt;br /&gt;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse)&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // Affichage jour + date en haut&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(5, 12, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  // Affichage digital centré en bas&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB24_tr); // grande police pour l&amp;#039;heure&lt;br /&gt;
  u8g2.drawStr(20, 55, bufferTime);&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;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1;&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X64 OLED 7.1 Tool ===&lt;br /&gt;
&lt;br /&gt;
Calcul de la hauteur et largeur d&amp;#039;un texte avec une sortie du résultat sur le &amp;lt;b&amp;gt;port série&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Police 6x13 -&amp;gt; Hauteur=13 px, Largeur max char=6 px, &amp;lt;br&amp;gt;&lt;br /&gt;
Largeur &amp;#039;12:34:56&amp;#039;=48 px, Largeur &amp;#039;Vendredi, 14/11/2025&amp;#039;=114 px&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Police ncenB14 -&amp;gt; Hauteur=14 px, Largeur max char=14 px, &amp;lt;br&amp;gt;&lt;br /&gt;
Largeur &amp;#039;12:34:56&amp;#039;=84 px, Largeur &amp;#039;Vendredi, 14/11/2025&amp;#039;=168 px&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Police ncenB18 -&amp;gt; Hauteur=18 px, Largeur max char=18 px, &amp;lt;br&amp;gt;&lt;br /&gt;
Largeur &amp;#039;12:34:56&amp;#039;=108 px, Largeur &amp;#039;Vendredi, 14/11/2025&amp;#039;=216 px&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Police ncenB24 -&amp;gt; Hauteur=24 px, Largeur max char=24 px, &amp;lt;br&amp;gt;&lt;br /&gt;
Largeur &amp;#039;12:34:56&amp;#039;=144 px, Largeur &amp;#039;Vendredi, 14/11/2025&amp;#039;=288 px&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
🖥️ Exemple de code de test (heure + date)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;Wire.h&amp;gt;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
U8G2_SSD1315_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
&lt;br /&gt;
  // Test avec plusieurs polices&lt;br /&gt;
  testFont(u8g2_font_6x13_tr, &amp;quot;6x13&amp;quot;);&lt;br /&gt;
  testFont(u8g2_font_ncenB14_tr, &amp;quot;ncenB14&amp;quot;);&lt;br /&gt;
  testFont(u8g2_font_ncenB18_tr, &amp;quot;ncenB18&amp;quot;);&lt;br /&gt;
  testFont(u8g2_font_ncenB24_tr, &amp;quot;ncenB24&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  // rien à faire en boucle&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void testFont(const uint8_t* font, const char* name) {&lt;br /&gt;
  u8g2.setFont(font);&lt;br /&gt;
&lt;br /&gt;
  // Hauteur et largeur max d’un caractère&lt;br /&gt;
  int h = u8g2.getMaxCharHeight();&lt;br /&gt;
  int wChar = u8g2.getMaxCharWidth();&lt;br /&gt;
&lt;br /&gt;
  // Largeur d’un exemple d’heure&lt;br /&gt;
  int wTime = u8g2.getStrWidth(&amp;quot;12:34:56&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Largeur d’un exemple de jour + date&lt;br /&gt;
  int wDate = u8g2.getStrWidth(&amp;quot;Vendredi, 14/11/2025&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;Police %s -&amp;gt; Hauteur=%d px, Largeur max char=%d px, Largeur &amp;#039;12:34:56&amp;#039;=%d px, Largeur &amp;#039;Vendredi, 14/11/2025&amp;#039;=%d px\n&amp;quot;,&lt;br /&gt;
                name, h, wChar, wTime, wDate);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X64 OLED 7.2 ===&lt;br /&gt;
&lt;br /&gt;
Les marges hautes et basses en % de la hauteur de l’écran.&amp;lt;br&amp;gt;&lt;br /&gt;
Le choix automatique de la police pour l’heure en fonction de l’espace disponible.&amp;lt;br&amp;gt;&lt;br /&gt;
Le centrage horizontal de l’heure.&amp;lt;br&amp;gt;&lt;br /&gt;
La date en haut avec une police adaptée.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED 128x64 SSD1308/SSD1315 ----&lt;br /&gt;
U8G2_SSD1315_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);&lt;br /&gt;
&lt;br /&gt;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
// ---- Paramètres écran ----&lt;br /&gt;
const int LARGEUR_ECRAN = 128;&lt;br /&gt;
const int HAUTEUR_ECRAN = 64;&lt;br /&gt;
&lt;br /&gt;
// ---- Marges en % ----&lt;br /&gt;
const float MARGE_HAUT_PCT = 0.10; // 10%&lt;br /&gt;
const float MARGE_BAS_PCT  = 0.10; // 10%&lt;br /&gt;
&lt;br /&gt;
// ---- Polices disponibles pour l&amp;#039;heure ----&lt;br /&gt;
const uint8_t* FONT_SMALL  = u8g2_font_ncenB14_tr; // ~14 px&lt;br /&gt;
const uint8_t* FONT_MEDIUM = u8g2_font_ncenB18_tr; // ~18 px&lt;br /&gt;
const uint8_t* FONT_LARGE  = u8g2_font_ncenB24_tr; // ~24 px&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse)&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // Calcul des marges en pixels&lt;br /&gt;
  int margeHaut = (int)(HAUTEUR_ECRAN * MARGE_HAUT_PCT);&lt;br /&gt;
  int margeBas  = (int)(HAUTEUR_ECRAN * MARGE_BAS_PCT);&lt;br /&gt;
  int hauteurUtile = HAUTEUR_ECRAN - (margeHaut + margeBas);&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage jour + date en haut ----&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(5, margeHaut + 12, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  // ---- Choix automatique de la police pour l&amp;#039;heure ----&lt;br /&gt;
  const uint8_t* fontChoisie;&lt;br /&gt;
  if (hauteurUtile &amp;gt;= 24) {&lt;br /&gt;
    fontChoisie = FONT_LARGE;   // assez de place pour 24 px&lt;br /&gt;
  } else if (hauteurUtile &amp;gt;= 18) {&lt;br /&gt;
    fontChoisie = FONT_MEDIUM;  // assez de place pour 18 px&lt;br /&gt;
  } else {&lt;br /&gt;
    fontChoisie = FONT_SMALL;   // sinon police plus petite&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage digital centré en bas ----&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(fontChoisie);&lt;br /&gt;
&lt;br /&gt;
  // Centrage horizontal&lt;br /&gt;
  int largeur = u8g2.getStrWidth(bufferTime);&lt;br /&gt;
  int x = (LARGEUR_ECRAN - largeur) / 2;&lt;br /&gt;
&lt;br /&gt;
  // Ligne de base juste avant la marge basse&lt;br /&gt;
  int y = HAUTEUR_ECRAN - margeBas;&lt;br /&gt;
&lt;br /&gt;
  u8g2.drawStr(x, y, bufferTime);&lt;br /&gt;
&lt;br /&gt;
  u8g2.sendBuffer();&lt;br /&gt;
  delay(1000);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1;&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X64 OLED 8 ===&lt;br /&gt;
&lt;br /&gt;
💻 Code : seulement le cadran analogique&amp;lt;br&amp;gt; fonctionne mais illisible on dirait 2 ovales ! mais on peut voir les aguilles &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Un cadran analogique avec les chiffres 12‑3‑6‑9.&amp;lt;br&amp;gt;&lt;br /&gt;
Trois aiguilles (heures, minutes, secondes).&amp;lt;br&amp;gt;&lt;br /&gt;
Pas de date ni d’heure digitale → affichage épuré.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED 128x64 SSD1308/SSD1315 ----&lt;br /&gt;
U8G2_SSD1315_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);&lt;br /&gt;
&lt;br /&gt;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
&lt;br /&gt;
// ---- Cadran ----&lt;br /&gt;
const int CENTER_X = 64;   // centre écran&lt;br /&gt;
const int CENTER_Y = 32;   // moitié de 64&lt;br /&gt;
const int RADIUS   = 28;   // adapté à la hauteur&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse)&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  // ---- Calcul des angles ----&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  // ---- Positions des aiguilles ----&lt;br /&gt;
  int hrX = CENTER_X + (RADIUS - 8) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY = CENTER_Y + (RADIUS - 8) * sin((hrAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 4) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 4) * sin((minAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // Cadran principal&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  // Chiffres 12-3-6-9&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 2, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 6, CENTER_Y + 4, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 10, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 10, CENTER_Y + 4, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Aiguilles&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, hrX, hrY);   // heures&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, minX, minY); // minutes&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, secX, secY); // secondes&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;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%02d:%02d:%02d\n&amp;quot;, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>144.2.107.134</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.myows.top/index.php?title=Analog_Clock_OLED&amp;diff=1846</id>
		<title>Analog Clock OLED</title>
		<link rel="alternate" type="text/html" href="https://wiki.myows.top/index.php?title=Analog_Clock_OLED&amp;diff=1846"/>
		<updated>2025-11-14T23:39:23Z</updated>

		<summary type="html">&lt;p&gt;144.2.107.134: /* Analog Clock 128X128 OLED 2 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Analog Clock 128X128 OLED 1 ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED Grove 1.12&amp;quot; SH1107 ----&lt;br /&gt;
// U8G2_SH1107_PIMAR_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);&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;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
// ---- Cadran ----&lt;br /&gt;
const int CENTER_X = 64;   // centre écran&lt;br /&gt;
const int CENTER_Y = 64;&lt;br /&gt;
const int RADIUS   = 55;   // grand rayon pour 128x128&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse) avec gestion automatique du DST&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  // ---- Calcul des angles ----&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  // ---- Positions des aiguilles ----&lt;br /&gt;
  int hrX = CENTER_X + (RADIUS - 20) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY = CENTER_Y + (RADIUS - 20) * sin((hrAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 10) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 10) * sin((minAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage jour + date en haut ----&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 45, 12, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  // Cadran principal&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  // Chiffres 12-3-6-9&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 5, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 10, CENTER_Y + 4, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 12, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 12, CENTER_Y + 4, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Aiguilles&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, hrX, hrY);   // heures&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, minX, minY); // minutes&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, secX, secY); // secondes&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage digital en bas ----&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB14_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 30, 120, bufferTime);&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;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1; // tm_mon commence à 0&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;    // jour de la semaine (0 = dimanche)&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X128 OLED 2 ===&lt;br /&gt;
&lt;br /&gt;
Ajout de const int Y_OFFSET = 16;&amp;lt;br&amp;gt;&lt;br /&gt;
Application de + Y_OFFSET sur toutes les coordonnées Y (drawStr, drawLine, drawCircle, calcul des aiguilles).&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;pas vraiment, il semble avoir un problème avec l&amp;#039;offset négatif ou positif, on a légèrement un affichage.&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;Wire.h&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED Grove 1.12&amp;quot; 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;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
// ---- Cadran ----&lt;br /&gt;
const int CENTER_X = 64;   // centre écran&lt;br /&gt;
const int CENTER_Y = 64;&lt;br /&gt;
const int RADIUS   = 55;   // grand rayon pour 128x128&lt;br /&gt;
&lt;br /&gt;
// ---- Correction Y pour SH1107 ----&lt;br /&gt;
const int Y_OFFSET = 16;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse) avec gestion automatique du DST&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  // ---- Calcul des angles ----&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  // ---- Positions des aiguilles ----&lt;br /&gt;
  int hrX = CENTER_X + (RADIUS - 20) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY = CENTER_Y + (RADIUS - 20) * sin((hrAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 10) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 10) * sin((minAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage jour + date en haut ----&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 45, 12 + Y_OFFSET, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  // Cadran principal&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y + Y_OFFSET, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  // Chiffres 12-3-6-9&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 5 + Y_OFFSET, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 10, CENTER_Y + 4 + Y_OFFSET, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 12 + Y_OFFSET, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 12, CENTER_Y + 4 + Y_OFFSET, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Aiguilles&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, hrX, hrY);   // heures&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, minX, minY); // minutes&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, secX, secY); // secondes&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage digital en bas ----&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB14_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 30, 120 + Y_OFFSET, bufferTime);&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;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1; // tm_mon commence à 0&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;    // jour de la semaine (0 = dimanche)&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X128 OLED 2.1 Tool ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;Wire.h&amp;gt;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED 128x64 SSD1315 ----&lt;br /&gt;
U8G2_SSD1315_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);&lt;br /&gt;
&lt;br /&gt;
// ---- Variables temps ----&lt;br /&gt;
int hrs = 10, mins = 15, secs = 30; // exemple fixe pour test&lt;br /&gt;
&lt;br /&gt;
// ---- Paramètres écran ----&lt;br /&gt;
const int LARGEUR_ECRAN = 128;&lt;br /&gt;
const int HAUTEUR_ECRAN = 64;&lt;br /&gt;
&lt;br /&gt;
// ---- Marges en % ----&lt;br /&gt;
const float MARGE_HAUT_PCT   = 0.10; // 10% haut&lt;br /&gt;
const float MARGE_BAS_PCT    = 0.10; // 10% bas&lt;br /&gt;
const float MARGE_GAUCHE_PCT = 0.10; // 10% gauche&lt;br /&gt;
const float MARGE_DROITE_PCT = 0.10; // 10% droite&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  // ---- Calcul des marges en pixels ----&lt;br /&gt;
  int margeHaut   = (int)(HAUTEUR_ECRAN * MARGE_HAUT_PCT);&lt;br /&gt;
  int margeBas    = (int)(HAUTEUR_ECRAN * MARGE_BAS_PCT);&lt;br /&gt;
  int margeGauche = (int)(LARGEUR_ECRAN * MARGE_GAUCHE_PCT);&lt;br /&gt;
  int margeDroite = (int)(LARGEUR_ECRAN * MARGE_DROITE_PCT);&lt;br /&gt;
&lt;br /&gt;
  // ---- Dimensions utiles ----&lt;br /&gt;
  int largeurUtile = LARGEUR_ECRAN - (margeGauche + margeDroite);&lt;br /&gt;
  int hauteurUtile = HAUTEUR_ECRAN - (margeHaut + margeBas);&lt;br /&gt;
&lt;br /&gt;
  // ---- Centre du cercle ----&lt;br /&gt;
  const int CENTER_X = margeGauche + largeurUtile / 2;&lt;br /&gt;
  const int CENTER_Y = margeHaut + hauteurUtile / 2;&lt;br /&gt;
&lt;br /&gt;
  // ---- Rayon adapté (prendre le plus petit côté utile / 2) ----&lt;br /&gt;
  const int RADIUS = min(largeurUtile, hauteurUtile) / 2 - 5;&lt;br /&gt;
&lt;br /&gt;
  // ---- Calcul des angles ----&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  // ---- Positions des aiguilles ----&lt;br /&gt;
  int hrX  = CENTER_X + (RADIUS - 8) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY  = CENTER_Y + (RADIUS - 8) * sin((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 4) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 4) * sin((minAngle - 90) * PI / 180);&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // Cercle principal&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  // Chiffres 12-3-6-9&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 2, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 6, CENTER_Y + 4, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 10, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 10, CENTER_Y + 4, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Aiguilles&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, hrX, hrY);&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, minX, minY);&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, secX, secY);&lt;br /&gt;
&lt;br /&gt;
  u8g2.sendBuffer();&lt;br /&gt;
  delay(1000);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X128 OLED 3 ===&lt;br /&gt;
&lt;br /&gt;
Si tu utilises SH1107, laisse #define SCREEN_SH1107 actif → offset = 16.&amp;lt;br&amp;gt;&lt;br /&gt;
Si tu passes à SSD1327, commente SCREEN_SH1107 et décommente SCREEN_SSD1327 → offset = 0.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- Sélection écran ----&lt;br /&gt;
// Décommente la ligne correspondant à ton écran&lt;br /&gt;
#define SCREEN_SH1107&lt;br /&gt;
// #define SCREEN_SSD1327&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED Grove 1.12&amp;quot; SH1107 ----&lt;br /&gt;
// (Même constructeur pour SSD1327, mais offset différent)&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;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
// ---- Cadran ----&lt;br /&gt;
const int CENTER_X = 64;   // centre écran&lt;br /&gt;
const int CENTER_Y = 64;&lt;br /&gt;
const int RADIUS   = 55;   // grand rayon pour 128x128&lt;br /&gt;
&lt;br /&gt;
// ---- Correction Y selon écran ----&lt;br /&gt;
int Y_OFFSET = 0;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Choix offset selon écran&lt;br /&gt;
  #ifdef SCREEN_SH1107&lt;br /&gt;
    Y_OFFSET = 16;   // correction typique pour SH1107&lt;br /&gt;
  #endif&lt;br /&gt;
&lt;br /&gt;
  #ifdef SCREEN_SSD1327&lt;br /&gt;
    Y_OFFSET = 0;    // pas besoin de correction&lt;br /&gt;
  #endif&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse) avec gestion automatique du DST&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  // ---- Calcul des angles ----&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  // ---- Positions des aiguilles ----&lt;br /&gt;
  int hrX = CENTER_X + (RADIUS - 20) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY = CENTER_Y + (RADIUS - 20) * sin((hrAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 10) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 10) * sin((minAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage jour + date en haut ----&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 45, 12 + Y_OFFSET, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  // Cadran principal&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y + Y_OFFSET, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  // Chiffres 12-3-6-9&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 5 + Y_OFFSET, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 10, CENTER_Y + 4 + Y_OFFSET, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 12 + Y_OFFSET, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 12, CENTER_Y + 4 + Y_OFFSET, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Aiguilles&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, hrX, hrY);   // heures&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, minX, minY); // minutes&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, secX, secY); // secondes&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage digital en bas ----&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB14_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 30, 120 + Y_OFFSET, bufferTime);&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;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1; // tm_mon commence à 0&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;    // jour de la semaine (0 = dimanche)&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X128 OLED 4 ===&lt;br /&gt;
&lt;br /&gt;
Au démarrage → attend 10 secondes une commande série.&amp;lt;br&amp;gt;&lt;br /&gt;
Si tu tapes t → mode test offset (lignes horizontales).&amp;lt;br&amp;gt;&lt;br /&gt;
Si tu tapes h → mode horloge.&amp;lt;br&amp;gt;&lt;br /&gt;
Si rien n’est tapé → après 10 secondes → mode horloge par défaut.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- Sélection écran ----&lt;br /&gt;
#define SCREEN_SH1107&lt;br /&gt;
// #define SCREEN_SSD1327&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED Grove 1.12&amp;quot; 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;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
// ---- Cadran ----&lt;br /&gt;
const int CENTER_X = 64;&lt;br /&gt;
const int CENTER_Y = 64;&lt;br /&gt;
const int RADIUS   = 55;&lt;br /&gt;
&lt;br /&gt;
// ---- Correction Y selon écran ----&lt;br /&gt;
int Y_OFFSET = 0;&lt;br /&gt;
&lt;br /&gt;
// ---- Mode ----&lt;br /&gt;
bool modeTest = false;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Choix offset selon écran&lt;br /&gt;
  #ifdef SCREEN_SH1107&lt;br /&gt;
    Y_OFFSET = 16;&lt;br /&gt;
  #endif&lt;br /&gt;
  #ifdef SCREEN_SSD1327&lt;br /&gt;
    Y_OFFSET = 0;&lt;br /&gt;
  #endif&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse)&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
&lt;br /&gt;
  // ---- Attente commande série pendant 10s ----&lt;br /&gt;
  Serial.println(&amp;quot;Tapez &amp;#039;t&amp;#039; pour mode test offset, &amp;#039;h&amp;#039; pour horloge. Sinon horloge par défaut après 10s.&amp;quot;);&lt;br /&gt;
  unsigned long start = millis();&lt;br /&gt;
  while (millis() - start &amp;lt; 10000) {&lt;br /&gt;
    if (Serial.available()) {&lt;br /&gt;
      char c = Serial.read();&lt;br /&gt;
      if (c == &amp;#039;t&amp;#039;) {&lt;br /&gt;
        modeTest = true;&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
      if (c == &amp;#039;h&amp;#039;) {&lt;br /&gt;
        modeTest = false;&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  if (modeTest) {&lt;br /&gt;
    testOffset();&lt;br /&gt;
  } else {&lt;br /&gt;
    afficherHorloge();&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ---- Fonction horloge ----&lt;br /&gt;
void afficherHorloge() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  int hrX = CENTER_X + (RADIUS - 20) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY = CENTER_Y + (RADIUS - 20) * sin((hrAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 10) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 10) * sin((minAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 45, 12 + Y_OFFSET, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y + Y_OFFSET, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 5 + Y_OFFSET, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 10, CENTER_Y + 4 + Y_OFFSET, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 12 + Y_OFFSET, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 12, CENTER_Y + 4 + Y_OFFSET, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, hrX, hrY);&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, minX, minY);&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, secX, secY);&lt;br /&gt;
&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB14_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 30, 120 + Y_OFFSET, bufferTime);&lt;br /&gt;
&lt;br /&gt;
  u8g2.sendBuffer();&lt;br /&gt;
  delay(1000);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ---- Fonction utilitaire test offset ----&lt;br /&gt;
void testOffset() {&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
&lt;br /&gt;
  u8g2.drawLine(0, CENTER_Y, 128, CENTER_Y);             // sans offset&lt;br /&gt;
  u8g2.drawLine(0, CENTER_Y + Y_OFFSET, 128, CENTER_Y + Y_OFFSET); // avec offset&lt;br /&gt;
&lt;br /&gt;
  u8g2.drawStr(10, CENTER_Y - 5, &amp;quot;Sans offset&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(10, CENTER_Y + Y_OFFSET - 5, &amp;quot;Avec offset&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  u8g2.sendBuffer();&lt;br /&gt;
  delay(1000);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ---- Récupération heure locale ----&lt;br /&gt;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1;&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X128 OLED 5 Tool ===&lt;br /&gt;
&lt;br /&gt;
Tu verras deux lignes horizontales sur ton écran :&amp;lt;br&amp;gt;&lt;br /&gt;
Une ligne au centre (sans correction).&amp;lt;br&amp;gt;&lt;br /&gt;
Une ligne décalée de Y_OFFSET pixels (avec correction).&amp;lt;br&amp;gt;&lt;br /&gt;
Les textes « Sans offset » et « Avec offset » t’indiquent quelle ligne correspond à quoi.&amp;lt;br&amp;gt;&lt;br /&gt;
Si la ligne corrigée est bien alignée avec ce que tu attends, tu sais que ton Y_OFFSET est correct.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;Wire.h&amp;gt;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- Sélection écran ----&lt;br /&gt;
#define SCREEN_SH1107&lt;br /&gt;
// #define SCREEN_SSD1327&lt;br /&gt;
&lt;br /&gt;
// ---- OLED Grove 1.12&amp;quot; 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;
// ---- Correction Y selon écran ----&lt;br /&gt;
int Y_OFFSET = 0;&lt;br /&gt;
&lt;br /&gt;
// ---- Centre écran ----&lt;br /&gt;
const int CENTER_X = 64;&lt;br /&gt;
const int CENTER_Y = 64;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Choix offset selon écran&lt;br /&gt;
  #ifdef SCREEN_SH1107&lt;br /&gt;
    Y_OFFSET = 16;   // correction typique pour SH1107&lt;br /&gt;
  #endif&lt;br /&gt;
  #ifdef SCREEN_SSD1327&lt;br /&gt;
    Y_OFFSET = 0;    // pas besoin de correction&lt;br /&gt;
  #endif&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
&lt;br /&gt;
  // Ligne horizontale sans offset&lt;br /&gt;
  u8g2.drawLine(0, CENTER_Y, 128, CENTER_Y);&lt;br /&gt;
  u8g2.drawStr(10, CENTER_Y - 5, &amp;quot;Sans offset&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Ligne horizontale avec offset&lt;br /&gt;
  u8g2.drawLine(0, CENTER_Y + Y_OFFSET, 128, CENTER_Y + Y_OFFSET);&lt;br /&gt;
  u8g2.drawStr(10, CENTER_Y + Y_OFFSET - 5, &amp;quot;Avec offset&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  u8g2.sendBuffer();&lt;br /&gt;
&lt;br /&gt;
  delay(1000);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128×64 OLED 6 ===&lt;br /&gt;
&lt;br /&gt;
Centre déplacé à (64, 32) pour un écran 128×64.&amp;lt;br&amp;gt;&lt;br /&gt;
Rayon réduit à 28 pour que le cadran tienne bien.&amp;lt;br&amp;gt;&lt;br /&gt;
Positions des textes ajustées (y=10 pour la date, y=58 pour l’heure digitale).&amp;lt;br&amp;gt;&lt;br /&gt;
Constructeur U8g2 changé pour SSD1308/SSD1315.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED 128x64 SSD1308/SSD1315 ----&lt;br /&gt;
// Choisis le constructeur selon ton écran&lt;br /&gt;
U8G2_SSD1315_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);&lt;br /&gt;
&lt;br /&gt;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
// ---- Cadran ----&lt;br /&gt;
const int CENTER_X = 64;   // centre écran&lt;br /&gt;
const int CENTER_Y = 32;   // moitié de 64&lt;br /&gt;
const int RADIUS   = 28;   // adapté à la hauteur&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse)&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  // ---- Calcul des angles ----&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  // ---- Positions des aiguilles ----&lt;br /&gt;
  int hrX = CENTER_X + (RADIUS - 8) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY = CENTER_Y + (RADIUS - 8) * sin((hrAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 4) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 4) * sin((minAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage jour + date en haut ----&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(5, 10, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  // Cadran principal&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  // Chiffres 12-3-6-9&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 2, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 6, CENTER_Y + 4, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 10, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 10, CENTER_Y + 4, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Aiguilles&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, hrX, hrY);&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, minX, minY);&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, secX, secY);&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage digital en bas ----&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB14_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 30, 58, bufferTime);&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;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1;&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128×64 OLED 7 ===&lt;br /&gt;
&lt;br /&gt;
💻 Code compact (SSD1308/SSD1315, 128×64)&lt;br /&gt;
&lt;br /&gt;
Dans cette version, on supprime le cadran analogique et on affiche uniquement la date en haut et l’heure digitale bien centrée en bas. Cela exploite mieux la petite hauteur de l’écran.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Date + jour en haut (petite police).&amp;lt;br&amp;gt;&lt;br /&gt;
Heure digitale en bas, bien grande et centrée (u8g2_font_ncenB24_tr).&amp;lt;br&amp;gt;&lt;br /&gt;
Pas de cadran analogique → affichage clair et lisible sur un petit écran.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;ceci fonctionne mais le jours est superposé avec l&amp;#039;heure&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;Wire.h&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED 128x64 SSD1308/SSD1315 ----&lt;br /&gt;
// Choisis le constructeur selon ton écran&lt;br /&gt;
U8G2_SSD1315_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);&lt;br /&gt;
&lt;br /&gt;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse)&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // Affichage jour + date en haut&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(5, 12, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  // Affichage digital centré en bas&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB24_tr); // grande police pour l&amp;#039;heure&lt;br /&gt;
  u8g2.drawStr(20, 55, bufferTime);&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;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1;&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X64 OLED 7.1 Tool ===&lt;br /&gt;
&lt;br /&gt;
Calcul de la hauteur et largeur d&amp;#039;un texte avec une sortie du résultat sur le &amp;lt;b&amp;gt;port série&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Police 6x13 -&amp;gt; Hauteur=13 px, Largeur max char=6 px, &amp;lt;br&amp;gt;&lt;br /&gt;
Largeur &amp;#039;12:34:56&amp;#039;=48 px, Largeur &amp;#039;Vendredi, 14/11/2025&amp;#039;=114 px&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Police ncenB14 -&amp;gt; Hauteur=14 px, Largeur max char=14 px, &amp;lt;br&amp;gt;&lt;br /&gt;
Largeur &amp;#039;12:34:56&amp;#039;=84 px, Largeur &amp;#039;Vendredi, 14/11/2025&amp;#039;=168 px&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Police ncenB18 -&amp;gt; Hauteur=18 px, Largeur max char=18 px, &amp;lt;br&amp;gt;&lt;br /&gt;
Largeur &amp;#039;12:34:56&amp;#039;=108 px, Largeur &amp;#039;Vendredi, 14/11/2025&amp;#039;=216 px&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Police ncenB24 -&amp;gt; Hauteur=24 px, Largeur max char=24 px, &amp;lt;br&amp;gt;&lt;br /&gt;
Largeur &amp;#039;12:34:56&amp;#039;=144 px, Largeur &amp;#039;Vendredi, 14/11/2025&amp;#039;=288 px&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
🖥️ Exemple de code de test (heure + date)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;Wire.h&amp;gt;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
U8G2_SSD1315_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
&lt;br /&gt;
  // Test avec plusieurs polices&lt;br /&gt;
  testFont(u8g2_font_6x13_tr, &amp;quot;6x13&amp;quot;);&lt;br /&gt;
  testFont(u8g2_font_ncenB14_tr, &amp;quot;ncenB14&amp;quot;);&lt;br /&gt;
  testFont(u8g2_font_ncenB18_tr, &amp;quot;ncenB18&amp;quot;);&lt;br /&gt;
  testFont(u8g2_font_ncenB24_tr, &amp;quot;ncenB24&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  // rien à faire en boucle&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void testFont(const uint8_t* font, const char* name) {&lt;br /&gt;
  u8g2.setFont(font);&lt;br /&gt;
&lt;br /&gt;
  // Hauteur et largeur max d’un caractère&lt;br /&gt;
  int h = u8g2.getMaxCharHeight();&lt;br /&gt;
  int wChar = u8g2.getMaxCharWidth();&lt;br /&gt;
&lt;br /&gt;
  // Largeur d’un exemple d’heure&lt;br /&gt;
  int wTime = u8g2.getStrWidth(&amp;quot;12:34:56&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Largeur d’un exemple de jour + date&lt;br /&gt;
  int wDate = u8g2.getStrWidth(&amp;quot;Vendredi, 14/11/2025&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;Police %s -&amp;gt; Hauteur=%d px, Largeur max char=%d px, Largeur &amp;#039;12:34:56&amp;#039;=%d px, Largeur &amp;#039;Vendredi, 14/11/2025&amp;#039;=%d px\n&amp;quot;,&lt;br /&gt;
                name, h, wChar, wTime, wDate);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X64 OLED 7.2 ===&lt;br /&gt;
&lt;br /&gt;
Les marges hautes et basses en % de la hauteur de l’écran.&amp;lt;br&amp;gt;&lt;br /&gt;
Le choix automatique de la police pour l’heure en fonction de l’espace disponible.&amp;lt;br&amp;gt;&lt;br /&gt;
Le centrage horizontal de l’heure.&amp;lt;br&amp;gt;&lt;br /&gt;
La date en haut avec une police adaptée.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED 128x64 SSD1308/SSD1315 ----&lt;br /&gt;
U8G2_SSD1315_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);&lt;br /&gt;
&lt;br /&gt;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
// ---- Paramètres écran ----&lt;br /&gt;
const int LARGEUR_ECRAN = 128;&lt;br /&gt;
const int HAUTEUR_ECRAN = 64;&lt;br /&gt;
&lt;br /&gt;
// ---- Marges en % ----&lt;br /&gt;
const float MARGE_HAUT_PCT = 0.10; // 10%&lt;br /&gt;
const float MARGE_BAS_PCT  = 0.10; // 10%&lt;br /&gt;
&lt;br /&gt;
// ---- Polices disponibles pour l&amp;#039;heure ----&lt;br /&gt;
const uint8_t* FONT_SMALL  = u8g2_font_ncenB14_tr; // ~14 px&lt;br /&gt;
const uint8_t* FONT_MEDIUM = u8g2_font_ncenB18_tr; // ~18 px&lt;br /&gt;
const uint8_t* FONT_LARGE  = u8g2_font_ncenB24_tr; // ~24 px&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse)&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // Calcul des marges en pixels&lt;br /&gt;
  int margeHaut = (int)(HAUTEUR_ECRAN * MARGE_HAUT_PCT);&lt;br /&gt;
  int margeBas  = (int)(HAUTEUR_ECRAN * MARGE_BAS_PCT);&lt;br /&gt;
  int hauteurUtile = HAUTEUR_ECRAN - (margeHaut + margeBas);&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage jour + date en haut ----&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(5, margeHaut + 12, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  // ---- Choix automatique de la police pour l&amp;#039;heure ----&lt;br /&gt;
  const uint8_t* fontChoisie;&lt;br /&gt;
  if (hauteurUtile &amp;gt;= 24) {&lt;br /&gt;
    fontChoisie = FONT_LARGE;   // assez de place pour 24 px&lt;br /&gt;
  } else if (hauteurUtile &amp;gt;= 18) {&lt;br /&gt;
    fontChoisie = FONT_MEDIUM;  // assez de place pour 18 px&lt;br /&gt;
  } else {&lt;br /&gt;
    fontChoisie = FONT_SMALL;   // sinon police plus petite&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage digital centré en bas ----&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(fontChoisie);&lt;br /&gt;
&lt;br /&gt;
  // Centrage horizontal&lt;br /&gt;
  int largeur = u8g2.getStrWidth(bufferTime);&lt;br /&gt;
  int x = (LARGEUR_ECRAN - largeur) / 2;&lt;br /&gt;
&lt;br /&gt;
  // Ligne de base juste avant la marge basse&lt;br /&gt;
  int y = HAUTEUR_ECRAN - margeBas;&lt;br /&gt;
&lt;br /&gt;
  u8g2.drawStr(x, y, bufferTime);&lt;br /&gt;
&lt;br /&gt;
  u8g2.sendBuffer();&lt;br /&gt;
  delay(1000);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1;&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X64 OLED 8 ===&lt;br /&gt;
&lt;br /&gt;
💻 Code : seulement le cadran analogique&amp;lt;br&amp;gt; fonctionne mais illisible on dirait 2 ovales ! mais on peut voir les aguilles &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Un cadran analogique avec les chiffres 12‑3‑6‑9.&amp;lt;br&amp;gt;&lt;br /&gt;
Trois aiguilles (heures, minutes, secondes).&amp;lt;br&amp;gt;&lt;br /&gt;
Pas de date ni d’heure digitale → affichage épuré.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED 128x64 SSD1308/SSD1315 ----&lt;br /&gt;
U8G2_SSD1315_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);&lt;br /&gt;
&lt;br /&gt;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
&lt;br /&gt;
// ---- Cadran ----&lt;br /&gt;
const int CENTER_X = 64;   // centre écran&lt;br /&gt;
const int CENTER_Y = 32;   // moitié de 64&lt;br /&gt;
const int RADIUS   = 28;   // adapté à la hauteur&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse)&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  // ---- Calcul des angles ----&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  // ---- Positions des aiguilles ----&lt;br /&gt;
  int hrX = CENTER_X + (RADIUS - 8) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY = CENTER_Y + (RADIUS - 8) * sin((hrAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 4) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 4) * sin((minAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // Cadran principal&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  // Chiffres 12-3-6-9&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 2, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 6, CENTER_Y + 4, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 10, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 10, CENTER_Y + 4, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Aiguilles&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, hrX, hrY);   // heures&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, minX, minY); // minutes&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, secX, secY); // secondes&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;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%02d:%02d:%02d\n&amp;quot;, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>144.2.107.134</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.myows.top/index.php?title=Analog_Clock_OLED&amp;diff=1845</id>
		<title>Analog Clock OLED</title>
		<link rel="alternate" type="text/html" href="https://wiki.myows.top/index.php?title=Analog_Clock_OLED&amp;diff=1845"/>
		<updated>2025-11-14T23:16:13Z</updated>

		<summary type="html">&lt;p&gt;144.2.107.134: /* Analog Clock OLED 1 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Analog Clock 128X128 OLED 1 ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED Grove 1.12&amp;quot; SH1107 ----&lt;br /&gt;
// U8G2_SH1107_PIMAR_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);&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;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
// ---- Cadran ----&lt;br /&gt;
const int CENTER_X = 64;   // centre écran&lt;br /&gt;
const int CENTER_Y = 64;&lt;br /&gt;
const int RADIUS   = 55;   // grand rayon pour 128x128&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse) avec gestion automatique du DST&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  // ---- Calcul des angles ----&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  // ---- Positions des aiguilles ----&lt;br /&gt;
  int hrX = CENTER_X + (RADIUS - 20) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY = CENTER_Y + (RADIUS - 20) * sin((hrAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 10) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 10) * sin((minAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage jour + date en haut ----&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 45, 12, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  // Cadran principal&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  // Chiffres 12-3-6-9&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 5, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 10, CENTER_Y + 4, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 12, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 12, CENTER_Y + 4, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Aiguilles&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, hrX, hrY);   // heures&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, minX, minY); // minutes&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, secX, secY); // secondes&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage digital en bas ----&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB14_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 30, 120, bufferTime);&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;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1; // tm_mon commence à 0&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;    // jour de la semaine (0 = dimanche)&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X128 OLED 2 ===&lt;br /&gt;
&lt;br /&gt;
Ajout de const int Y_OFFSET = 16;&amp;lt;br&amp;gt;&lt;br /&gt;
Application de + Y_OFFSET sur toutes les coordonnées Y (drawStr, drawLine, drawCircle, calcul des aiguilles).&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;pas vraiment, il semble avoir un problème avec l&amp;#039;offset négatif ou positif, on a légèrement un affichage.&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;Wire.h&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED Grove 1.12&amp;quot; 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;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
// ---- Cadran ----&lt;br /&gt;
const int CENTER_X = 64;   // centre écran&lt;br /&gt;
const int CENTER_Y = 64;&lt;br /&gt;
const int RADIUS   = 55;   // grand rayon pour 128x128&lt;br /&gt;
&lt;br /&gt;
// ---- Correction Y pour SH1107 ----&lt;br /&gt;
const int Y_OFFSET = 16;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse) avec gestion automatique du DST&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  // ---- Calcul des angles ----&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  // ---- Positions des aiguilles ----&lt;br /&gt;
  int hrX = CENTER_X + (RADIUS - 20) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY = CENTER_Y + (RADIUS - 20) * sin((hrAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 10) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 10) * sin((minAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage jour + date en haut ----&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 45, 12 + Y_OFFSET, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  // Cadran principal&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y + Y_OFFSET, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  // Chiffres 12-3-6-9&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 5 + Y_OFFSET, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 10, CENTER_Y + 4 + Y_OFFSET, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 12 + Y_OFFSET, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 12, CENTER_Y + 4 + Y_OFFSET, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Aiguilles&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, hrX, hrY);   // heures&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, minX, minY); // minutes&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, secX, secY); // secondes&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage digital en bas ----&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB14_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 30, 120 + Y_OFFSET, bufferTime);&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;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1; // tm_mon commence à 0&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;    // jour de la semaine (0 = dimanche)&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X128 OLED 3 ===&lt;br /&gt;
&lt;br /&gt;
Si tu utilises SH1107, laisse #define SCREEN_SH1107 actif → offset = 16.&amp;lt;br&amp;gt;&lt;br /&gt;
Si tu passes à SSD1327, commente SCREEN_SH1107 et décommente SCREEN_SSD1327 → offset = 0.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- Sélection écran ----&lt;br /&gt;
// Décommente la ligne correspondant à ton écran&lt;br /&gt;
#define SCREEN_SH1107&lt;br /&gt;
// #define SCREEN_SSD1327&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED Grove 1.12&amp;quot; SH1107 ----&lt;br /&gt;
// (Même constructeur pour SSD1327, mais offset différent)&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;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
// ---- Cadran ----&lt;br /&gt;
const int CENTER_X = 64;   // centre écran&lt;br /&gt;
const int CENTER_Y = 64;&lt;br /&gt;
const int RADIUS   = 55;   // grand rayon pour 128x128&lt;br /&gt;
&lt;br /&gt;
// ---- Correction Y selon écran ----&lt;br /&gt;
int Y_OFFSET = 0;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Choix offset selon écran&lt;br /&gt;
  #ifdef SCREEN_SH1107&lt;br /&gt;
    Y_OFFSET = 16;   // correction typique pour SH1107&lt;br /&gt;
  #endif&lt;br /&gt;
&lt;br /&gt;
  #ifdef SCREEN_SSD1327&lt;br /&gt;
    Y_OFFSET = 0;    // pas besoin de correction&lt;br /&gt;
  #endif&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse) avec gestion automatique du DST&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  // ---- Calcul des angles ----&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  // ---- Positions des aiguilles ----&lt;br /&gt;
  int hrX = CENTER_X + (RADIUS - 20) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY = CENTER_Y + (RADIUS - 20) * sin((hrAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 10) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 10) * sin((minAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage jour + date en haut ----&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 45, 12 + Y_OFFSET, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  // Cadran principal&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y + Y_OFFSET, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  // Chiffres 12-3-6-9&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 5 + Y_OFFSET, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 10, CENTER_Y + 4 + Y_OFFSET, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 12 + Y_OFFSET, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 12, CENTER_Y + 4 + Y_OFFSET, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Aiguilles&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, hrX, hrY);   // heures&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, minX, minY); // minutes&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, secX, secY); // secondes&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage digital en bas ----&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB14_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 30, 120 + Y_OFFSET, bufferTime);&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;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1; // tm_mon commence à 0&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;    // jour de la semaine (0 = dimanche)&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X128 OLED 4 ===&lt;br /&gt;
&lt;br /&gt;
Au démarrage → attend 10 secondes une commande série.&amp;lt;br&amp;gt;&lt;br /&gt;
Si tu tapes t → mode test offset (lignes horizontales).&amp;lt;br&amp;gt;&lt;br /&gt;
Si tu tapes h → mode horloge.&amp;lt;br&amp;gt;&lt;br /&gt;
Si rien n’est tapé → après 10 secondes → mode horloge par défaut.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- Sélection écran ----&lt;br /&gt;
#define SCREEN_SH1107&lt;br /&gt;
// #define SCREEN_SSD1327&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED Grove 1.12&amp;quot; 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;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
// ---- Cadran ----&lt;br /&gt;
const int CENTER_X = 64;&lt;br /&gt;
const int CENTER_Y = 64;&lt;br /&gt;
const int RADIUS   = 55;&lt;br /&gt;
&lt;br /&gt;
// ---- Correction Y selon écran ----&lt;br /&gt;
int Y_OFFSET = 0;&lt;br /&gt;
&lt;br /&gt;
// ---- Mode ----&lt;br /&gt;
bool modeTest = false;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Choix offset selon écran&lt;br /&gt;
  #ifdef SCREEN_SH1107&lt;br /&gt;
    Y_OFFSET = 16;&lt;br /&gt;
  #endif&lt;br /&gt;
  #ifdef SCREEN_SSD1327&lt;br /&gt;
    Y_OFFSET = 0;&lt;br /&gt;
  #endif&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse)&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
&lt;br /&gt;
  // ---- Attente commande série pendant 10s ----&lt;br /&gt;
  Serial.println(&amp;quot;Tapez &amp;#039;t&amp;#039; pour mode test offset, &amp;#039;h&amp;#039; pour horloge. Sinon horloge par défaut après 10s.&amp;quot;);&lt;br /&gt;
  unsigned long start = millis();&lt;br /&gt;
  while (millis() - start &amp;lt; 10000) {&lt;br /&gt;
    if (Serial.available()) {&lt;br /&gt;
      char c = Serial.read();&lt;br /&gt;
      if (c == &amp;#039;t&amp;#039;) {&lt;br /&gt;
        modeTest = true;&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
      if (c == &amp;#039;h&amp;#039;) {&lt;br /&gt;
        modeTest = false;&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  if (modeTest) {&lt;br /&gt;
    testOffset();&lt;br /&gt;
  } else {&lt;br /&gt;
    afficherHorloge();&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ---- Fonction horloge ----&lt;br /&gt;
void afficherHorloge() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  int hrX = CENTER_X + (RADIUS - 20) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY = CENTER_Y + (RADIUS - 20) * sin((hrAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 10) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 10) * sin((minAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 45, 12 + Y_OFFSET, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y + Y_OFFSET, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 5 + Y_OFFSET, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 10, CENTER_Y + 4 + Y_OFFSET, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 12 + Y_OFFSET, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 12, CENTER_Y + 4 + Y_OFFSET, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, hrX, hrY);&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, minX, minY);&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, secX, secY);&lt;br /&gt;
&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB14_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 30, 120 + Y_OFFSET, bufferTime);&lt;br /&gt;
&lt;br /&gt;
  u8g2.sendBuffer();&lt;br /&gt;
  delay(1000);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ---- Fonction utilitaire test offset ----&lt;br /&gt;
void testOffset() {&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
&lt;br /&gt;
  u8g2.drawLine(0, CENTER_Y, 128, CENTER_Y);             // sans offset&lt;br /&gt;
  u8g2.drawLine(0, CENTER_Y + Y_OFFSET, 128, CENTER_Y + Y_OFFSET); // avec offset&lt;br /&gt;
&lt;br /&gt;
  u8g2.drawStr(10, CENTER_Y - 5, &amp;quot;Sans offset&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(10, CENTER_Y + Y_OFFSET - 5, &amp;quot;Avec offset&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  u8g2.sendBuffer();&lt;br /&gt;
  delay(1000);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ---- Récupération heure locale ----&lt;br /&gt;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1;&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X128 OLED 5 Tool ===&lt;br /&gt;
&lt;br /&gt;
Tu verras deux lignes horizontales sur ton écran :&amp;lt;br&amp;gt;&lt;br /&gt;
Une ligne au centre (sans correction).&amp;lt;br&amp;gt;&lt;br /&gt;
Une ligne décalée de Y_OFFSET pixels (avec correction).&amp;lt;br&amp;gt;&lt;br /&gt;
Les textes « Sans offset » et « Avec offset » t’indiquent quelle ligne correspond à quoi.&amp;lt;br&amp;gt;&lt;br /&gt;
Si la ligne corrigée est bien alignée avec ce que tu attends, tu sais que ton Y_OFFSET est correct.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;Wire.h&amp;gt;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- Sélection écran ----&lt;br /&gt;
#define SCREEN_SH1107&lt;br /&gt;
// #define SCREEN_SSD1327&lt;br /&gt;
&lt;br /&gt;
// ---- OLED Grove 1.12&amp;quot; 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;
// ---- Correction Y selon écran ----&lt;br /&gt;
int Y_OFFSET = 0;&lt;br /&gt;
&lt;br /&gt;
// ---- Centre écran ----&lt;br /&gt;
const int CENTER_X = 64;&lt;br /&gt;
const int CENTER_Y = 64;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Choix offset selon écran&lt;br /&gt;
  #ifdef SCREEN_SH1107&lt;br /&gt;
    Y_OFFSET = 16;   // correction typique pour SH1107&lt;br /&gt;
  #endif&lt;br /&gt;
  #ifdef SCREEN_SSD1327&lt;br /&gt;
    Y_OFFSET = 0;    // pas besoin de correction&lt;br /&gt;
  #endif&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
&lt;br /&gt;
  // Ligne horizontale sans offset&lt;br /&gt;
  u8g2.drawLine(0, CENTER_Y, 128, CENTER_Y);&lt;br /&gt;
  u8g2.drawStr(10, CENTER_Y - 5, &amp;quot;Sans offset&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Ligne horizontale avec offset&lt;br /&gt;
  u8g2.drawLine(0, CENTER_Y + Y_OFFSET, 128, CENTER_Y + Y_OFFSET);&lt;br /&gt;
  u8g2.drawStr(10, CENTER_Y + Y_OFFSET - 5, &amp;quot;Avec offset&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  u8g2.sendBuffer();&lt;br /&gt;
&lt;br /&gt;
  delay(1000);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128×64 OLED 6 ===&lt;br /&gt;
&lt;br /&gt;
Centre déplacé à (64, 32) pour un écran 128×64.&amp;lt;br&amp;gt;&lt;br /&gt;
Rayon réduit à 28 pour que le cadran tienne bien.&amp;lt;br&amp;gt;&lt;br /&gt;
Positions des textes ajustées (y=10 pour la date, y=58 pour l’heure digitale).&amp;lt;br&amp;gt;&lt;br /&gt;
Constructeur U8g2 changé pour SSD1308/SSD1315.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED 128x64 SSD1308/SSD1315 ----&lt;br /&gt;
// Choisis le constructeur selon ton écran&lt;br /&gt;
U8G2_SSD1315_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);&lt;br /&gt;
&lt;br /&gt;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
// ---- Cadran ----&lt;br /&gt;
const int CENTER_X = 64;   // centre écran&lt;br /&gt;
const int CENTER_Y = 32;   // moitié de 64&lt;br /&gt;
const int RADIUS   = 28;   // adapté à la hauteur&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse)&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  // ---- Calcul des angles ----&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  // ---- Positions des aiguilles ----&lt;br /&gt;
  int hrX = CENTER_X + (RADIUS - 8) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY = CENTER_Y + (RADIUS - 8) * sin((hrAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 4) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 4) * sin((minAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage jour + date en haut ----&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(5, 10, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  // Cadran principal&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  // Chiffres 12-3-6-9&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 2, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 6, CENTER_Y + 4, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 10, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 10, CENTER_Y + 4, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Aiguilles&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, hrX, hrY);&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, minX, minY);&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, secX, secY);&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage digital en bas ----&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB14_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 30, 58, bufferTime);&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;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1;&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128×64 OLED 7 ===&lt;br /&gt;
&lt;br /&gt;
💻 Code compact (SSD1308/SSD1315, 128×64)&lt;br /&gt;
&lt;br /&gt;
Dans cette version, on supprime le cadran analogique et on affiche uniquement la date en haut et l’heure digitale bien centrée en bas. Cela exploite mieux la petite hauteur de l’écran.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Date + jour en haut (petite police).&amp;lt;br&amp;gt;&lt;br /&gt;
Heure digitale en bas, bien grande et centrée (u8g2_font_ncenB24_tr).&amp;lt;br&amp;gt;&lt;br /&gt;
Pas de cadran analogique → affichage clair et lisible sur un petit écran.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;ceci fonctionne mais le jours est superposé avec l&amp;#039;heure&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;Wire.h&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED 128x64 SSD1308/SSD1315 ----&lt;br /&gt;
// Choisis le constructeur selon ton écran&lt;br /&gt;
U8G2_SSD1315_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);&lt;br /&gt;
&lt;br /&gt;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse)&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // Affichage jour + date en haut&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(5, 12, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  // Affichage digital centré en bas&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB24_tr); // grande police pour l&amp;#039;heure&lt;br /&gt;
  u8g2.drawStr(20, 55, bufferTime);&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;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1;&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X64 OLED 7.1 Tool ===&lt;br /&gt;
&lt;br /&gt;
Calcul de la hauteur et largeur d&amp;#039;un texte avec une sortie du résultat sur le &amp;lt;b&amp;gt;port série&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Police 6x13 -&amp;gt; Hauteur=13 px, Largeur max char=6 px, &amp;lt;br&amp;gt;&lt;br /&gt;
Largeur &amp;#039;12:34:56&amp;#039;=48 px, Largeur &amp;#039;Vendredi, 14/11/2025&amp;#039;=114 px&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Police ncenB14 -&amp;gt; Hauteur=14 px, Largeur max char=14 px, &amp;lt;br&amp;gt;&lt;br /&gt;
Largeur &amp;#039;12:34:56&amp;#039;=84 px, Largeur &amp;#039;Vendredi, 14/11/2025&amp;#039;=168 px&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Police ncenB18 -&amp;gt; Hauteur=18 px, Largeur max char=18 px, &amp;lt;br&amp;gt;&lt;br /&gt;
Largeur &amp;#039;12:34:56&amp;#039;=108 px, Largeur &amp;#039;Vendredi, 14/11/2025&amp;#039;=216 px&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Police ncenB24 -&amp;gt; Hauteur=24 px, Largeur max char=24 px, &amp;lt;br&amp;gt;&lt;br /&gt;
Largeur &amp;#039;12:34:56&amp;#039;=144 px, Largeur &amp;#039;Vendredi, 14/11/2025&amp;#039;=288 px&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
🖥️ Exemple de code de test (heure + date)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;Wire.h&amp;gt;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
U8G2_SSD1315_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
&lt;br /&gt;
  // Test avec plusieurs polices&lt;br /&gt;
  testFont(u8g2_font_6x13_tr, &amp;quot;6x13&amp;quot;);&lt;br /&gt;
  testFont(u8g2_font_ncenB14_tr, &amp;quot;ncenB14&amp;quot;);&lt;br /&gt;
  testFont(u8g2_font_ncenB18_tr, &amp;quot;ncenB18&amp;quot;);&lt;br /&gt;
  testFont(u8g2_font_ncenB24_tr, &amp;quot;ncenB24&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  // rien à faire en boucle&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void testFont(const uint8_t* font, const char* name) {&lt;br /&gt;
  u8g2.setFont(font);&lt;br /&gt;
&lt;br /&gt;
  // Hauteur et largeur max d’un caractère&lt;br /&gt;
  int h = u8g2.getMaxCharHeight();&lt;br /&gt;
  int wChar = u8g2.getMaxCharWidth();&lt;br /&gt;
&lt;br /&gt;
  // Largeur d’un exemple d’heure&lt;br /&gt;
  int wTime = u8g2.getStrWidth(&amp;quot;12:34:56&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Largeur d’un exemple de jour + date&lt;br /&gt;
  int wDate = u8g2.getStrWidth(&amp;quot;Vendredi, 14/11/2025&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;Police %s -&amp;gt; Hauteur=%d px, Largeur max char=%d px, Largeur &amp;#039;12:34:56&amp;#039;=%d px, Largeur &amp;#039;Vendredi, 14/11/2025&amp;#039;=%d px\n&amp;quot;,&lt;br /&gt;
                name, h, wChar, wTime, wDate);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X64 OLED 7.2 ===&lt;br /&gt;
&lt;br /&gt;
Les marges hautes et basses en % de la hauteur de l’écran.&amp;lt;br&amp;gt;&lt;br /&gt;
Le choix automatique de la police pour l’heure en fonction de l’espace disponible.&amp;lt;br&amp;gt;&lt;br /&gt;
Le centrage horizontal de l’heure.&amp;lt;br&amp;gt;&lt;br /&gt;
La date en haut avec une police adaptée.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED 128x64 SSD1308/SSD1315 ----&lt;br /&gt;
U8G2_SSD1315_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);&lt;br /&gt;
&lt;br /&gt;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
// ---- Paramètres écran ----&lt;br /&gt;
const int LARGEUR_ECRAN = 128;&lt;br /&gt;
const int HAUTEUR_ECRAN = 64;&lt;br /&gt;
&lt;br /&gt;
// ---- Marges en % ----&lt;br /&gt;
const float MARGE_HAUT_PCT = 0.10; // 10%&lt;br /&gt;
const float MARGE_BAS_PCT  = 0.10; // 10%&lt;br /&gt;
&lt;br /&gt;
// ---- Polices disponibles pour l&amp;#039;heure ----&lt;br /&gt;
const uint8_t* FONT_SMALL  = u8g2_font_ncenB14_tr; // ~14 px&lt;br /&gt;
const uint8_t* FONT_MEDIUM = u8g2_font_ncenB18_tr; // ~18 px&lt;br /&gt;
const uint8_t* FONT_LARGE  = u8g2_font_ncenB24_tr; // ~24 px&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse)&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // Calcul des marges en pixels&lt;br /&gt;
  int margeHaut = (int)(HAUTEUR_ECRAN * MARGE_HAUT_PCT);&lt;br /&gt;
  int margeBas  = (int)(HAUTEUR_ECRAN * MARGE_BAS_PCT);&lt;br /&gt;
  int hauteurUtile = HAUTEUR_ECRAN - (margeHaut + margeBas);&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage jour + date en haut ----&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(5, margeHaut + 12, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  // ---- Choix automatique de la police pour l&amp;#039;heure ----&lt;br /&gt;
  const uint8_t* fontChoisie;&lt;br /&gt;
  if (hauteurUtile &amp;gt;= 24) {&lt;br /&gt;
    fontChoisie = FONT_LARGE;   // assez de place pour 24 px&lt;br /&gt;
  } else if (hauteurUtile &amp;gt;= 18) {&lt;br /&gt;
    fontChoisie = FONT_MEDIUM;  // assez de place pour 18 px&lt;br /&gt;
  } else {&lt;br /&gt;
    fontChoisie = FONT_SMALL;   // sinon police plus petite&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage digital centré en bas ----&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(fontChoisie);&lt;br /&gt;
&lt;br /&gt;
  // Centrage horizontal&lt;br /&gt;
  int largeur = u8g2.getStrWidth(bufferTime);&lt;br /&gt;
  int x = (LARGEUR_ECRAN - largeur) / 2;&lt;br /&gt;
&lt;br /&gt;
  // Ligne de base juste avant la marge basse&lt;br /&gt;
  int y = HAUTEUR_ECRAN - margeBas;&lt;br /&gt;
&lt;br /&gt;
  u8g2.drawStr(x, y, bufferTime);&lt;br /&gt;
&lt;br /&gt;
  u8g2.sendBuffer();&lt;br /&gt;
  delay(1000);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1;&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X64 OLED 8 ===&lt;br /&gt;
&lt;br /&gt;
💻 Code : seulement le cadran analogique&amp;lt;br&amp;gt; fonctionne mais illisible on dirait 2 ovales ! mais on peut voir les aguilles &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Un cadran analogique avec les chiffres 12‑3‑6‑9.&amp;lt;br&amp;gt;&lt;br /&gt;
Trois aiguilles (heures, minutes, secondes).&amp;lt;br&amp;gt;&lt;br /&gt;
Pas de date ni d’heure digitale → affichage épuré.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED 128x64 SSD1308/SSD1315 ----&lt;br /&gt;
U8G2_SSD1315_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);&lt;br /&gt;
&lt;br /&gt;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
&lt;br /&gt;
// ---- Cadran ----&lt;br /&gt;
const int CENTER_X = 64;   // centre écran&lt;br /&gt;
const int CENTER_Y = 32;   // moitié de 64&lt;br /&gt;
const int RADIUS   = 28;   // adapté à la hauteur&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse)&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  // ---- Calcul des angles ----&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  // ---- Positions des aiguilles ----&lt;br /&gt;
  int hrX = CENTER_X + (RADIUS - 8) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY = CENTER_Y + (RADIUS - 8) * sin((hrAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 4) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 4) * sin((minAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // Cadran principal&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  // Chiffres 12-3-6-9&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 2, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 6, CENTER_Y + 4, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 10, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 10, CENTER_Y + 4, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Aiguilles&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, hrX, hrY);   // heures&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, minX, minY); // minutes&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, secX, secY); // secondes&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;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%02d:%02d:%02d\n&amp;quot;, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>144.2.107.134</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.myows.top/index.php?title=Analog_Clock_OLED&amp;diff=1844</id>
		<title>Analog Clock OLED</title>
		<link rel="alternate" type="text/html" href="https://wiki.myows.top/index.php?title=Analog_Clock_OLED&amp;diff=1844"/>
		<updated>2025-11-14T23:15:46Z</updated>

		<summary type="html">&lt;p&gt;144.2.107.134: /* Analog Clock 128X128 OLED 2 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Analog Clock OLED 1 ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED Grove 1.12&amp;quot; SH1107 ----&lt;br /&gt;
// U8G2_SH1107_PIMAR_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);&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;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
// ---- Cadran ----&lt;br /&gt;
const int CENTER_X = 64;   // centre écran&lt;br /&gt;
const int CENTER_Y = 64;&lt;br /&gt;
const int RADIUS   = 55;   // grand rayon pour 128x128&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse) avec gestion automatique du DST&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  // ---- Calcul des angles ----&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  // ---- Positions des aiguilles ----&lt;br /&gt;
  int hrX = CENTER_X + (RADIUS - 20) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY = CENTER_Y + (RADIUS - 20) * sin((hrAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 10) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 10) * sin((minAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage jour + date en haut ----&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 45, 12, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  // Cadran principal&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  // Chiffres 12-3-6-9&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 5, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 10, CENTER_Y + 4, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 12, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 12, CENTER_Y + 4, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Aiguilles&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, hrX, hrY);   // heures&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, minX, minY); // minutes&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, secX, secY); // secondes&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage digital en bas ----&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB14_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 30, 120, bufferTime);&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;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1; // tm_mon commence à 0&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;    // jour de la semaine (0 = dimanche)&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X128 OLED 2 ===&lt;br /&gt;
&lt;br /&gt;
Ajout de const int Y_OFFSET = 16;&amp;lt;br&amp;gt;&lt;br /&gt;
Application de + Y_OFFSET sur toutes les coordonnées Y (drawStr, drawLine, drawCircle, calcul des aiguilles).&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;pas vraiment, il semble avoir un problème avec l&amp;#039;offset négatif ou positif, on a légèrement un affichage.&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;Wire.h&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED Grove 1.12&amp;quot; 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;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
// ---- Cadran ----&lt;br /&gt;
const int CENTER_X = 64;   // centre écran&lt;br /&gt;
const int CENTER_Y = 64;&lt;br /&gt;
const int RADIUS   = 55;   // grand rayon pour 128x128&lt;br /&gt;
&lt;br /&gt;
// ---- Correction Y pour SH1107 ----&lt;br /&gt;
const int Y_OFFSET = 16;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse) avec gestion automatique du DST&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  // ---- Calcul des angles ----&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  // ---- Positions des aiguilles ----&lt;br /&gt;
  int hrX = CENTER_X + (RADIUS - 20) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY = CENTER_Y + (RADIUS - 20) * sin((hrAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 10) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 10) * sin((minAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage jour + date en haut ----&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 45, 12 + Y_OFFSET, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  // Cadran principal&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y + Y_OFFSET, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  // Chiffres 12-3-6-9&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 5 + Y_OFFSET, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 10, CENTER_Y + 4 + Y_OFFSET, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 12 + Y_OFFSET, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 12, CENTER_Y + 4 + Y_OFFSET, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Aiguilles&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, hrX, hrY);   // heures&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, minX, minY); // minutes&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, secX, secY); // secondes&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage digital en bas ----&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB14_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 30, 120 + Y_OFFSET, bufferTime);&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;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1; // tm_mon commence à 0&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;    // jour de la semaine (0 = dimanche)&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X128 OLED 3 ===&lt;br /&gt;
&lt;br /&gt;
Si tu utilises SH1107, laisse #define SCREEN_SH1107 actif → offset = 16.&amp;lt;br&amp;gt;&lt;br /&gt;
Si tu passes à SSD1327, commente SCREEN_SH1107 et décommente SCREEN_SSD1327 → offset = 0.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- Sélection écran ----&lt;br /&gt;
// Décommente la ligne correspondant à ton écran&lt;br /&gt;
#define SCREEN_SH1107&lt;br /&gt;
// #define SCREEN_SSD1327&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED Grove 1.12&amp;quot; SH1107 ----&lt;br /&gt;
// (Même constructeur pour SSD1327, mais offset différent)&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;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
// ---- Cadran ----&lt;br /&gt;
const int CENTER_X = 64;   // centre écran&lt;br /&gt;
const int CENTER_Y = 64;&lt;br /&gt;
const int RADIUS   = 55;   // grand rayon pour 128x128&lt;br /&gt;
&lt;br /&gt;
// ---- Correction Y selon écran ----&lt;br /&gt;
int Y_OFFSET = 0;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Choix offset selon écran&lt;br /&gt;
  #ifdef SCREEN_SH1107&lt;br /&gt;
    Y_OFFSET = 16;   // correction typique pour SH1107&lt;br /&gt;
  #endif&lt;br /&gt;
&lt;br /&gt;
  #ifdef SCREEN_SSD1327&lt;br /&gt;
    Y_OFFSET = 0;    // pas besoin de correction&lt;br /&gt;
  #endif&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse) avec gestion automatique du DST&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  // ---- Calcul des angles ----&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  // ---- Positions des aiguilles ----&lt;br /&gt;
  int hrX = CENTER_X + (RADIUS - 20) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY = CENTER_Y + (RADIUS - 20) * sin((hrAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 10) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 10) * sin((minAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage jour + date en haut ----&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 45, 12 + Y_OFFSET, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  // Cadran principal&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y + Y_OFFSET, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  // Chiffres 12-3-6-9&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 5 + Y_OFFSET, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 10, CENTER_Y + 4 + Y_OFFSET, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 12 + Y_OFFSET, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 12, CENTER_Y + 4 + Y_OFFSET, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Aiguilles&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, hrX, hrY);   // heures&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, minX, minY); // minutes&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, secX, secY); // secondes&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage digital en bas ----&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB14_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 30, 120 + Y_OFFSET, bufferTime);&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;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1; // tm_mon commence à 0&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;    // jour de la semaine (0 = dimanche)&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X128 OLED 4 ===&lt;br /&gt;
&lt;br /&gt;
Au démarrage → attend 10 secondes une commande série.&amp;lt;br&amp;gt;&lt;br /&gt;
Si tu tapes t → mode test offset (lignes horizontales).&amp;lt;br&amp;gt;&lt;br /&gt;
Si tu tapes h → mode horloge.&amp;lt;br&amp;gt;&lt;br /&gt;
Si rien n’est tapé → après 10 secondes → mode horloge par défaut.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- Sélection écran ----&lt;br /&gt;
#define SCREEN_SH1107&lt;br /&gt;
// #define SCREEN_SSD1327&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED Grove 1.12&amp;quot; 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;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
// ---- Cadran ----&lt;br /&gt;
const int CENTER_X = 64;&lt;br /&gt;
const int CENTER_Y = 64;&lt;br /&gt;
const int RADIUS   = 55;&lt;br /&gt;
&lt;br /&gt;
// ---- Correction Y selon écran ----&lt;br /&gt;
int Y_OFFSET = 0;&lt;br /&gt;
&lt;br /&gt;
// ---- Mode ----&lt;br /&gt;
bool modeTest = false;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Choix offset selon écran&lt;br /&gt;
  #ifdef SCREEN_SH1107&lt;br /&gt;
    Y_OFFSET = 16;&lt;br /&gt;
  #endif&lt;br /&gt;
  #ifdef SCREEN_SSD1327&lt;br /&gt;
    Y_OFFSET = 0;&lt;br /&gt;
  #endif&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse)&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
&lt;br /&gt;
  // ---- Attente commande série pendant 10s ----&lt;br /&gt;
  Serial.println(&amp;quot;Tapez &amp;#039;t&amp;#039; pour mode test offset, &amp;#039;h&amp;#039; pour horloge. Sinon horloge par défaut après 10s.&amp;quot;);&lt;br /&gt;
  unsigned long start = millis();&lt;br /&gt;
  while (millis() - start &amp;lt; 10000) {&lt;br /&gt;
    if (Serial.available()) {&lt;br /&gt;
      char c = Serial.read();&lt;br /&gt;
      if (c == &amp;#039;t&amp;#039;) {&lt;br /&gt;
        modeTest = true;&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
      if (c == &amp;#039;h&amp;#039;) {&lt;br /&gt;
        modeTest = false;&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  if (modeTest) {&lt;br /&gt;
    testOffset();&lt;br /&gt;
  } else {&lt;br /&gt;
    afficherHorloge();&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ---- Fonction horloge ----&lt;br /&gt;
void afficherHorloge() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  int hrX = CENTER_X + (RADIUS - 20) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY = CENTER_Y + (RADIUS - 20) * sin((hrAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 10) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 10) * sin((minAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 45, 12 + Y_OFFSET, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y + Y_OFFSET, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 5 + Y_OFFSET, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 10, CENTER_Y + 4 + Y_OFFSET, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 12 + Y_OFFSET, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 12, CENTER_Y + 4 + Y_OFFSET, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, hrX, hrY);&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, minX, minY);&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, secX, secY);&lt;br /&gt;
&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB14_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 30, 120 + Y_OFFSET, bufferTime);&lt;br /&gt;
&lt;br /&gt;
  u8g2.sendBuffer();&lt;br /&gt;
  delay(1000);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ---- Fonction utilitaire test offset ----&lt;br /&gt;
void testOffset() {&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
&lt;br /&gt;
  u8g2.drawLine(0, CENTER_Y, 128, CENTER_Y);             // sans offset&lt;br /&gt;
  u8g2.drawLine(0, CENTER_Y + Y_OFFSET, 128, CENTER_Y + Y_OFFSET); // avec offset&lt;br /&gt;
&lt;br /&gt;
  u8g2.drawStr(10, CENTER_Y - 5, &amp;quot;Sans offset&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(10, CENTER_Y + Y_OFFSET - 5, &amp;quot;Avec offset&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  u8g2.sendBuffer();&lt;br /&gt;
  delay(1000);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ---- Récupération heure locale ----&lt;br /&gt;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1;&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X128 OLED 5 Tool ===&lt;br /&gt;
&lt;br /&gt;
Tu verras deux lignes horizontales sur ton écran :&amp;lt;br&amp;gt;&lt;br /&gt;
Une ligne au centre (sans correction).&amp;lt;br&amp;gt;&lt;br /&gt;
Une ligne décalée de Y_OFFSET pixels (avec correction).&amp;lt;br&amp;gt;&lt;br /&gt;
Les textes « Sans offset » et « Avec offset » t’indiquent quelle ligne correspond à quoi.&amp;lt;br&amp;gt;&lt;br /&gt;
Si la ligne corrigée est bien alignée avec ce que tu attends, tu sais que ton Y_OFFSET est correct.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;Wire.h&amp;gt;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- Sélection écran ----&lt;br /&gt;
#define SCREEN_SH1107&lt;br /&gt;
// #define SCREEN_SSD1327&lt;br /&gt;
&lt;br /&gt;
// ---- OLED Grove 1.12&amp;quot; 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;
// ---- Correction Y selon écran ----&lt;br /&gt;
int Y_OFFSET = 0;&lt;br /&gt;
&lt;br /&gt;
// ---- Centre écran ----&lt;br /&gt;
const int CENTER_X = 64;&lt;br /&gt;
const int CENTER_Y = 64;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Choix offset selon écran&lt;br /&gt;
  #ifdef SCREEN_SH1107&lt;br /&gt;
    Y_OFFSET = 16;   // correction typique pour SH1107&lt;br /&gt;
  #endif&lt;br /&gt;
  #ifdef SCREEN_SSD1327&lt;br /&gt;
    Y_OFFSET = 0;    // pas besoin de correction&lt;br /&gt;
  #endif&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
&lt;br /&gt;
  // Ligne horizontale sans offset&lt;br /&gt;
  u8g2.drawLine(0, CENTER_Y, 128, CENTER_Y);&lt;br /&gt;
  u8g2.drawStr(10, CENTER_Y - 5, &amp;quot;Sans offset&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Ligne horizontale avec offset&lt;br /&gt;
  u8g2.drawLine(0, CENTER_Y + Y_OFFSET, 128, CENTER_Y + Y_OFFSET);&lt;br /&gt;
  u8g2.drawStr(10, CENTER_Y + Y_OFFSET - 5, &amp;quot;Avec offset&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  u8g2.sendBuffer();&lt;br /&gt;
&lt;br /&gt;
  delay(1000);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128×64 OLED 6 ===&lt;br /&gt;
&lt;br /&gt;
Centre déplacé à (64, 32) pour un écran 128×64.&amp;lt;br&amp;gt;&lt;br /&gt;
Rayon réduit à 28 pour que le cadran tienne bien.&amp;lt;br&amp;gt;&lt;br /&gt;
Positions des textes ajustées (y=10 pour la date, y=58 pour l’heure digitale).&amp;lt;br&amp;gt;&lt;br /&gt;
Constructeur U8g2 changé pour SSD1308/SSD1315.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED 128x64 SSD1308/SSD1315 ----&lt;br /&gt;
// Choisis le constructeur selon ton écran&lt;br /&gt;
U8G2_SSD1315_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);&lt;br /&gt;
&lt;br /&gt;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
// ---- Cadran ----&lt;br /&gt;
const int CENTER_X = 64;   // centre écran&lt;br /&gt;
const int CENTER_Y = 32;   // moitié de 64&lt;br /&gt;
const int RADIUS   = 28;   // adapté à la hauteur&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse)&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  // ---- Calcul des angles ----&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  // ---- Positions des aiguilles ----&lt;br /&gt;
  int hrX = CENTER_X + (RADIUS - 8) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY = CENTER_Y + (RADIUS - 8) * sin((hrAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 4) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 4) * sin((minAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage jour + date en haut ----&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(5, 10, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  // Cadran principal&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  // Chiffres 12-3-6-9&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 2, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 6, CENTER_Y + 4, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 10, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 10, CENTER_Y + 4, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Aiguilles&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, hrX, hrY);&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, minX, minY);&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, secX, secY);&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage digital en bas ----&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB14_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 30, 58, bufferTime);&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;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1;&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128×64 OLED 7 ===&lt;br /&gt;
&lt;br /&gt;
💻 Code compact (SSD1308/SSD1315, 128×64)&lt;br /&gt;
&lt;br /&gt;
Dans cette version, on supprime le cadran analogique et on affiche uniquement la date en haut et l’heure digitale bien centrée en bas. Cela exploite mieux la petite hauteur de l’écran.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Date + jour en haut (petite police).&amp;lt;br&amp;gt;&lt;br /&gt;
Heure digitale en bas, bien grande et centrée (u8g2_font_ncenB24_tr).&amp;lt;br&amp;gt;&lt;br /&gt;
Pas de cadran analogique → affichage clair et lisible sur un petit écran.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;ceci fonctionne mais le jours est superposé avec l&amp;#039;heure&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;Wire.h&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED 128x64 SSD1308/SSD1315 ----&lt;br /&gt;
// Choisis le constructeur selon ton écran&lt;br /&gt;
U8G2_SSD1315_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);&lt;br /&gt;
&lt;br /&gt;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse)&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // Affichage jour + date en haut&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(5, 12, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  // Affichage digital centré en bas&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB24_tr); // grande police pour l&amp;#039;heure&lt;br /&gt;
  u8g2.drawStr(20, 55, bufferTime);&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;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1;&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X64 OLED 7.1 Tool ===&lt;br /&gt;
&lt;br /&gt;
Calcul de la hauteur et largeur d&amp;#039;un texte avec une sortie du résultat sur le &amp;lt;b&amp;gt;port série&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Police 6x13 -&amp;gt; Hauteur=13 px, Largeur max char=6 px, &amp;lt;br&amp;gt;&lt;br /&gt;
Largeur &amp;#039;12:34:56&amp;#039;=48 px, Largeur &amp;#039;Vendredi, 14/11/2025&amp;#039;=114 px&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Police ncenB14 -&amp;gt; Hauteur=14 px, Largeur max char=14 px, &amp;lt;br&amp;gt;&lt;br /&gt;
Largeur &amp;#039;12:34:56&amp;#039;=84 px, Largeur &amp;#039;Vendredi, 14/11/2025&amp;#039;=168 px&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Police ncenB18 -&amp;gt; Hauteur=18 px, Largeur max char=18 px, &amp;lt;br&amp;gt;&lt;br /&gt;
Largeur &amp;#039;12:34:56&amp;#039;=108 px, Largeur &amp;#039;Vendredi, 14/11/2025&amp;#039;=216 px&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Police ncenB24 -&amp;gt; Hauteur=24 px, Largeur max char=24 px, &amp;lt;br&amp;gt;&lt;br /&gt;
Largeur &amp;#039;12:34:56&amp;#039;=144 px, Largeur &amp;#039;Vendredi, 14/11/2025&amp;#039;=288 px&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
🖥️ Exemple de code de test (heure + date)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;Wire.h&amp;gt;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
U8G2_SSD1315_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
&lt;br /&gt;
  // Test avec plusieurs polices&lt;br /&gt;
  testFont(u8g2_font_6x13_tr, &amp;quot;6x13&amp;quot;);&lt;br /&gt;
  testFont(u8g2_font_ncenB14_tr, &amp;quot;ncenB14&amp;quot;);&lt;br /&gt;
  testFont(u8g2_font_ncenB18_tr, &amp;quot;ncenB18&amp;quot;);&lt;br /&gt;
  testFont(u8g2_font_ncenB24_tr, &amp;quot;ncenB24&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  // rien à faire en boucle&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void testFont(const uint8_t* font, const char* name) {&lt;br /&gt;
  u8g2.setFont(font);&lt;br /&gt;
&lt;br /&gt;
  // Hauteur et largeur max d’un caractère&lt;br /&gt;
  int h = u8g2.getMaxCharHeight();&lt;br /&gt;
  int wChar = u8g2.getMaxCharWidth();&lt;br /&gt;
&lt;br /&gt;
  // Largeur d’un exemple d’heure&lt;br /&gt;
  int wTime = u8g2.getStrWidth(&amp;quot;12:34:56&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Largeur d’un exemple de jour + date&lt;br /&gt;
  int wDate = u8g2.getStrWidth(&amp;quot;Vendredi, 14/11/2025&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;Police %s -&amp;gt; Hauteur=%d px, Largeur max char=%d px, Largeur &amp;#039;12:34:56&amp;#039;=%d px, Largeur &amp;#039;Vendredi, 14/11/2025&amp;#039;=%d px\n&amp;quot;,&lt;br /&gt;
                name, h, wChar, wTime, wDate);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X64 OLED 7.2 ===&lt;br /&gt;
&lt;br /&gt;
Les marges hautes et basses en % de la hauteur de l’écran.&amp;lt;br&amp;gt;&lt;br /&gt;
Le choix automatique de la police pour l’heure en fonction de l’espace disponible.&amp;lt;br&amp;gt;&lt;br /&gt;
Le centrage horizontal de l’heure.&amp;lt;br&amp;gt;&lt;br /&gt;
La date en haut avec une police adaptée.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED 128x64 SSD1308/SSD1315 ----&lt;br /&gt;
U8G2_SSD1315_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);&lt;br /&gt;
&lt;br /&gt;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
// ---- Paramètres écran ----&lt;br /&gt;
const int LARGEUR_ECRAN = 128;&lt;br /&gt;
const int HAUTEUR_ECRAN = 64;&lt;br /&gt;
&lt;br /&gt;
// ---- Marges en % ----&lt;br /&gt;
const float MARGE_HAUT_PCT = 0.10; // 10%&lt;br /&gt;
const float MARGE_BAS_PCT  = 0.10; // 10%&lt;br /&gt;
&lt;br /&gt;
// ---- Polices disponibles pour l&amp;#039;heure ----&lt;br /&gt;
const uint8_t* FONT_SMALL  = u8g2_font_ncenB14_tr; // ~14 px&lt;br /&gt;
const uint8_t* FONT_MEDIUM = u8g2_font_ncenB18_tr; // ~18 px&lt;br /&gt;
const uint8_t* FONT_LARGE  = u8g2_font_ncenB24_tr; // ~24 px&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse)&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // Calcul des marges en pixels&lt;br /&gt;
  int margeHaut = (int)(HAUTEUR_ECRAN * MARGE_HAUT_PCT);&lt;br /&gt;
  int margeBas  = (int)(HAUTEUR_ECRAN * MARGE_BAS_PCT);&lt;br /&gt;
  int hauteurUtile = HAUTEUR_ECRAN - (margeHaut + margeBas);&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage jour + date en haut ----&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(5, margeHaut + 12, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  // ---- Choix automatique de la police pour l&amp;#039;heure ----&lt;br /&gt;
  const uint8_t* fontChoisie;&lt;br /&gt;
  if (hauteurUtile &amp;gt;= 24) {&lt;br /&gt;
    fontChoisie = FONT_LARGE;   // assez de place pour 24 px&lt;br /&gt;
  } else if (hauteurUtile &amp;gt;= 18) {&lt;br /&gt;
    fontChoisie = FONT_MEDIUM;  // assez de place pour 18 px&lt;br /&gt;
  } else {&lt;br /&gt;
    fontChoisie = FONT_SMALL;   // sinon police plus petite&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage digital centré en bas ----&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(fontChoisie);&lt;br /&gt;
&lt;br /&gt;
  // Centrage horizontal&lt;br /&gt;
  int largeur = u8g2.getStrWidth(bufferTime);&lt;br /&gt;
  int x = (LARGEUR_ECRAN - largeur) / 2;&lt;br /&gt;
&lt;br /&gt;
  // Ligne de base juste avant la marge basse&lt;br /&gt;
  int y = HAUTEUR_ECRAN - margeBas;&lt;br /&gt;
&lt;br /&gt;
  u8g2.drawStr(x, y, bufferTime);&lt;br /&gt;
&lt;br /&gt;
  u8g2.sendBuffer();&lt;br /&gt;
  delay(1000);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1;&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X64 OLED 8 ===&lt;br /&gt;
&lt;br /&gt;
💻 Code : seulement le cadran analogique&amp;lt;br&amp;gt; fonctionne mais illisible on dirait 2 ovales ! mais on peut voir les aguilles &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Un cadran analogique avec les chiffres 12‑3‑6‑9.&amp;lt;br&amp;gt;&lt;br /&gt;
Trois aiguilles (heures, minutes, secondes).&amp;lt;br&amp;gt;&lt;br /&gt;
Pas de date ni d’heure digitale → affichage épuré.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED 128x64 SSD1308/SSD1315 ----&lt;br /&gt;
U8G2_SSD1315_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);&lt;br /&gt;
&lt;br /&gt;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
&lt;br /&gt;
// ---- Cadran ----&lt;br /&gt;
const int CENTER_X = 64;   // centre écran&lt;br /&gt;
const int CENTER_Y = 32;   // moitié de 64&lt;br /&gt;
const int RADIUS   = 28;   // adapté à la hauteur&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse)&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  // ---- Calcul des angles ----&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  // ---- Positions des aiguilles ----&lt;br /&gt;
  int hrX = CENTER_X + (RADIUS - 8) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY = CENTER_Y + (RADIUS - 8) * sin((hrAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 4) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 4) * sin((minAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // Cadran principal&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  // Chiffres 12-3-6-9&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 2, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 6, CENTER_Y + 4, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 10, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 10, CENTER_Y + 4, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Aiguilles&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, hrX, hrY);   // heures&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, minX, minY); // minutes&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, secX, secY); // secondes&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;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%02d:%02d:%02d\n&amp;quot;, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>144.2.107.134</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.myows.top/index.php?title=Analog_Clock_OLED&amp;diff=1843</id>
		<title>Analog Clock OLED</title>
		<link rel="alternate" type="text/html" href="https://wiki.myows.top/index.php?title=Analog_Clock_OLED&amp;diff=1843"/>
		<updated>2025-11-14T23:15:21Z</updated>

		<summary type="html">&lt;p&gt;144.2.107.134: /* Analog Clock 128X128 OLED 2 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Analog Clock OLED 1 ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED Grove 1.12&amp;quot; SH1107 ----&lt;br /&gt;
// U8G2_SH1107_PIMAR_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);&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;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
// ---- Cadran ----&lt;br /&gt;
const int CENTER_X = 64;   // centre écran&lt;br /&gt;
const int CENTER_Y = 64;&lt;br /&gt;
const int RADIUS   = 55;   // grand rayon pour 128x128&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse) avec gestion automatique du DST&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  // ---- Calcul des angles ----&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  // ---- Positions des aiguilles ----&lt;br /&gt;
  int hrX = CENTER_X + (RADIUS - 20) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY = CENTER_Y + (RADIUS - 20) * sin((hrAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 10) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 10) * sin((minAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage jour + date en haut ----&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 45, 12, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  // Cadran principal&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  // Chiffres 12-3-6-9&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 5, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 10, CENTER_Y + 4, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 12, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 12, CENTER_Y + 4, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Aiguilles&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, hrX, hrY);   // heures&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, minX, minY); // minutes&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, secX, secY); // secondes&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage digital en bas ----&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB14_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 30, 120, bufferTime);&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;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1; // tm_mon commence à 0&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;    // jour de la semaine (0 = dimanche)&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X128 OLED 2 ===&lt;br /&gt;
&lt;br /&gt;
Ajout de const int Y_OFFSET = 16;&amp;lt;br&amp;gt;&lt;br /&gt;
Application de + Y_OFFSET sur toutes les coordonnées Y (drawStr, drawLine, drawCircle, calcul des aiguilles).&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;pas vraiment, il semble avoir un problème avec l&amp;#039;offset négatif ou positif, on a légèrement un affichage&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;Wire.h&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED Grove 1.12&amp;quot; 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;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
// ---- Cadran ----&lt;br /&gt;
const int CENTER_X = 64;   // centre écran&lt;br /&gt;
const int CENTER_Y = 64;&lt;br /&gt;
const int RADIUS   = 55;   // grand rayon pour 128x128&lt;br /&gt;
&lt;br /&gt;
// ---- Correction Y pour SH1107 ----&lt;br /&gt;
const int Y_OFFSET = 16;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse) avec gestion automatique du DST&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  // ---- Calcul des angles ----&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  // ---- Positions des aiguilles ----&lt;br /&gt;
  int hrX = CENTER_X + (RADIUS - 20) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY = CENTER_Y + (RADIUS - 20) * sin((hrAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 10) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 10) * sin((minAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage jour + date en haut ----&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 45, 12 + Y_OFFSET, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  // Cadran principal&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y + Y_OFFSET, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  // Chiffres 12-3-6-9&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 5 + Y_OFFSET, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 10, CENTER_Y + 4 + Y_OFFSET, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 12 + Y_OFFSET, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 12, CENTER_Y + 4 + Y_OFFSET, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Aiguilles&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, hrX, hrY);   // heures&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, minX, minY); // minutes&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, secX, secY); // secondes&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage digital en bas ----&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB14_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 30, 120 + Y_OFFSET, bufferTime);&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;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1; // tm_mon commence à 0&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;    // jour de la semaine (0 = dimanche)&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X128 OLED 3 ===&lt;br /&gt;
&lt;br /&gt;
Si tu utilises SH1107, laisse #define SCREEN_SH1107 actif → offset = 16.&amp;lt;br&amp;gt;&lt;br /&gt;
Si tu passes à SSD1327, commente SCREEN_SH1107 et décommente SCREEN_SSD1327 → offset = 0.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- Sélection écran ----&lt;br /&gt;
// Décommente la ligne correspondant à ton écran&lt;br /&gt;
#define SCREEN_SH1107&lt;br /&gt;
// #define SCREEN_SSD1327&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED Grove 1.12&amp;quot; SH1107 ----&lt;br /&gt;
// (Même constructeur pour SSD1327, mais offset différent)&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;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
// ---- Cadran ----&lt;br /&gt;
const int CENTER_X = 64;   // centre écran&lt;br /&gt;
const int CENTER_Y = 64;&lt;br /&gt;
const int RADIUS   = 55;   // grand rayon pour 128x128&lt;br /&gt;
&lt;br /&gt;
// ---- Correction Y selon écran ----&lt;br /&gt;
int Y_OFFSET = 0;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Choix offset selon écran&lt;br /&gt;
  #ifdef SCREEN_SH1107&lt;br /&gt;
    Y_OFFSET = 16;   // correction typique pour SH1107&lt;br /&gt;
  #endif&lt;br /&gt;
&lt;br /&gt;
  #ifdef SCREEN_SSD1327&lt;br /&gt;
    Y_OFFSET = 0;    // pas besoin de correction&lt;br /&gt;
  #endif&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse) avec gestion automatique du DST&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  // ---- Calcul des angles ----&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  // ---- Positions des aiguilles ----&lt;br /&gt;
  int hrX = CENTER_X + (RADIUS - 20) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY = CENTER_Y + (RADIUS - 20) * sin((hrAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 10) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 10) * sin((minAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage jour + date en haut ----&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 45, 12 + Y_OFFSET, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  // Cadran principal&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y + Y_OFFSET, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  // Chiffres 12-3-6-9&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 5 + Y_OFFSET, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 10, CENTER_Y + 4 + Y_OFFSET, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 12 + Y_OFFSET, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 12, CENTER_Y + 4 + Y_OFFSET, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Aiguilles&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, hrX, hrY);   // heures&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, minX, minY); // minutes&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, secX, secY); // secondes&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage digital en bas ----&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB14_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 30, 120 + Y_OFFSET, bufferTime);&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;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1; // tm_mon commence à 0&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;    // jour de la semaine (0 = dimanche)&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X128 OLED 4 ===&lt;br /&gt;
&lt;br /&gt;
Au démarrage → attend 10 secondes une commande série.&amp;lt;br&amp;gt;&lt;br /&gt;
Si tu tapes t → mode test offset (lignes horizontales).&amp;lt;br&amp;gt;&lt;br /&gt;
Si tu tapes h → mode horloge.&amp;lt;br&amp;gt;&lt;br /&gt;
Si rien n’est tapé → après 10 secondes → mode horloge par défaut.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- Sélection écran ----&lt;br /&gt;
#define SCREEN_SH1107&lt;br /&gt;
// #define SCREEN_SSD1327&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED Grove 1.12&amp;quot; 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;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
// ---- Cadran ----&lt;br /&gt;
const int CENTER_X = 64;&lt;br /&gt;
const int CENTER_Y = 64;&lt;br /&gt;
const int RADIUS   = 55;&lt;br /&gt;
&lt;br /&gt;
// ---- Correction Y selon écran ----&lt;br /&gt;
int Y_OFFSET = 0;&lt;br /&gt;
&lt;br /&gt;
// ---- Mode ----&lt;br /&gt;
bool modeTest = false;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Choix offset selon écran&lt;br /&gt;
  #ifdef SCREEN_SH1107&lt;br /&gt;
    Y_OFFSET = 16;&lt;br /&gt;
  #endif&lt;br /&gt;
  #ifdef SCREEN_SSD1327&lt;br /&gt;
    Y_OFFSET = 0;&lt;br /&gt;
  #endif&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse)&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
&lt;br /&gt;
  // ---- Attente commande série pendant 10s ----&lt;br /&gt;
  Serial.println(&amp;quot;Tapez &amp;#039;t&amp;#039; pour mode test offset, &amp;#039;h&amp;#039; pour horloge. Sinon horloge par défaut après 10s.&amp;quot;);&lt;br /&gt;
  unsigned long start = millis();&lt;br /&gt;
  while (millis() - start &amp;lt; 10000) {&lt;br /&gt;
    if (Serial.available()) {&lt;br /&gt;
      char c = Serial.read();&lt;br /&gt;
      if (c == &amp;#039;t&amp;#039;) {&lt;br /&gt;
        modeTest = true;&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
      if (c == &amp;#039;h&amp;#039;) {&lt;br /&gt;
        modeTest = false;&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  if (modeTest) {&lt;br /&gt;
    testOffset();&lt;br /&gt;
  } else {&lt;br /&gt;
    afficherHorloge();&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ---- Fonction horloge ----&lt;br /&gt;
void afficherHorloge() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  int hrX = CENTER_X + (RADIUS - 20) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY = CENTER_Y + (RADIUS - 20) * sin((hrAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 10) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 10) * sin((minAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 45, 12 + Y_OFFSET, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y + Y_OFFSET, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 5 + Y_OFFSET, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 10, CENTER_Y + 4 + Y_OFFSET, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 12 + Y_OFFSET, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 12, CENTER_Y + 4 + Y_OFFSET, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, hrX, hrY);&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, minX, minY);&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, secX, secY);&lt;br /&gt;
&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB14_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 30, 120 + Y_OFFSET, bufferTime);&lt;br /&gt;
&lt;br /&gt;
  u8g2.sendBuffer();&lt;br /&gt;
  delay(1000);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ---- Fonction utilitaire test offset ----&lt;br /&gt;
void testOffset() {&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
&lt;br /&gt;
  u8g2.drawLine(0, CENTER_Y, 128, CENTER_Y);             // sans offset&lt;br /&gt;
  u8g2.drawLine(0, CENTER_Y + Y_OFFSET, 128, CENTER_Y + Y_OFFSET); // avec offset&lt;br /&gt;
&lt;br /&gt;
  u8g2.drawStr(10, CENTER_Y - 5, &amp;quot;Sans offset&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(10, CENTER_Y + Y_OFFSET - 5, &amp;quot;Avec offset&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  u8g2.sendBuffer();&lt;br /&gt;
  delay(1000);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ---- Récupération heure locale ----&lt;br /&gt;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1;&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X128 OLED 5 Tool ===&lt;br /&gt;
&lt;br /&gt;
Tu verras deux lignes horizontales sur ton écran :&amp;lt;br&amp;gt;&lt;br /&gt;
Une ligne au centre (sans correction).&amp;lt;br&amp;gt;&lt;br /&gt;
Une ligne décalée de Y_OFFSET pixels (avec correction).&amp;lt;br&amp;gt;&lt;br /&gt;
Les textes « Sans offset » et « Avec offset » t’indiquent quelle ligne correspond à quoi.&amp;lt;br&amp;gt;&lt;br /&gt;
Si la ligne corrigée est bien alignée avec ce que tu attends, tu sais que ton Y_OFFSET est correct.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;Wire.h&amp;gt;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- Sélection écran ----&lt;br /&gt;
#define SCREEN_SH1107&lt;br /&gt;
// #define SCREEN_SSD1327&lt;br /&gt;
&lt;br /&gt;
// ---- OLED Grove 1.12&amp;quot; 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;
// ---- Correction Y selon écran ----&lt;br /&gt;
int Y_OFFSET = 0;&lt;br /&gt;
&lt;br /&gt;
// ---- Centre écran ----&lt;br /&gt;
const int CENTER_X = 64;&lt;br /&gt;
const int CENTER_Y = 64;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Choix offset selon écran&lt;br /&gt;
  #ifdef SCREEN_SH1107&lt;br /&gt;
    Y_OFFSET = 16;   // correction typique pour SH1107&lt;br /&gt;
  #endif&lt;br /&gt;
  #ifdef SCREEN_SSD1327&lt;br /&gt;
    Y_OFFSET = 0;    // pas besoin de correction&lt;br /&gt;
  #endif&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
&lt;br /&gt;
  // Ligne horizontale sans offset&lt;br /&gt;
  u8g2.drawLine(0, CENTER_Y, 128, CENTER_Y);&lt;br /&gt;
  u8g2.drawStr(10, CENTER_Y - 5, &amp;quot;Sans offset&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Ligne horizontale avec offset&lt;br /&gt;
  u8g2.drawLine(0, CENTER_Y + Y_OFFSET, 128, CENTER_Y + Y_OFFSET);&lt;br /&gt;
  u8g2.drawStr(10, CENTER_Y + Y_OFFSET - 5, &amp;quot;Avec offset&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  u8g2.sendBuffer();&lt;br /&gt;
&lt;br /&gt;
  delay(1000);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128×64 OLED 6 ===&lt;br /&gt;
&lt;br /&gt;
Centre déplacé à (64, 32) pour un écran 128×64.&amp;lt;br&amp;gt;&lt;br /&gt;
Rayon réduit à 28 pour que le cadran tienne bien.&amp;lt;br&amp;gt;&lt;br /&gt;
Positions des textes ajustées (y=10 pour la date, y=58 pour l’heure digitale).&amp;lt;br&amp;gt;&lt;br /&gt;
Constructeur U8g2 changé pour SSD1308/SSD1315.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED 128x64 SSD1308/SSD1315 ----&lt;br /&gt;
// Choisis le constructeur selon ton écran&lt;br /&gt;
U8G2_SSD1315_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);&lt;br /&gt;
&lt;br /&gt;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
// ---- Cadran ----&lt;br /&gt;
const int CENTER_X = 64;   // centre écran&lt;br /&gt;
const int CENTER_Y = 32;   // moitié de 64&lt;br /&gt;
const int RADIUS   = 28;   // adapté à la hauteur&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse)&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  // ---- Calcul des angles ----&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  // ---- Positions des aiguilles ----&lt;br /&gt;
  int hrX = CENTER_X + (RADIUS - 8) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY = CENTER_Y + (RADIUS - 8) * sin((hrAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 4) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 4) * sin((minAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage jour + date en haut ----&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(5, 10, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  // Cadran principal&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  // Chiffres 12-3-6-9&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 2, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 6, CENTER_Y + 4, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 10, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 10, CENTER_Y + 4, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Aiguilles&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, hrX, hrY);&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, minX, minY);&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, secX, secY);&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage digital en bas ----&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB14_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 30, 58, bufferTime);&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;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1;&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128×64 OLED 7 ===&lt;br /&gt;
&lt;br /&gt;
💻 Code compact (SSD1308/SSD1315, 128×64)&lt;br /&gt;
&lt;br /&gt;
Dans cette version, on supprime le cadran analogique et on affiche uniquement la date en haut et l’heure digitale bien centrée en bas. Cela exploite mieux la petite hauteur de l’écran.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Date + jour en haut (petite police).&amp;lt;br&amp;gt;&lt;br /&gt;
Heure digitale en bas, bien grande et centrée (u8g2_font_ncenB24_tr).&amp;lt;br&amp;gt;&lt;br /&gt;
Pas de cadran analogique → affichage clair et lisible sur un petit écran.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;ceci fonctionne mais le jours est superposé avec l&amp;#039;heure&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;Wire.h&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED 128x64 SSD1308/SSD1315 ----&lt;br /&gt;
// Choisis le constructeur selon ton écran&lt;br /&gt;
U8G2_SSD1315_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);&lt;br /&gt;
&lt;br /&gt;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse)&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // Affichage jour + date en haut&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(5, 12, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  // Affichage digital centré en bas&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB24_tr); // grande police pour l&amp;#039;heure&lt;br /&gt;
  u8g2.drawStr(20, 55, bufferTime);&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;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1;&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X64 OLED 7.1 Tool ===&lt;br /&gt;
&lt;br /&gt;
Calcul de la hauteur et largeur d&amp;#039;un texte avec une sortie du résultat sur le &amp;lt;b&amp;gt;port série&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Police 6x13 -&amp;gt; Hauteur=13 px, Largeur max char=6 px, &amp;lt;br&amp;gt;&lt;br /&gt;
Largeur &amp;#039;12:34:56&amp;#039;=48 px, Largeur &amp;#039;Vendredi, 14/11/2025&amp;#039;=114 px&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Police ncenB14 -&amp;gt; Hauteur=14 px, Largeur max char=14 px, &amp;lt;br&amp;gt;&lt;br /&gt;
Largeur &amp;#039;12:34:56&amp;#039;=84 px, Largeur &amp;#039;Vendredi, 14/11/2025&amp;#039;=168 px&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Police ncenB18 -&amp;gt; Hauteur=18 px, Largeur max char=18 px, &amp;lt;br&amp;gt;&lt;br /&gt;
Largeur &amp;#039;12:34:56&amp;#039;=108 px, Largeur &amp;#039;Vendredi, 14/11/2025&amp;#039;=216 px&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Police ncenB24 -&amp;gt; Hauteur=24 px, Largeur max char=24 px, &amp;lt;br&amp;gt;&lt;br /&gt;
Largeur &amp;#039;12:34:56&amp;#039;=144 px, Largeur &amp;#039;Vendredi, 14/11/2025&amp;#039;=288 px&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
🖥️ Exemple de code de test (heure + date)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;Wire.h&amp;gt;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
U8G2_SSD1315_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
&lt;br /&gt;
  // Test avec plusieurs polices&lt;br /&gt;
  testFont(u8g2_font_6x13_tr, &amp;quot;6x13&amp;quot;);&lt;br /&gt;
  testFont(u8g2_font_ncenB14_tr, &amp;quot;ncenB14&amp;quot;);&lt;br /&gt;
  testFont(u8g2_font_ncenB18_tr, &amp;quot;ncenB18&amp;quot;);&lt;br /&gt;
  testFont(u8g2_font_ncenB24_tr, &amp;quot;ncenB24&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  // rien à faire en boucle&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void testFont(const uint8_t* font, const char* name) {&lt;br /&gt;
  u8g2.setFont(font);&lt;br /&gt;
&lt;br /&gt;
  // Hauteur et largeur max d’un caractère&lt;br /&gt;
  int h = u8g2.getMaxCharHeight();&lt;br /&gt;
  int wChar = u8g2.getMaxCharWidth();&lt;br /&gt;
&lt;br /&gt;
  // Largeur d’un exemple d’heure&lt;br /&gt;
  int wTime = u8g2.getStrWidth(&amp;quot;12:34:56&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Largeur d’un exemple de jour + date&lt;br /&gt;
  int wDate = u8g2.getStrWidth(&amp;quot;Vendredi, 14/11/2025&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;Police %s -&amp;gt; Hauteur=%d px, Largeur max char=%d px, Largeur &amp;#039;12:34:56&amp;#039;=%d px, Largeur &amp;#039;Vendredi, 14/11/2025&amp;#039;=%d px\n&amp;quot;,&lt;br /&gt;
                name, h, wChar, wTime, wDate);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X64 OLED 7.2 ===&lt;br /&gt;
&lt;br /&gt;
Les marges hautes et basses en % de la hauteur de l’écran.&amp;lt;br&amp;gt;&lt;br /&gt;
Le choix automatique de la police pour l’heure en fonction de l’espace disponible.&amp;lt;br&amp;gt;&lt;br /&gt;
Le centrage horizontal de l’heure.&amp;lt;br&amp;gt;&lt;br /&gt;
La date en haut avec une police adaptée.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED 128x64 SSD1308/SSD1315 ----&lt;br /&gt;
U8G2_SSD1315_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);&lt;br /&gt;
&lt;br /&gt;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
// ---- Paramètres écran ----&lt;br /&gt;
const int LARGEUR_ECRAN = 128;&lt;br /&gt;
const int HAUTEUR_ECRAN = 64;&lt;br /&gt;
&lt;br /&gt;
// ---- Marges en % ----&lt;br /&gt;
const float MARGE_HAUT_PCT = 0.10; // 10%&lt;br /&gt;
const float MARGE_BAS_PCT  = 0.10; // 10%&lt;br /&gt;
&lt;br /&gt;
// ---- Polices disponibles pour l&amp;#039;heure ----&lt;br /&gt;
const uint8_t* FONT_SMALL  = u8g2_font_ncenB14_tr; // ~14 px&lt;br /&gt;
const uint8_t* FONT_MEDIUM = u8g2_font_ncenB18_tr; // ~18 px&lt;br /&gt;
const uint8_t* FONT_LARGE  = u8g2_font_ncenB24_tr; // ~24 px&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse)&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // Calcul des marges en pixels&lt;br /&gt;
  int margeHaut = (int)(HAUTEUR_ECRAN * MARGE_HAUT_PCT);&lt;br /&gt;
  int margeBas  = (int)(HAUTEUR_ECRAN * MARGE_BAS_PCT);&lt;br /&gt;
  int hauteurUtile = HAUTEUR_ECRAN - (margeHaut + margeBas);&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage jour + date en haut ----&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(5, margeHaut + 12, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  // ---- Choix automatique de la police pour l&amp;#039;heure ----&lt;br /&gt;
  const uint8_t* fontChoisie;&lt;br /&gt;
  if (hauteurUtile &amp;gt;= 24) {&lt;br /&gt;
    fontChoisie = FONT_LARGE;   // assez de place pour 24 px&lt;br /&gt;
  } else if (hauteurUtile &amp;gt;= 18) {&lt;br /&gt;
    fontChoisie = FONT_MEDIUM;  // assez de place pour 18 px&lt;br /&gt;
  } else {&lt;br /&gt;
    fontChoisie = FONT_SMALL;   // sinon police plus petite&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage digital centré en bas ----&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(fontChoisie);&lt;br /&gt;
&lt;br /&gt;
  // Centrage horizontal&lt;br /&gt;
  int largeur = u8g2.getStrWidth(bufferTime);&lt;br /&gt;
  int x = (LARGEUR_ECRAN - largeur) / 2;&lt;br /&gt;
&lt;br /&gt;
  // Ligne de base juste avant la marge basse&lt;br /&gt;
  int y = HAUTEUR_ECRAN - margeBas;&lt;br /&gt;
&lt;br /&gt;
  u8g2.drawStr(x, y, bufferTime);&lt;br /&gt;
&lt;br /&gt;
  u8g2.sendBuffer();&lt;br /&gt;
  delay(1000);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1;&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X64 OLED 8 ===&lt;br /&gt;
&lt;br /&gt;
💻 Code : seulement le cadran analogique&amp;lt;br&amp;gt; fonctionne mais illisible on dirait 2 ovales ! mais on peut voir les aguilles &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Un cadran analogique avec les chiffres 12‑3‑6‑9.&amp;lt;br&amp;gt;&lt;br /&gt;
Trois aiguilles (heures, minutes, secondes).&amp;lt;br&amp;gt;&lt;br /&gt;
Pas de date ni d’heure digitale → affichage épuré.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED 128x64 SSD1308/SSD1315 ----&lt;br /&gt;
U8G2_SSD1315_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);&lt;br /&gt;
&lt;br /&gt;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
&lt;br /&gt;
// ---- Cadran ----&lt;br /&gt;
const int CENTER_X = 64;   // centre écran&lt;br /&gt;
const int CENTER_Y = 32;   // moitié de 64&lt;br /&gt;
const int RADIUS   = 28;   // adapté à la hauteur&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse)&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  // ---- Calcul des angles ----&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  // ---- Positions des aiguilles ----&lt;br /&gt;
  int hrX = CENTER_X + (RADIUS - 8) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY = CENTER_Y + (RADIUS - 8) * sin((hrAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 4) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 4) * sin((minAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // Cadran principal&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  // Chiffres 12-3-6-9&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 2, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 6, CENTER_Y + 4, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 10, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 10, CENTER_Y + 4, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Aiguilles&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, hrX, hrY);   // heures&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, minX, minY); // minutes&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, secX, secY); // secondes&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;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%02d:%02d:%02d\n&amp;quot;, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>144.2.107.134</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.myows.top/index.php?title=Analog_Clock_OLED&amp;diff=1842</id>
		<title>Analog Clock OLED</title>
		<link rel="alternate" type="text/html" href="https://wiki.myows.top/index.php?title=Analog_Clock_OLED&amp;diff=1842"/>
		<updated>2025-11-14T23:14:47Z</updated>

		<summary type="html">&lt;p&gt;144.2.107.134: /* Analog Clock OLED 2 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Analog Clock OLED 1 ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED Grove 1.12&amp;quot; SH1107 ----&lt;br /&gt;
// U8G2_SH1107_PIMAR_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);&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;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
// ---- Cadran ----&lt;br /&gt;
const int CENTER_X = 64;   // centre écran&lt;br /&gt;
const int CENTER_Y = 64;&lt;br /&gt;
const int RADIUS   = 55;   // grand rayon pour 128x128&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse) avec gestion automatique du DST&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  // ---- Calcul des angles ----&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  // ---- Positions des aiguilles ----&lt;br /&gt;
  int hrX = CENTER_X + (RADIUS - 20) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY = CENTER_Y + (RADIUS - 20) * sin((hrAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 10) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 10) * sin((minAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage jour + date en haut ----&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 45, 12, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  // Cadran principal&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  // Chiffres 12-3-6-9&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 5, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 10, CENTER_Y + 4, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 12, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 12, CENTER_Y + 4, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Aiguilles&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, hrX, hrY);   // heures&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, minX, minY); // minutes&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, secX, secY); // secondes&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage digital en bas ----&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB14_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 30, 120, bufferTime);&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;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1; // tm_mon commence à 0&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;    // jour de la semaine (0 = dimanche)&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X128 OLED 2 ===&lt;br /&gt;
&lt;br /&gt;
Ajout de const int Y_OFFSET = 16;&amp;lt;br&amp;gt;&lt;br /&gt;
Application de + Y_OFFSET sur toutes les coordonnées Y (drawStr, drawLine, drawCircle, calcul des aiguilles).&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
pas vraiment, il semble avoir un problème avec l&amp;#039;offset négatif ou positif, on a légèrement un affichage&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED Grove 1.12&amp;quot; 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;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
// ---- Cadran ----&lt;br /&gt;
const int CENTER_X = 64;   // centre écran&lt;br /&gt;
const int CENTER_Y = 64;&lt;br /&gt;
const int RADIUS   = 55;   // grand rayon pour 128x128&lt;br /&gt;
&lt;br /&gt;
// ---- Correction Y pour SH1107 ----&lt;br /&gt;
const int Y_OFFSET = 16;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse) avec gestion automatique du DST&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  // ---- Calcul des angles ----&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  // ---- Positions des aiguilles ----&lt;br /&gt;
  int hrX = CENTER_X + (RADIUS - 20) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY = CENTER_Y + (RADIUS - 20) * sin((hrAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 10) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 10) * sin((minAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage jour + date en haut ----&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 45, 12 + Y_OFFSET, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  // Cadran principal&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y + Y_OFFSET, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  // Chiffres 12-3-6-9&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 5 + Y_OFFSET, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 10, CENTER_Y + 4 + Y_OFFSET, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 12 + Y_OFFSET, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 12, CENTER_Y + 4 + Y_OFFSET, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Aiguilles&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, hrX, hrY);   // heures&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, minX, minY); // minutes&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, secX, secY); // secondes&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage digital en bas ----&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB14_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 30, 120 + Y_OFFSET, bufferTime);&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;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1; // tm_mon commence à 0&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;    // jour de la semaine (0 = dimanche)&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X128 OLED 3 ===&lt;br /&gt;
&lt;br /&gt;
Si tu utilises SH1107, laisse #define SCREEN_SH1107 actif → offset = 16.&amp;lt;br&amp;gt;&lt;br /&gt;
Si tu passes à SSD1327, commente SCREEN_SH1107 et décommente SCREEN_SSD1327 → offset = 0.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- Sélection écran ----&lt;br /&gt;
// Décommente la ligne correspondant à ton écran&lt;br /&gt;
#define SCREEN_SH1107&lt;br /&gt;
// #define SCREEN_SSD1327&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED Grove 1.12&amp;quot; SH1107 ----&lt;br /&gt;
// (Même constructeur pour SSD1327, mais offset différent)&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;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
// ---- Cadran ----&lt;br /&gt;
const int CENTER_X = 64;   // centre écran&lt;br /&gt;
const int CENTER_Y = 64;&lt;br /&gt;
const int RADIUS   = 55;   // grand rayon pour 128x128&lt;br /&gt;
&lt;br /&gt;
// ---- Correction Y selon écran ----&lt;br /&gt;
int Y_OFFSET = 0;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Choix offset selon écran&lt;br /&gt;
  #ifdef SCREEN_SH1107&lt;br /&gt;
    Y_OFFSET = 16;   // correction typique pour SH1107&lt;br /&gt;
  #endif&lt;br /&gt;
&lt;br /&gt;
  #ifdef SCREEN_SSD1327&lt;br /&gt;
    Y_OFFSET = 0;    // pas besoin de correction&lt;br /&gt;
  #endif&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse) avec gestion automatique du DST&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  // ---- Calcul des angles ----&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  // ---- Positions des aiguilles ----&lt;br /&gt;
  int hrX = CENTER_X + (RADIUS - 20) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY = CENTER_Y + (RADIUS - 20) * sin((hrAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 10) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 10) * sin((minAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage jour + date en haut ----&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 45, 12 + Y_OFFSET, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  // Cadran principal&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y + Y_OFFSET, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  // Chiffres 12-3-6-9&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 5 + Y_OFFSET, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 10, CENTER_Y + 4 + Y_OFFSET, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 12 + Y_OFFSET, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 12, CENTER_Y + 4 + Y_OFFSET, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Aiguilles&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, hrX, hrY);   // heures&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, minX, minY); // minutes&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, secX, secY); // secondes&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage digital en bas ----&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB14_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 30, 120 + Y_OFFSET, bufferTime);&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;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1; // tm_mon commence à 0&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;    // jour de la semaine (0 = dimanche)&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X128 OLED 4 ===&lt;br /&gt;
&lt;br /&gt;
Au démarrage → attend 10 secondes une commande série.&amp;lt;br&amp;gt;&lt;br /&gt;
Si tu tapes t → mode test offset (lignes horizontales).&amp;lt;br&amp;gt;&lt;br /&gt;
Si tu tapes h → mode horloge.&amp;lt;br&amp;gt;&lt;br /&gt;
Si rien n’est tapé → après 10 secondes → mode horloge par défaut.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- Sélection écran ----&lt;br /&gt;
#define SCREEN_SH1107&lt;br /&gt;
// #define SCREEN_SSD1327&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED Grove 1.12&amp;quot; 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;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
// ---- Cadran ----&lt;br /&gt;
const int CENTER_X = 64;&lt;br /&gt;
const int CENTER_Y = 64;&lt;br /&gt;
const int RADIUS   = 55;&lt;br /&gt;
&lt;br /&gt;
// ---- Correction Y selon écran ----&lt;br /&gt;
int Y_OFFSET = 0;&lt;br /&gt;
&lt;br /&gt;
// ---- Mode ----&lt;br /&gt;
bool modeTest = false;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Choix offset selon écran&lt;br /&gt;
  #ifdef SCREEN_SH1107&lt;br /&gt;
    Y_OFFSET = 16;&lt;br /&gt;
  #endif&lt;br /&gt;
  #ifdef SCREEN_SSD1327&lt;br /&gt;
    Y_OFFSET = 0;&lt;br /&gt;
  #endif&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse)&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
&lt;br /&gt;
  // ---- Attente commande série pendant 10s ----&lt;br /&gt;
  Serial.println(&amp;quot;Tapez &amp;#039;t&amp;#039; pour mode test offset, &amp;#039;h&amp;#039; pour horloge. Sinon horloge par défaut après 10s.&amp;quot;);&lt;br /&gt;
  unsigned long start = millis();&lt;br /&gt;
  while (millis() - start &amp;lt; 10000) {&lt;br /&gt;
    if (Serial.available()) {&lt;br /&gt;
      char c = Serial.read();&lt;br /&gt;
      if (c == &amp;#039;t&amp;#039;) {&lt;br /&gt;
        modeTest = true;&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
      if (c == &amp;#039;h&amp;#039;) {&lt;br /&gt;
        modeTest = false;&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  if (modeTest) {&lt;br /&gt;
    testOffset();&lt;br /&gt;
  } else {&lt;br /&gt;
    afficherHorloge();&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ---- Fonction horloge ----&lt;br /&gt;
void afficherHorloge() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  int hrX = CENTER_X + (RADIUS - 20) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY = CENTER_Y + (RADIUS - 20) * sin((hrAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 10) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 10) * sin((minAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180) + Y_OFFSET;&lt;br /&gt;
&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 45, 12 + Y_OFFSET, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y + Y_OFFSET, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 5 + Y_OFFSET, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 10, CENTER_Y + 4 + Y_OFFSET, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 12 + Y_OFFSET, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 12, CENTER_Y + 4 + Y_OFFSET, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, hrX, hrY);&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, minX, minY);&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, secX, secY);&lt;br /&gt;
&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB14_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 30, 120 + Y_OFFSET, bufferTime);&lt;br /&gt;
&lt;br /&gt;
  u8g2.sendBuffer();&lt;br /&gt;
  delay(1000);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ---- Fonction utilitaire test offset ----&lt;br /&gt;
void testOffset() {&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
&lt;br /&gt;
  u8g2.drawLine(0, CENTER_Y, 128, CENTER_Y);             // sans offset&lt;br /&gt;
  u8g2.drawLine(0, CENTER_Y + Y_OFFSET, 128, CENTER_Y + Y_OFFSET); // avec offset&lt;br /&gt;
&lt;br /&gt;
  u8g2.drawStr(10, CENTER_Y - 5, &amp;quot;Sans offset&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(10, CENTER_Y + Y_OFFSET - 5, &amp;quot;Avec offset&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  u8g2.sendBuffer();&lt;br /&gt;
  delay(1000);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ---- Récupération heure locale ----&lt;br /&gt;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1;&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X128 OLED 5 Tool ===&lt;br /&gt;
&lt;br /&gt;
Tu verras deux lignes horizontales sur ton écran :&amp;lt;br&amp;gt;&lt;br /&gt;
Une ligne au centre (sans correction).&amp;lt;br&amp;gt;&lt;br /&gt;
Une ligne décalée de Y_OFFSET pixels (avec correction).&amp;lt;br&amp;gt;&lt;br /&gt;
Les textes « Sans offset » et « Avec offset » t’indiquent quelle ligne correspond à quoi.&amp;lt;br&amp;gt;&lt;br /&gt;
Si la ligne corrigée est bien alignée avec ce que tu attends, tu sais que ton Y_OFFSET est correct.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;Wire.h&amp;gt;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- Sélection écran ----&lt;br /&gt;
#define SCREEN_SH1107&lt;br /&gt;
// #define SCREEN_SSD1327&lt;br /&gt;
&lt;br /&gt;
// ---- OLED Grove 1.12&amp;quot; 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;
// ---- Correction Y selon écran ----&lt;br /&gt;
int Y_OFFSET = 0;&lt;br /&gt;
&lt;br /&gt;
// ---- Centre écran ----&lt;br /&gt;
const int CENTER_X = 64;&lt;br /&gt;
const int CENTER_Y = 64;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Choix offset selon écran&lt;br /&gt;
  #ifdef SCREEN_SH1107&lt;br /&gt;
    Y_OFFSET = 16;   // correction typique pour SH1107&lt;br /&gt;
  #endif&lt;br /&gt;
  #ifdef SCREEN_SSD1327&lt;br /&gt;
    Y_OFFSET = 0;    // pas besoin de correction&lt;br /&gt;
  #endif&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
&lt;br /&gt;
  // Ligne horizontale sans offset&lt;br /&gt;
  u8g2.drawLine(0, CENTER_Y, 128, CENTER_Y);&lt;br /&gt;
  u8g2.drawStr(10, CENTER_Y - 5, &amp;quot;Sans offset&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Ligne horizontale avec offset&lt;br /&gt;
  u8g2.drawLine(0, CENTER_Y + Y_OFFSET, 128, CENTER_Y + Y_OFFSET);&lt;br /&gt;
  u8g2.drawStr(10, CENTER_Y + Y_OFFSET - 5, &amp;quot;Avec offset&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  u8g2.sendBuffer();&lt;br /&gt;
&lt;br /&gt;
  delay(1000);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128×64 OLED 6 ===&lt;br /&gt;
&lt;br /&gt;
Centre déplacé à (64, 32) pour un écran 128×64.&amp;lt;br&amp;gt;&lt;br /&gt;
Rayon réduit à 28 pour que le cadran tienne bien.&amp;lt;br&amp;gt;&lt;br /&gt;
Positions des textes ajustées (y=10 pour la date, y=58 pour l’heure digitale).&amp;lt;br&amp;gt;&lt;br /&gt;
Constructeur U8g2 changé pour SSD1308/SSD1315.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED 128x64 SSD1308/SSD1315 ----&lt;br /&gt;
// Choisis le constructeur selon ton écran&lt;br /&gt;
U8G2_SSD1315_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);&lt;br /&gt;
&lt;br /&gt;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
// ---- Cadran ----&lt;br /&gt;
const int CENTER_X = 64;   // centre écran&lt;br /&gt;
const int CENTER_Y = 32;   // moitié de 64&lt;br /&gt;
const int RADIUS   = 28;   // adapté à la hauteur&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse)&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  // ---- Calcul des angles ----&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  // ---- Positions des aiguilles ----&lt;br /&gt;
  int hrX = CENTER_X + (RADIUS - 8) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY = CENTER_Y + (RADIUS - 8) * sin((hrAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 4) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 4) * sin((minAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage jour + date en haut ----&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(5, 10, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  // Cadran principal&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  // Chiffres 12-3-6-9&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 2, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 6, CENTER_Y + 4, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 10, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 10, CENTER_Y + 4, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Aiguilles&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, hrX, hrY);&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, minX, minY);&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, secX, secY);&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage digital en bas ----&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB14_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 30, 58, bufferTime);&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;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1;&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128×64 OLED 7 ===&lt;br /&gt;
&lt;br /&gt;
💻 Code compact (SSD1308/SSD1315, 128×64)&lt;br /&gt;
&lt;br /&gt;
Dans cette version, on supprime le cadran analogique et on affiche uniquement la date en haut et l’heure digitale bien centrée en bas. Cela exploite mieux la petite hauteur de l’écran.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Date + jour en haut (petite police).&amp;lt;br&amp;gt;&lt;br /&gt;
Heure digitale en bas, bien grande et centrée (u8g2_font_ncenB24_tr).&amp;lt;br&amp;gt;&lt;br /&gt;
Pas de cadran analogique → affichage clair et lisible sur un petit écran.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;ceci fonctionne mais le jours est superposé avec l&amp;#039;heure&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;Wire.h&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED 128x64 SSD1308/SSD1315 ----&lt;br /&gt;
// Choisis le constructeur selon ton écran&lt;br /&gt;
U8G2_SSD1315_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);&lt;br /&gt;
&lt;br /&gt;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse)&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // Affichage jour + date en haut&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(5, 12, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  // Affichage digital centré en bas&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB24_tr); // grande police pour l&amp;#039;heure&lt;br /&gt;
  u8g2.drawStr(20, 55, bufferTime);&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;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1;&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X64 OLED 7.1 Tool ===&lt;br /&gt;
&lt;br /&gt;
Calcul de la hauteur et largeur d&amp;#039;un texte avec une sortie du résultat sur le &amp;lt;b&amp;gt;port série&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Police 6x13 -&amp;gt; Hauteur=13 px, Largeur max char=6 px, &amp;lt;br&amp;gt;&lt;br /&gt;
Largeur &amp;#039;12:34:56&amp;#039;=48 px, Largeur &amp;#039;Vendredi, 14/11/2025&amp;#039;=114 px&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Police ncenB14 -&amp;gt; Hauteur=14 px, Largeur max char=14 px, &amp;lt;br&amp;gt;&lt;br /&gt;
Largeur &amp;#039;12:34:56&amp;#039;=84 px, Largeur &amp;#039;Vendredi, 14/11/2025&amp;#039;=168 px&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Police ncenB18 -&amp;gt; Hauteur=18 px, Largeur max char=18 px, &amp;lt;br&amp;gt;&lt;br /&gt;
Largeur &amp;#039;12:34:56&amp;#039;=108 px, Largeur &amp;#039;Vendredi, 14/11/2025&amp;#039;=216 px&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Police ncenB24 -&amp;gt; Hauteur=24 px, Largeur max char=24 px, &amp;lt;br&amp;gt;&lt;br /&gt;
Largeur &amp;#039;12:34:56&amp;#039;=144 px, Largeur &amp;#039;Vendredi, 14/11/2025&amp;#039;=288 px&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
🖥️ Exemple de code de test (heure + date)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;Wire.h&amp;gt;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
U8G2_SSD1315_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
&lt;br /&gt;
  // Test avec plusieurs polices&lt;br /&gt;
  testFont(u8g2_font_6x13_tr, &amp;quot;6x13&amp;quot;);&lt;br /&gt;
  testFont(u8g2_font_ncenB14_tr, &amp;quot;ncenB14&amp;quot;);&lt;br /&gt;
  testFont(u8g2_font_ncenB18_tr, &amp;quot;ncenB18&amp;quot;);&lt;br /&gt;
  testFont(u8g2_font_ncenB24_tr, &amp;quot;ncenB24&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  // rien à faire en boucle&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void testFont(const uint8_t* font, const char* name) {&lt;br /&gt;
  u8g2.setFont(font);&lt;br /&gt;
&lt;br /&gt;
  // Hauteur et largeur max d’un caractère&lt;br /&gt;
  int h = u8g2.getMaxCharHeight();&lt;br /&gt;
  int wChar = u8g2.getMaxCharWidth();&lt;br /&gt;
&lt;br /&gt;
  // Largeur d’un exemple d’heure&lt;br /&gt;
  int wTime = u8g2.getStrWidth(&amp;quot;12:34:56&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Largeur d’un exemple de jour + date&lt;br /&gt;
  int wDate = u8g2.getStrWidth(&amp;quot;Vendredi, 14/11/2025&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;Police %s -&amp;gt; Hauteur=%d px, Largeur max char=%d px, Largeur &amp;#039;12:34:56&amp;#039;=%d px, Largeur &amp;#039;Vendredi, 14/11/2025&amp;#039;=%d px\n&amp;quot;,&lt;br /&gt;
                name, h, wChar, wTime, wDate);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X64 OLED 7.2 ===&lt;br /&gt;
&lt;br /&gt;
Les marges hautes et basses en % de la hauteur de l’écran.&amp;lt;br&amp;gt;&lt;br /&gt;
Le choix automatique de la police pour l’heure en fonction de l’espace disponible.&amp;lt;br&amp;gt;&lt;br /&gt;
Le centrage horizontal de l’heure.&amp;lt;br&amp;gt;&lt;br /&gt;
La date en haut avec une police adaptée.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED 128x64 SSD1308/SSD1315 ----&lt;br /&gt;
U8G2_SSD1315_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);&lt;br /&gt;
&lt;br /&gt;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
int day, month, year, wday;&lt;br /&gt;
&lt;br /&gt;
// ---- Tableau des jours (français) ----&lt;br /&gt;
const char* jours[] = {&amp;quot;Dimanche&amp;quot;,&amp;quot;Lundi&amp;quot;,&amp;quot;Mardi&amp;quot;,&amp;quot;Mercredi&amp;quot;,&amp;quot;Jeudi&amp;quot;,&amp;quot;Vendredi&amp;quot;,&amp;quot;Samedi&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
// ---- Paramètres écran ----&lt;br /&gt;
const int LARGEUR_ECRAN = 128;&lt;br /&gt;
const int HAUTEUR_ECRAN = 64;&lt;br /&gt;
&lt;br /&gt;
// ---- Marges en % ----&lt;br /&gt;
const float MARGE_HAUT_PCT = 0.10; // 10%&lt;br /&gt;
const float MARGE_BAS_PCT  = 0.10; // 10%&lt;br /&gt;
&lt;br /&gt;
// ---- Polices disponibles pour l&amp;#039;heure ----&lt;br /&gt;
const uint8_t* FONT_SMALL  = u8g2_font_ncenB14_tr; // ~14 px&lt;br /&gt;
const uint8_t* FONT_MEDIUM = u8g2_font_ncenB18_tr; // ~18 px&lt;br /&gt;
const uint8_t* FONT_LARGE  = u8g2_font_ncenB24_tr; // ~24 px&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse)&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // Calcul des marges en pixels&lt;br /&gt;
  int margeHaut = (int)(HAUTEUR_ECRAN * MARGE_HAUT_PCT);&lt;br /&gt;
  int margeBas  = (int)(HAUTEUR_ECRAN * MARGE_BAS_PCT);&lt;br /&gt;
  int hauteurUtile = HAUTEUR_ECRAN - (margeHaut + margeBas);&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage jour + date en haut ----&lt;br /&gt;
  char bufferDate[30];&lt;br /&gt;
  sprintf(bufferDate, &amp;quot;%s %02d/%02d/%04d&amp;quot;, jours[wday], day, month, year);&lt;br /&gt;
  u8g2.setFont(u8g2_font_6x13_tr);&lt;br /&gt;
  u8g2.drawStr(5, margeHaut + 12, bufferDate);&lt;br /&gt;
&lt;br /&gt;
  // ---- Choix automatique de la police pour l&amp;#039;heure ----&lt;br /&gt;
  const uint8_t* fontChoisie;&lt;br /&gt;
  if (hauteurUtile &amp;gt;= 24) {&lt;br /&gt;
    fontChoisie = FONT_LARGE;   // assez de place pour 24 px&lt;br /&gt;
  } else if (hauteurUtile &amp;gt;= 18) {&lt;br /&gt;
    fontChoisie = FONT_MEDIUM;  // assez de place pour 18 px&lt;br /&gt;
  } else {&lt;br /&gt;
    fontChoisie = FONT_SMALL;   // sinon police plus petite&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // ---- Affichage digital centré en bas ----&lt;br /&gt;
  char bufferTime[10];&lt;br /&gt;
  sprintf(bufferTime, &amp;quot;%02d:%02d:%02d&amp;quot;, hrs, mins, secs);&lt;br /&gt;
  u8g2.setFont(fontChoisie);&lt;br /&gt;
&lt;br /&gt;
  // Centrage horizontal&lt;br /&gt;
  int largeur = u8g2.getStrWidth(bufferTime);&lt;br /&gt;
  int x = (LARGEUR_ECRAN - largeur) / 2;&lt;br /&gt;
&lt;br /&gt;
  // Ligne de base juste avant la marge basse&lt;br /&gt;
  int y = HAUTEUR_ECRAN - margeBas;&lt;br /&gt;
&lt;br /&gt;
  u8g2.drawStr(x, y, bufferTime);&lt;br /&gt;
&lt;br /&gt;
  u8g2.sendBuffer();&lt;br /&gt;
  delay(1000);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
  day   = timeinfo.tm_mday;&lt;br /&gt;
  month = timeinfo.tm_mon + 1;&lt;br /&gt;
  year  = timeinfo.tm_year + 1900;&lt;br /&gt;
  wday  = timeinfo.tm_wday;&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%s %02d/%02d/%04d %02d:%02d:%02d\n&amp;quot;,&lt;br /&gt;
                jours[wday], day, month, year, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog Clock 128X64 OLED 8 ===&lt;br /&gt;
&lt;br /&gt;
💻 Code : seulement le cadran analogique&amp;lt;br&amp;gt; fonctionne mais illisible on dirait 2 ovales ! mais on peut voir les aguilles &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Un cadran analogique avec les chiffres 12‑3‑6‑9.&amp;lt;br&amp;gt;&lt;br /&gt;
Trois aiguilles (heures, minutes, secondes).&amp;lt;br&amp;gt;&lt;br /&gt;
Pas de date ni d’heure digitale → affichage épuré.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;sntp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;U8g2lib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ---- WiFi ----&lt;br /&gt;
const char* ssid = &amp;quot;TonSSID&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;TonMotDePasse&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- Serveurs NTP ----&lt;br /&gt;
const char* ntpServer1 = &amp;quot;pool.ntp.org&amp;quot;;&lt;br /&gt;
const char* ntpServer2 = &amp;quot;time.nist.gov&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// ---- OLED 128x64 SSD1308/SSD1315 ----&lt;br /&gt;
U8G2_SSD1315_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);&lt;br /&gt;
&lt;br /&gt;
// ---- Variables temps ----&lt;br /&gt;
int hrs, mins, secs;&lt;br /&gt;
&lt;br /&gt;
// ---- Cadran ----&lt;br /&gt;
const int CENTER_X = 64;   // centre écran&lt;br /&gt;
const int CENTER_Y = 32;   // moitié de 64&lt;br /&gt;
const int RADIUS   = 28;   // adapté à la hauteur&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  // Connexion WiFi&lt;br /&gt;
  WiFi.begin(ssid, password);&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) {&lt;br /&gt;
    delay(500);&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  Serial.println(&amp;quot; CONNECTÉ&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Fuseau CET/CEST (Suisse)&lt;br /&gt;
  configTzTime(&amp;quot;CET-1CEST,M3.5.0/2,M10.5.0/3&amp;quot;, ntpServer1, ntpServer2);&lt;br /&gt;
&lt;br /&gt;
  // Init OLED&lt;br /&gt;
  u8g2.begin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  setLocalTime();&lt;br /&gt;
&lt;br /&gt;
  // ---- Calcul des angles ----&lt;br /&gt;
  float secAngle = secs * 6;&lt;br /&gt;
  float minAngle = mins * 6 + secs * 0.1;&lt;br /&gt;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;&lt;br /&gt;
&lt;br /&gt;
  // ---- Positions des aiguilles ----&lt;br /&gt;
  int hrX = CENTER_X + (RADIUS - 8) * cos((hrAngle - 90) * PI / 180);&lt;br /&gt;
  int hrY = CENTER_Y + (RADIUS - 8) * sin((hrAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  int minX = CENTER_X + (RADIUS - 4) * cos((minAngle - 90) * PI / 180);&lt;br /&gt;
  int minY = CENTER_Y + (RADIUS - 4) * sin((minAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);&lt;br /&gt;
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180);&lt;br /&gt;
&lt;br /&gt;
  // ---- Dessin ----&lt;br /&gt;
  u8g2.clearBuffer();&lt;br /&gt;
&lt;br /&gt;
  // Cadran principal&lt;br /&gt;
  u8g2.drawCircle(CENTER_X, CENTER_Y, RADIUS);&lt;br /&gt;
&lt;br /&gt;
  // Chiffres 12-3-6-9&lt;br /&gt;
  u8g2.setFont(u8g2_font_ncenB08_tr);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 2, &amp;quot;12&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X + RADIUS - 6, CENTER_Y + 4, &amp;quot;3&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 10, &amp;quot;6&amp;quot;);&lt;br /&gt;
  u8g2.drawStr(CENTER_X - RADIUS - 10, CENTER_Y + 4, &amp;quot;9&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // Aiguilles&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, hrX, hrY);   // heures&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, minX, minY); // minutes&lt;br /&gt;
  u8g2.drawLine(CENTER_X, CENTER_Y, secX, secY); // secondes&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;
void setLocalTime() {&lt;br /&gt;
  struct tm timeinfo;&lt;br /&gt;
  if (!getLocalTime(&amp;amp;timeinfo)) {&lt;br /&gt;
    Serial.println(&amp;quot;Pas encore d&amp;#039;heure disponible&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  hrs   = timeinfo.tm_hour;&lt;br /&gt;
  mins  = timeinfo.tm_min;&lt;br /&gt;
  secs  = timeinfo.tm_sec;&lt;br /&gt;
&lt;br /&gt;
  Serial.printf(&amp;quot;%02d:%02d:%02d\n&amp;quot;, hrs, mins, secs);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>144.2.107.134</name></author>
		
	</entry>
</feed>