Horloge avec wemos mini / ws2812b et DS3132

Bonjour tous le monde

je prépare un petit projet pour l'anniversaire d'un pot et j'ai des soucis de fonctionnement.
le programme ci dessous fonctionne sur une esp8266 wemos mini , DS3132 pour l'horloge et un écran 8X32 flexible ws2812b.

Le programme se lance sans souci, j'ai créer une interface web avec la possibilité de pouvoir régler l'heure, la date, la luminosité et le temps entre chaque animations sans être obligé de passer par le net, car la ou sera placée l'horloge on ne pourra pas avoir accès au wifi d'où l'utilisation de AP wifi via un téléphone.

je vous expose mes problèmes:

  • l'accès AP n'est pas super stable pourquoi ??? existe t'il une solution plus simple ?
  • la fonction luminosité ne fonctionne pas (elle réagis car je vois clignotée l'écran mais la luminosité ne se modifie pas, parfois cela fonctionne mais pour quelle raison ???
  • je voudrai via l'interface pouvoir sélectionner les animations qui doivent apparaitre ou non (je n'y suis pas arrivé)....
  • je voudrai que l'heure et la date s'incrémente entre chaque animation et non lorsque toute les animations sont lus.
    je suis hyper novice dans le domaine, je suis plus doué en mécanique et électronique mais la programmation je m'arrache les cheuveux , voila si une personne ou des personnes qui maitrise peuvent m'aider cela serait super sympa.
    Cordialement et merci pour votre aide
#include <ESP8266WiFi.h>
#include <ESPAsyncWebServer.h>
#include <WiFiUdp.h>
#include <NTPClient.h>
#include <Wire.h>
#include <RTClib.h>
#include <Adafruit_GFX.h>
#include <Adafruit_NeoMatrix.h>
#include <Adafruit_NeoPixel.h>

#define LED_PIN D3  // Correspond à D4 sur la Wemos D1 Mini
#define NUM_LEDS 256 // 8x32 = 256 LEDs

// Configuration du panneau LED 8x32
Adafruit_NeoPixel leds(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);
Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(32, 8, LED_PIN,
  NEO_MATRIX_BOTTOM + NEO_MATRIX_RIGHT +
  NEO_MATRIX_COLUMNS + NEO_MATRIX_ZIGZAG,
  NEO_GRB + NEO_KHZ800);

int brightness = 50; // Luminosité initiale
int displayDelay = 5; // Temps en secondes avant alternance entre heure et date
bool showTime = true; // Indicateur pour alterner l'affichage

// Paramètres Wi-Fi (Point d'accès)
const char* ssid = "ESP8266_AP";
const char* password = "password";

AsyncWebServer server(80);
WiFiUDP udp;
NTPClient timeClient(udp, "pool.ntp.org", 3600); // UTC+1

RTC_DS3231 rtc;
unsigned long lastSwitchTime = 0;

void setup() {
    Serial.begin(115200);
    Wire.begin();

    matrix.begin();
    matrix.setTextWrap(false);
    matrix.setBrightness(brightness);

    if (!rtc.begin()) {
        Serial.println("Erreur : Impossible de trouver le module DS3231 !");
        while (1);
    }

    if (rtc.lostPower()) {
        Serial.println("Le DS3231 a perdu l'alimentation, initialisation...");
        rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // Mise à l'heure initiale
    }

    // Configuration du Wi-Fi en mode point d'accès
    WiFi.softAP(ssid, password);
    Serial.println("Point d'accès Wi-Fi créé");

    // Initialisation du client NTP
    timeClient.begin();
    syncTimeWithNTP(); // Mise à jour du DS3231 avec NTP

    // Page principale avec réglage de l'heure, date, luminosité et délai d'affichage
    server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
        DateTime now = rtc.now();
        String currentTime = String(now.hour()) + ":" + String(now.minute()) + ":" + String(now.second());

        // Formattage du jour et du mois pour avoir 2 chiffres
        char formattedDate[6];
        sprintf(formattedDate, "%02d/%02d", now.day(), now.month());
        String currentDate = String(formattedDate);

        String html = "<h1>Affichage LED</h1>";
        html += "<p>Heure actuelle: <span id='currentTime'>" + currentTime + "</span></p>";
        html += "<p>Date actuelle: <span id='currentDate'>" + currentDate + "</span></p>";

        // Formulaire pour régler l’heure et la date
        html += "<form action='/setDateTime' method='get'>";
        html += "Date: <input type='number' name='day' min='1' max='31' required>/";
        html += "<input type='number' name='month' min='1' max='12' required>/";
        html += "<input type='number' name='year' min='2023' max='2100' required><br>";
        html += "Heure: <input type='number' name='hour' min='0' max='23' required>:";
        html += "<input type='number' name='minute' min='0' max='59' required>:"; 
        html += "<input type='number' name='second' min='0' max='59' required> "; 
        html += "<input type='submit' value='Régler l&apos;heure et la date'>";
        html += "</form>";

        // Slider pour ajuster la luminosité
        html += "<label for='brightness'>Luminosité : </label>";
        html += "<input type='range' id='brightness' min='0' max='255' value='" + String(brightness) + "' oninput='updateBrightness(this.value)'>";

        // Slider pour régler l'alternance heure/date
        html += "<label for='displayDelay'>Délai d'affichage (s) : </label>";
        html += "<input type='range' id='displayDelay' min='2' max='30' value='" + String(displayDelay) + "' oninput='updateDisplayDelay(this.value)'>";

        html += "<script>";
        html += "function updateBrightness(value) { fetch('/setBrightness?value=' + value); }";
        html += "function updateDisplayDelay(value) { fetch('/setDisplayDelay?value=' + value); }";
        html += "setInterval(function(){ fetch('/getDateTime').then(response => response.json()).then(data => {";
        html += "document.getElementById('currentTime').innerText = data.time;";
        html += "document.getElementById('currentDate').innerText = data.date;";
        html += "}); }, 1000);";
        html += "</script>";

        request->send(200, "text/html", html);
    });

    // Routes pour modifier les paramètres
    server.on("/setBrightness", HTTP_GET, [](AsyncWebServerRequest *request){
        if (request->hasParam("value")) {
            brightness = request->getParam("value")->value().toInt();
            matrix.setBrightness(brightness);
            matrix.show();
        }
        request->send(200, "text/plain", "Brightness updated");
    });

    server.on("/setDisplayDelay", HTTP_GET, [](AsyncWebServerRequest *request){
        if (request->hasParam("value")) {
            displayDelay = request->getParam("value")->value().toInt();
        }
        request->send(200, "text/plain", "Display delay updated");
    });

    server.on("/setDateTime", HTTP_GET, [](AsyncWebServerRequest *request){
        if (request->hasParam("day") && request->hasParam("month") && request->hasParam("year") &&
            request->hasParam("hour") && request->hasParam("minute") && request->hasParam("second")) {

            int day = request->getParam("day")->value().toInt();
            int month = request->getParam("month")->value().toInt();
            int year = request->getParam("year")->value().toInt();
            int hour = request->getParam("hour")->value().toInt();
            int minute = request->getParam("minute")->value().toInt();
            int second = request->getParam("second")->value().toInt();

            rtc.adjust(DateTime(year, month, day, hour, minute, second));
        }
        request->send(200, "text/plain", "DateTime updated");
    });

    server.on("/getDateTime", HTTP_GET, [](AsyncWebServerRequest *request){
        DateTime now = rtc.now();
        // Formattage du jour et du mois pour avoir 2 chiffres
        char formattedDate[6];
        sprintf(formattedDate, "%02d/%02d", now.day(), now.month());
        String json = "{\"time\":\"" + String(now.hour()) + ":" + String(now.minute()) + ":" + String(now.second()) +
                      "\", \"date\":\"" + String(formattedDate) + "\"}";
        request->send(200, "application/json", json);
    });

    server.begin();
}

void syncTimeWithNTP() {
    timeClient.update();
    unsigned long epochTime = timeClient.getEpochTime();
    DateTime now(epochTime);
    rtc.adjust(now);
}
void displayColorGradient() {
    for (int i = 0; i < 256; i++) {
        matrix.fillScreen(matrix.Color(i, 255 - i, 0));  // Crée un dégradé de couleur
        matrix.show();
        delay(10);  // Délai pour rendre l'animation fluide
    }
}
// 🐍1
void displayWaveEffect() {
    int waveWidth = 8;  // Largeur de la vague
    int speed = 5;  // Vitesse de l'animation

    for (int j = 0; j < 32 + waveWidth; j++) {
        matrix.fillScreen(0);  // Effacer l'écran

        // Créer un effet de vague
        for (int i = 0; i < 32; i++) {
            // Déplacement de la vague, variation des couleurs
            int color = matrix.Color((sin((i + j) * 0.2) + 1) * 128, 0, 0);  // Rouge + effet sinusoïdal
            matrix.drawPixel(i, 3, color);  // Placer le pixel sur la ligne centrale
        }

        matrix.show();  // Mettre à jour l'écran
        delay(speed);  // Vitesse de la vague
    }
}
// 🐍2
void displayPulsingCircle() {
    int speed = 10;  // Vitesse de l'animation

    for (int i = 0; i < 32; i++) {
        matrix.fillScreen(0);  // Effacer l'écran

        // Dessiner un cercle qui pulse
        for (int x = 0; x < 32; x++) {
            for (int y = 0; y < 8; y++) {
                int distance = sqrt(pow(x - 16, 2) + pow(y - 4, 2));  // Distance au centre
                int brightness = max(0, 255 - (distance - i) * 10);  // Calcul de la luminosité en fonction de la distance
                if (brightness > 0) {
                    matrix.drawPixel(x, y, matrix.Color(brightness, 0, 255 - brightness));  // Couleur changeante
                }
            }
        }

        matrix.show();  // Mettre à jour l'écran
        delay(speed);  // Délai pour contrôler la vitesse de l'animation
    }
}
/* 🌈 3. Dégradé arc-en-ciel fluide */
void arcEnCiel(int vitesse) {
  for (long PremiereLedCouleur = 0; PremiereLedCouleur < 65536; PremiereLedCouleur += 256) {
    for (int i = 0; i < NUM_LEDS; i++) {
      int ledTeinte = PremiereLedCouleur + (i * 65536 / NUM_LEDS);
      leds.setPixelColor(i, leds.gamma32(leds.ColorHSV(ledTeinte)));
    }
    leds.show();
    delay(vitesse);
  }
}

/* 🌊 4. Effet de vague lumineuse */
void vagueLumieuse(int vitesse) {
  for (int phase = 0; phase < 360; phase += 10) {
    for (int i = 0; i < NUM_LEDS; i++) {
      int valeur = (sin((i * 10 + phase) * 3.14 / 180) * 127) + 128; 
      leds.setPixelColor(i, leds.Color(valeur, 0, 255 - valeur));
    }
    leds.show();
    delay(vitesse);
  }
}

/* ✨ 5. Scintillement aléatoire façon étoiles */
void etoilesScintillantes(int vitesse) {
  for (int i = 0; i < 10; i++) {
    int index = random(NUM_LEDS);
    leds.setPixelColor(index, leds.Color(random(50, 255), random(50, 255), random(50, 255)));
  }
  leds.show();
  delay(vitesse);
  leds.clear();
}

/* 🐍 6. Serpent lumineux */
void serpent(int vitesse) {
  int longueur = 10;
  for (int i = 0; i < NUM_LEDS + longueur; i++) {
    leds.clear();
    for (int j = 0; j < longueur; j++) {
      int index = i - j;
      if (index >= 0 && index < NUM_LEDS) {
        leds.setPixelColor(index, leds.Color(0, 255 - j * 25, j * 25));
      }
    }
    leds.show();
    delay(vitesse);
  }
}
// 🌌 7. Ciel étoilé avec traînées
void cielEtoile(int vitesse) {
  for (int i = 0; i < NUM_LEDS; i++) {
    if (random(10) > 8) {
      leds.setPixelColor(i, leds.Color(random(150, 255), random(150, 255), random(150, 255)));
    } else {
      leds.setPixelColor(i, leds.Color(0, 0, 0));
    }
  }

  for (int i = 0; i < random(5, 20); i++) {
    int starIndex = random(NUM_LEDS); 
    leds.setPixelColor(starIndex, leds.Color(random(100, 255), random(100, 255), random(100, 255)));
    for (int j = 1; j < 5; j++) {
      int trailIndex = (starIndex + j) % NUM_LEDS;
      leds.setPixelColor(trailIndex, leds.Color(0, 0, 0));
    }
  }

  leds.show();
  delay(vitesse);
}

// 🔄 8. Vortex lumineux en rotation
void vortex(int vitesse) {
  int center = NUM_LEDS / 2;
  int rayon = NUM_LEDS / 4;

  for (int angle = 0; angle < 360; angle += 10) {
    for (int i = 0; i < NUM_LEDS; i++) {
      float distance = abs(i - center);
      int intensity = max(0, (int)(255 - distance * 255.0 / rayon));

      int red = (int)(sin(angle * 3.14 / 180) * 127 + 128);
      int green = (int)(sin((angle + 120) * 3.14 / 180) * 127 + 128);
      int blue = (int)(sin((angle + 240) * 3.14 / 180) * 127 + 128);

      leds.setPixelColor(i, leds.Color(red * intensity / 255, green * intensity / 255, blue * intensity / 255));
    }
    leds.show();
    delay(vitesse);
  }
}

// 🎆 9. Explosion de couleurs (Feu d'artifice)
void explosion(int vitesse) {
  for (int i = 0; i < NUM_LEDS; i++) {
    leds.setPixelColor(i, leds.Color(0, 0, 0));
  }

  int explosionCenter = random(NUM_LEDS); 

  for (int radius = 1; radius < NUM_LEDS / 2; radius++) {
    for (int i = explosionCenter - radius; i <= explosionCenter + radius; i++) {
      int color = random(0, 256);
      leds.setPixelColor(i, leds.Color(random(255), random(255), random(255)));
    }
    leds.show();
    delay(vitesse);
  }

  delay(100);
}

// 🐍 10- Serpent lumineux avec couleurs dynamiques
void serpentDynamique(int vitesse) {
  int longueur = 10;
  int vitesseSerpent = random(50, 100);
  for (int i = 0; i < NUM_LEDS + longueur; i++) {
    leds.clear();
    
    for (int j = 0; j < longueur; j++) {
      int index = (i - j) % NUM_LEDS;
      if (index >= 0) {
        int red = (int)(sin(i * 0.1 + millis() / 1000.0) * 127 + 128);
        int green = (int)(sin(i * 0.1 + millis() / 2000.0) * 127 + 128);
        int blue = (int)(sin(i * 0.1 + millis() / 3000.0) * 127 + 128);
        
        leds.setPixelColor(index, leds.Color(red, green, blue));
      }
    }
    leds.show();
    delay(vitesseSerpent);
  }
}

// 💧 11. Cascade lumineuse avec couleurs changeantes
void cascade(int vitesse) {
  int numSteps = NUM_LEDS / 4;
  for (int i = 0; i < numSteps; i++) {
    for (int j = 0; j < NUM_LEDS; j++) {
      if (j >= i && j < i + 4) {
        leds.setPixelColor(j, leds.Color(random(50, 255), random(50, 255), random(50, 255)));
      } else {
        leds.setPixelColor(j, leds.Color(0, 0, 0));  
      }
    }
    leds.show();
    delay(vitesse);
  }
}
// 🌈12. Arc-en-ciel fluide avec dégradé
void arcEnCielFluide(int temps) {
  for (int i = 0; i < NUM_LEDS; i++) {
    int couleur = (i * 65536 / NUM_LEDS);  // Crée un dégradé de couleurs
    leds.setPixelColor(i, leds.gamma32(leds.ColorHSV(couleur)));
  }
  leds.show();
  delay(temps); // Ralentir pour une transition douce
}

// 🌈13. Pluie de couleurs
void pluieDeCouleurs(int temps) {
  for (int i = 0; i < NUM_LEDS; i++) {
    int couleur = random(0, 65536);  // Générer une couleur aléatoire
    leds.setPixelColor(i, leds.gamma32(leds.ColorHSV(couleur)));
  }
  leds.show();
  delay(temps); // Intervalle entre chaque "pluie"
}

// 🌈14. Explosion de couleurs
void explosionDeCouleurs(int temps) {
  for (int i = 0; i < NUM_LEDS; i++) {
    int couleur = random(0, 65536);  // Couleurs aléatoires pour l'explosion
    leds.setPixelColor(i, leds.gamma32(leds.ColorHSV(couleur)));
  }
  leds.show();
  delay(temps); // Intervalle de l'explosion
}

// 🌈15. Mouvement de vague lumineuse
void vagueLumineuse(int temps) {
  for (int i = 0; i < NUM_LEDS; i++) {
    int couleur = (sin(i + millis() / 100.0) * 127 + 128);  // Effet de vague
    leds.setPixelColor(i, leds.Color(couleur, 0, 255 - couleur));
  }
  leds.show();
  delay(temps); // Intervalle entre chaque vague
}

// 🌈16. Lumière pulsée (Pulse)
void lumierePulsee(int temps) {
  for (int i = 0; i < 255; i++) {
    leds.fill(leds.Color(i, 0, 255 - i));  // Augmenter puis réduire l'intensité
    leds.show();
    delay(temps);  // Temps entre les pulsations
  }
  for (int i = 255; i > 0; i--) {
    leds.fill(leds.Color(i, 0, 255 - i));
    leds.show();
    delay(temps);
  }
}

// 🌈17. Effet de spirale lumineuse
void spiraleLumineuse(int temps) {
  for (int i = 0; i < NUM_LEDS; i++) {
    int distance = abs(i - NUM_LEDS / 2);  // Calculer la distance à partir du centre
    int couleur = (distance * 65536 / NUM_LEDS); // Créer un effet lumineux autour du centre
    leds.setPixelColor(i, leds.gamma32(leds.ColorHSV(couleur)));
  }
  leds.show();
  delay(temps); // Intervalle entre chaque mouvement de spirale
}

// 🌈18. Lumière clignotante aléatoire
void clignotantAleatoire(int temps) {
  for (int i = 0; i < NUM_LEDS; i++) {
    if (random(0, 10) > 7) {
      leds.setPixelColor(i, leds.Color(255, 255, 255));  // LED blanche
    } else {
      leds.setPixelColor(i, leds.Color(0, 0, 0));  // LED éteinte
    }
  }
  leds.show();
  delay(temps);  // Intervalle entre les clignotements
}

// 🌈19. Ciel étoilé scintillant
void cielEtoiles(int temps) {
  for (int i = 0; i < NUM_LEDS; i++) {
    if (random(0, 100) < 10) {
      leds.setPixelColor(i, leds.Color(random(200, 255), random(200, 255), random(200, 255)));  // Etoile brillante
    } else {
      leds.setPixelColor(i, leds.Color(0, 0, 0));  // LED éteinte
    }
  }
  leds.show();
  delay(temps);  // Temps entre les scintillements
}

// 🌈20. Lumière de l'aurore (Aurora Borealis)
void auroreBoreale(int temps) {
  for (int i = 0; i < NUM_LEDS; i++) {
    int couleur = (sin(i + millis() / 500.0) * 127 + 128);  // Effet de vagues
    leds.setPixelColor(i, leds.Color(couleur, random(0, 128), random(128, 255)));
  }
  leds.show();
  delay(temps);  // Temps entre chaque onde de lumière
}
void loop() {
    DateTime now = rtc.now();

    if (millis() - lastSwitchTime > displayDelay * 1000) {
        showTime = !showTime;
        lastSwitchTime = millis();
    }

    matrix.fillScreen(0);

    if (showTime) {
        // Afficher l'heure
        matrix.setTextColor(matrix.Color(0, 250, 0));
        String timeStr = String(now.hour()) + ":" + String(now.minute());
        matrix.setCursor(5, 1);
        matrix.print(timeStr);
    } else {
        // Afficher la date
        matrix.setTextColor(matrix.Color(250, 0, 0));
        char formattedDate[6];
        sprintf(formattedDate, "%02d/%02d", now.day(), now.month());
        matrix.setCursor(2, 1);
        matrix.print(formattedDate);
    }

    matrix.show();
    delay(1000); // Rafraîchir toutes les secondes

    // Affichage défilant du texte
    matrix.setTextColor(matrix.Color(250, 130, 0));
    for (int x = 31; x >= -81; x -= 1) { 
        matrix.setCursor(x, 1); 
        matrix.print("Bienvenue DEUDEU");
        matrix.show();
        delay(80);
        matrix.fillScreen(0);
    }

    matrix.setTextColor(matrix.Color(250, 0, 0));
    matrix.setCursor(2, 1); 
    matrix.print("Lulu");  
    matrix.show();
    delay(2000);

    matrix.setTextColor(matrix.Color(250, 130, 0));
    for (int y = 1; y <= 8; y += 1) { 
        matrix.setCursor(2, y); 
        matrix.print("Lulu");  
        matrix.show();
        delay(30);
        matrix.fillScreen(0);
    }

    matrix.show();

    // Ajouter des animations en boucle
    displayColorGradient();  // Animation gradient de couleurs
    displayWaveEffect();       // Effet de vague
    displayPulsingCircle();    // Cercle pulsant
    arcEnCiel(10);   // Animation Arc-en-ciel
    vagueLumieuse(15); // Animation de vague lumineuse
    etoilesScintillantes(100); // Animation de scintillement
    serpent(20);     // Animation de serpent lumineux
    cielEtoile(50);// Animation 1 : Ciel étoilé avec traînées;
    vortex(50);// Animation 2 : Vortex lumineux en rotation
    explosion(50);// Animation 3 : Explosion de couleurs (Feu d'artifice)
    serpentDynamique(50); // Animation 4 : Serpent lumineux avec couleurs dynamiques
    cascade(100);// Animation 5 : Cascade lumineuse avec couleurs changeantes
    arcEnCielFluide(100);    // Animation 1 : Arc-en-ciel fluide
    pluieDeCouleurs(100);    // Animation 2 : Pluie de couleurs
    explosionDeCouleurs(100); // Animation 3 : Explosion de couleurs
    vagueLumineuse(100);     // Animation 4 : Vague lumineuse
    lumierePulsee(100);      // Animation 5 : Lumière pulsée
    spiraleLumineuse(100);   // Animation 6 : Spirale lumineuse
    clignotantAleatoire(100);// Animation 7 : Clignotant aléatoire
    cielEtoiles(100);         // Animation 8 : Ciel étoilé scintillant
    auroreBoreale(100);      // Animation 9 : Aurore boréale
}

Bon j'ai repris mon programme et simplifier.

il me reste un souci que je n'arrive pas a résoudre dur dur.
je démarre l'horloge, je vais dans l'interface web pour modifier l 'heure et date puis je valide jusque là tout fonctionne.

j'arrête l'horloge puis le redémarre 5 mn plus tard et cela mets l'heure par défaut et non celle que j'avais enregistrer sur la page web + 5mn.
je n'arrive pas à comprendre ou est mon erreur.

Help et merci encore pour votre aide

#include <ESP8266WiFi.h>
#include <ESPAsyncWebServer.h>
#include <WiFiUdp.h>
#include <NTPClient.h>
#include <Wire.h>
#include <RTClib.h>
#include <Adafruit_GFX.h>
#include <Adafruit_NeoMatrix.h>
#include <Adafruit_NeoPixel.h>
#include <EEPROM.h>

#define LED_PIN D3  // Correspond à D4 sur la Wemos D1 Mini
#define NUM_LEDS 256 // 8x32 = 256 LEDs

// Configuration du panneau LED 8x32
Adafruit_NeoPixel leds(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);
Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(32, 8, LED_PIN,
  NEO_MATRIX_BOTTOM + NEO_MATRIX_RIGHT +
  NEO_MATRIX_COLUMNS + NEO_MATRIX_ZIGZAG,
  NEO_GRB + NEO_KHZ800);

float brightness = 0.3; // Luminosité initiale (0.0 à 1.0)
int displayDelay = 10; // Temps en secondes avant alternance entre heure et date
bool showTime = true;


const char* ssid = "ESP8266_AP";
const char* password = "password";

AsyncWebServer server(80);
WiFiUDP udp;
NTPClient timeClient(udp, "pool.ntp.org", 3600);
RTC_DS3231 rtc;
unsigned long lastSwitchTime = 0;

void setup() {
    Serial.begin(115200);
    Wire.begin();
    leds.begin(); // Initialisation des LEDs
    EEPROM.begin(512); // Initialiser l'EEPROM une seule fois

    if (!rtc.begin()) {
        Serial.println("Erreur : Impossible de trouver le module DS3231 !");
        while (1);  // Blocage si le DS3231 n'est pas trouvé
    }

    if (rtc.lostPower()) {
        rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    }

    DateTime now = rtc.now();
    Serial.print("Heure actuelle du DS3231 : ");
    Serial.print(now.hour());
    Serial.print(":");
    Serial.print(now.minute());
    Serial.print(":");
    Serial.println(now.second());

    WiFi.softAP(ssid, password);
    Serial.println("Point d'accès Wi-Fi créé");
    timeClient.begin();
    syncTimeWithNTP();

    loadBrightness();

    server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
        DateTime now = rtc.now();
        String html = "<h1>Affichage LED</h1>";
        html += "<label for='brightness'>Luminosité (0-100%) :</label>";
        html += "<input type='number' id='brightness' name='brightness' min='0' max='100' value='" + String(brightness * 100) + "'>";
        html += "<button onclick='updateBrightness()'>Valider</button>";
        html += "<script>";
        html += "function updateBrightness() {";
        html += "  var brightnessValue = document.getElementById('brightness').value;";
        html += "  fetch('/setBrightness?value=' + brightnessValue);";
        html += "}";
        html += "</script>";
        html += "<h3>Réglage de l'heure et de la date :</h3>";
        html += "<label for='hour'>Heure : </label><input type='number' id='hour' min='0' max='23' value='" + String(now.hour()) + "'><br>";
        html += "<label for='minute'>Minute : </label><input type='number' id='minute' min='0' max='59' value='" + String(now.minute()) + "'><br>";
        html += "<label for='day'>Jour : </label><input type='number' id='day' min='1' max='31' value='" + String(now.day()) + "'><br>";
        html += "<label for='month'>Mois : </label><input type='number' id='month' min='1' max='12' value='" + String(now.month()) + "'><br>";
        html += "<label for='year'>Année : </label><input type='number' id='year' min='2020' max='2100' value='" + String(now.year()) + "'><br>";
        html += "<button onclick='submitDateTime()'>Mettre à jour</button>";
        html += "<script>function submitDateTime() {";
        html += "  let hour = document.getElementById('hour').value;";
        html += "  let minute = document.getElementById('minute').value;";
        html += "  let day = document.getElementById('day').value;";
        html += "  let month = document.getElementById('month').value;";
        html += "  let year = document.getElementById('year').value;";
        html += "  fetch('/setDateTime?hour=' + hour + '&minute=' + minute + '&day=' + day + '&month=' + month + '&year=' + year);";
        html += "}</script>";
        request->send(200, "text/html", html);
    });

    server.on("/setBrightness", HTTP_GET, [](AsyncWebServerRequest *request){
        if (request->hasParam("value")) {
            float newBrightness = request->getParam("value")->value().toFloat() / 100.0;
            brightness = constrain(newBrightness, 0.0, 1.0);
            saveBrightness(brightness);
            for (int i = 0; i < NUM_LEDS; i++) {
                uint8_t r = 255, g = 255, b = 255;
                setPixelColorWithBrightness(i, r, g, b);
            }
            leds.show();
        }
        request->send(200, "text/plain", "Luminosité mise à jour");
    });

    server.on("/setDateTime", HTTP_GET, [](AsyncWebServerRequest *request){
        if (request->hasParam("hour") && request->hasParam("minute") &&
            request->hasParam("day") && request->hasParam("month") &&
            request->hasParam("year")) {
            int hour = request->getParam("hour")->value().toInt();
            int minute = request->getParam("minute")->value().toInt();
            int day = request->getParam("day")->value().toInt();
            int month = request->getParam("month")->value().toInt();
            int year = request->getParam("year")->value().toInt();
            rtc.adjust(DateTime(year, month, day, hour, minute, 0));
            DateTime currentTime = rtc.now();
            Serial.print("Heure après mise à jour : ");
            Serial.print(currentTime.hour());
            Serial.print(":");
            Serial.print(currentTime.minute());
            Serial.println();
            request->send(200, "text/plain", "Date et heure mises à jour !");
        } else {
            request->send(400, "text/plain", "Paramètres manquants");
        }
    });

    server.begin();
}

void saveBrightness(float newBrightness) {
    int storedBrightness = newBrightness * 255.0;
    EEPROM.write(0, storedBrightness);
    EEPROM.commit();
}

void saveSettings() {
    int brightnessInt = (int)(brightness * 255);
    EEPROM.write(0, brightnessInt);
    EEPROM.commit();
}

void loadSettings() {
    int brightnessInt = EEPROM.read(0);
    brightness = brightnessInt / 255.0;

}

void syncTimeWithNTP() {
    timeClient.update();
    rtc.adjust(DateTime(timeClient.getEpochTime()));
}

void setPixelColorWithBrightness(int pixel, uint8_t r, uint8_t g, uint8_t b) {
    r = (uint8_t)(r * brightness);
    g = (uint8_t)(g * brightness);
    b = (uint8_t)(b * brightness);
    leds.setPixelColor(pixel, leds.Color(r, g, b));
}

void loadBrightness() {
    int storedBrightness = EEPROM.read(0);
    brightness = storedBrightness / 255.0;
}

void auroreBoreale(int temps) {
    for (int i = 0; i < NUM_LEDS; i++) {
        int couleur = (sin(i + millis() / 500.0) * 127 + 128);
        setPixelColorWithBrightness(i, couleur, random(0, 128), random(128, 255));
    }
    leds.show();
    delay(temps);
}
// 🔄 8. Vortex lumineux en rotation
void vortex(int vitesse) {
  int center = NUM_LEDS / 2;
  int rayon = NUM_LEDS / 4;

  for (int angle = 0; angle < 360; angle += 10) {
    for (int i = 0; i < NUM_LEDS; i++) {
      float distance = abs(i - center);
      int intensity = max(0, (int)(255 - distance * 255.0 / rayon));

      int red = (int)(sin(angle * 3.14 / 180) * 127 + 128);
      int green = (int)(sin((angle + 120) * 3.14 / 180) * 127 + 128);
      int blue = (int)(sin((angle + 240) * 3.14 / 180) * 127 + 128);

      leds.setPixelColor(i, leds.Color(red * intensity / 255, green * intensity / 255, blue * intensity / 255));
    }
    leds.show();
    delay(vitesse);
  }
}

int cycleState = 0; // État de la boucle d'animation (0 = heure, 1 = animation 1, 2 = date, 3 = animation 2, 4 = texte défilant)

  void loop() {
      
      DateTime now = rtc.now();
      Serial.print("Heure du DS3231 : ");
      Serial.print(now.hour());
      Serial.print(":");
      Serial.print(now.minute());
      Serial.print(":");
      Serial.println(now.second());
    

      // Changer d'état à chaque intervalle défini
      if (millis() - lastSwitchTime > displayDelay * 1000) {
          cycleState = (cycleState + 1) % 5; // Alterner entre les états (0 à 4)
          lastSwitchTime = millis(); // Mettre à jour lastSwitchTime
      }

      // Effacer l'écran et ajuster la luminosité
      matrix.fillScreen(0);
      matrix.setTextColor(matrix.Color(250 * brightness, 0, 0));

      // En fonction de l'état, afficher l'animation ou l'heure/date
      switch (cycleState) {
          case 0: // Afficher l'heure
              matrix.setCursor(5, 1);
              matrix.print(String(now.hour()) + ":" + String(now.minute()));
              matrix.show();
              break;
          case 1: // Animation 1 (aurore boréale)
              auroreBoreale(2000); // Durée de l'animation
              break;
          case 2: // Afficher la date
              matrix.setCursor(5, 1);
              matrix.print(String(now.day()) + "/" + String(now.month()));
              matrix.show();
              break;
          case 3: // Animation 2 (vortex lumineux)
              vortex(50); // Durée de l'animation
              break;
          case 4: // Affichage défilant du texte
      // Défilement du texte "Bienvenue DEUDEU" à partir de la position (x = 5, y = 1)
      // Appliquer la luminosité à la couleur du texte
      uint32_t textColor = matrix.Color(250 * brightness, 130 * brightness, 0); // Appliquer la luminosité
      matrix.setTextColor(textColor);

      for (int x = 31; x >= -81; x -= 1) { 
          matrix.setCursor(x + 5, 1); // Début du texte à x = 5
          matrix.print("Bon anniversaire");
          matrix.show();
          delay(80); // Délai pour le défilement
          matrix.fillScreen(0); // Effacer l'écran entre les déplacements
      }

      // Appliquer la luminosité à la couleur "DeuDeu"
      uint32_t textColorDeuDeu = matrix.Color(250 * brightness, 0, 0); // Appliquer la luminosité
      matrix.setTextColor(textColorDeuDeu);
      matrix.setCursor(5, 1); 
      matrix.print("DeuDeu");  
      matrix.show();
      delay(2000); // Attente avant la prochaine animation

      // Appliquer la luminosité au texte défilant "DeuDeu" à différentes positions y
      uint32_t textColorDeuDeu2 = matrix.Color(250 * brightness, 130 * brightness, 0); // Appliquer la luminosité
      matrix.setTextColor(textColorDeuDeu2);
      for (int y = 1; y <= 8; y += 1) { 
          matrix.setCursor(5, y); // Utilisation de x = 5, y défile de 1 à 8
          matrix.print("DeuDeu");  
          matrix.show();
          delay(30); // Délai entre chaque ligne
          matrix.fillScreen(0); // Effacer l'écran entre les déplacements
      }

      matrix.show();
      break;
      }

      delay(1000); // Petite pause pour laisser le temps aux animations de se dérouler
}  

Tu as une pile ou une batterie de sauvegarde sur ton DS3231?
Si ce n'est pas le cas, ou si la batterie est déchargée, à chaque démarrage tu exécutes le if ci-dessous qui remet l'heure par défaut.


Ce n'est pas un projet fini. Je le déplace à la racine du forum francophone.

Merci de m'aider, J'ai commenté cette partie pour quelle ne soit pas pris en compte dans le programme mais cela ne résous pas le problème, je m'arrache les cheveux sur ce soucis...

    if (rtc.lostPower()) {
        rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    }

Et tu as une pile/batterie de sauvegarde avec une tension correcte?

j'ai une pile pour la sauvegarde, je l'ai mesuré au testeur elle semble ok, mais dans le doute ce soir je la remplacerai, dans mon code je fait souvent appel à : slight_smile: timeClient.begin();
syncTimeWithNTP();

Au moins 3 fois mais je n'ai pas accès à internet et je ne fonctionne que sur le ds3132 et mise à jour de l'heure et la date via AP local sur une page web

la mise à jour du panneau de 256 leds ws2812b est couteux en temps et bloque les interruptions pendant ce temps là (environ 8ms); ça peut jouer sur la stabilité du WiFi car vous êtes sur un mono-coeur. Un ESP32 avec 2 coeurs serait plus stable sans doute.

Pourquoi inclure NTP si vous n'avez pas de connexion Internet ?

Oui, mais si tu n'as pas accès à internet, je ne sais pas ce que fait syncTimeWithNTP();
Essaie de mettre cette ligne en commentaire pour voir si cela résout ton problème.

en effet inutile (c'était au cas ou, mais là ou est utilisé l'horloge je n'aurais pas accès à internet) je vais les enlever ou commenté, mais cela peut il avoir une influence sur le fait que mon heure ne reste pas enregistrer après arrêt et relance de l'horloge?

Ça dépend de ce que fait syncTimeWithNTP() lorsque le serveur NTP ne peut pas être joint.
Le plus simple c'est d'essayer et de voir ce qu'il se passe.

bon cela avance :zany_face: en effet j'ai supprimé les timeClient.begin();
syncTimeWithNTP(); et cela va bien chercher maintenant l'heure sur le ds3132
j'en ai profité pour alléger le code en enlevant tous ce qui est inutile

mais bon j'ai 1 dernier petit souci :

  • si j'arrête l'horloge et que je relance 5mn après cela ne le prendre pas en compte ex: je coupe l'alimentation à 12h05 j'attends 5 mn puis rebranche et cela remet 12h05 au lieu de logiquement 12h10.

merci encore pour votre aide
voici le code légèrement allégé:

#include <ESPAsyncWebServer.h>
#include <WiFiUdp.h>
#include <NTPClient.h>
#include <Wire.h>
#include <RTClib.h>
#include <Adafruit_GFX.h>
#include <Adafruit_NeoMatrix.h>
#include <Adafruit_NeoPixel.h>
#include <EEPROM.h>

#define LED_PIN D3  // Correspond à D4 sur la Wemos D1 Mini  
#define NUM_LEDS 256 // 8x32 = 256 LEDs

// Configuration du panneau LED 8x32  
Adafruit_NeoPixel leds(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);
Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(32, 8, LED_PIN,
  NEO_MATRIX_BOTTOM + NEO_MATRIX_RIGHT +
  NEO_MATRIX_COLUMNS + NEO_MATRIX_ZIGZAG,
  NEO_GRB + NEO_KHZ800);

float brightness = 0.3; // Luminosité initiale (  . à 1.)
int displayDelay = 10; // Temps en secondes avant alternance entre heure et date  
bool showTime = true;

const char* ssid = "ESP8266_AP";
const char* password = "password";

AsyncWebServer server(80);
RTC_DS3231 rtc;
unsigned long lastSwitchTime = 0;

void setup() {
    Serial.begin(115200);
    Wire.begin();
    leds.begin(); // Initialisation des LEDs  
    EEPROM.begin(512); // Initialiser l'EEPROM une seule fois

    if (!rtc.begin()) {
        Serial.println("Erreur : Impossible de trouver le module DS3231 !");
        while (1);  // Blocage si le DS3231 n'est pas trouvé  
    }


if (rtc.lostPower()) {
    Serial.println("Le DS3231 a perdu l'alimentation, initialisation...");
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // Mise à l'heure initiale
}

    loadDateTime(); // Charge l'heure et la date depuis l'EEPROM

    WiFi.softAP(ssid, password);

    loadBrightness();

    server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
        DateTime now = rtc.now();
        String html = "<h1>Affichage LED</h1>";
        html += "<label for='brightness'>Luminosité (-100%) :</label>";
        html += "<input type='number' id='brightness' name='brightness' min='' max='100' value='" + String(brightness * 100) + "'>";
        html += "<button onclick='updateBrightness()'>Valider</button>";
        html += "<script>";
        html += "function updateBrightness() {";
        html += "  var brightnessValue = document.getElementById('brightness').value;";
        html += "  fetch('/setBrightness?value=' + brightnessValue);";
        html += "}";
        html += "</script>";
        html += "<h3>Réglage de l'heure et de la date :</h3>";
        html += "<label for='hour'>Heure : </label><input type='number' id='hour' min='' max='23' value='" + String(now.hour()) + "'><br>";
        html += "<label for='minute'>Minute : </label><input type='number' id='minute' min='' max='59' value='" + String(now.minute()) + "'><br>";
        html += "<label for='day'>Jour : </label><input type='number' id='day' min='1' max='31' value='" + String(now.day()) + "'><br>";
        html += "<label for='month'>Mois : </label><input type='number' id='month' min='1' max='12' value='" + String(now.month()) + "'><br>";
        html += "<label for='year'>Année : </label><input type='number' id='year' min='202' max='210' value='" + String(now.year()) + "'><br>";
        html += "<button onclick='submitDateTime()'>Mettre à jour</button>";
        html += "<script>function submitDateTime() {";
        html += "  let hour = document.getElementById('hour').value;";
        html += "  let minute = document.getElementById('minute').value;";
        html += "  let day = document.getElementById('day').value;";
        html += "  let month = document.getElementById('month').value;";
        html += "  let year = document.getElementById('year').value;";
        html += "  fetch('/setDateTime?hour=' + hour + '&minute=' + minute + '&day=' + day + '&month=' + month + '&year=' + year);";
        html += "}</script>";
        request->send(200, "text/html", html);
    });

    server.on("/setBrightness", HTTP_GET, [](AsyncWebServerRequest *request){
        if (request->hasParam("value")) {
            float newBrightness = request->getParam("value")->value().toFloat() / 100.0;
            brightness = constrain(newBrightness, 0.0, 1.0);
            saveBrightness(brightness);
            for (int i = 0; i < NUM_LEDS; i++) {
                uint8_t r = 255, g = 255, b = 255;
                setPixelColorWithBrightness(i, r, g, b);
            }
            leds.show();
        }
        request->send(200, "text/plain", "Luminosité mise à jour");
    });

    server.on("/setDateTime", HTTP_GET, [](AsyncWebServerRequest *request){
        if (request->hasParam("hour") && request->hasParam("minute") &&
            request->hasParam("day") && request->hasParam("month") &&
            request->hasParam("year")) {
            int hour = request->getParam("hour")->value().toInt();
            int minute = request->getParam("minute")->value().toInt();
            int day = request->getParam("day")->value().toInt();
            int month = request->getParam("month")->value().toInt();
            int year = request->getParam("year")->value().toInt();
            rtc.adjust(DateTime(year, month, day, hour, minute, 0));
            saveDateTime(hour, minute, day, month, year); // Sauvegarde l'heure et la date  
            request->send(200, "text/plain", "Date et heure mises à jour !");
        } else {
            request->send(400, "text/plain", "Paramètres manquants");
        }
    });

    server.begin();
}

void saveBrightness(float newBrightness) {
    int storedBrightness = newBrightness * 255.0;
    EEPROM.write(0, storedBrightness);
    EEPROM.commit();
}

void saveDateTime(int hour, int minute, int day, int month, int year) {
    EEPROM.write(1, hour);   // Adresse 1 pour l'heure  
    EEPROM.write(2, minute); // Adresse 2 pour la minute  
    EEPROM.write(3, day);    // Adresse 3 pour le jour  
    EEPROM.write(4, month);  // Adresse 4 pour le mois  
    EEPROM.write(5, year);   // Adresse 5 pour l'année  
    EEPROM.commit();
}

void loadDateTime() {
    int hour = EEPROM.read(1);
    int minute = EEPROM.read(2);
    int day = EEPROM.read(3);
    int month = EEPROM.read(4);
    int year = EEPROM.read(5);
    rtc.adjust(DateTime(year, month, day, hour, minute, 0)); // Ajuste le RTC  
}

void setPixelColorWithBrightness(int pixel, uint8_t r, uint8_t g, uint8_t b) {
    r = (uint8_t)(r * brightness);
    g = (uint8_t)(g * brightness);
    b = (uint8_t)(b * brightness);
    leds.setPixelColor(pixel, leds.Color(r, g, b));
}

void loadBrightness() {
    int storedBrightness = EEPROM.read(0);
    brightness = storedBrightness / 255.0;
}

void auroreBoreale(int temps) {
    for (int i = 0; i < NUM_LEDS; i++) {
        int couleur = (sin(i + millis() / 500.0 ) * 127 + 128);
        setPixelColorWithBrightness(i, couleur, random(0, 128), random(128, 255));
    }
    leds.show();
    delay(temps);
}
// 🌈13. Pluie de couleurs
void pluieDeCouleurs(int temps) {
  for (int i = 0; i < NUM_LEDS; i++) {
    int couleur = random(0, 65536);  // Générer une couleur aléatoire
    leds.setPixelColor(i, leds.gamma32(leds.ColorHSV(couleur)));
  }
  leds.show();
  delay(temps); // Intervalle entre chaque "pluie"
}



int cycleState = 0; // État de la boucle d'animation ( = heure, 1 = animation 1, 2 = date, 3 = animation 2, 4 = texte défilant)

void loop() {

    // Changer d'état à chaque intervalle défini  
    if (millis() - lastSwitchTime > displayDelay * 1000) {
        cycleState = (cycleState + 1) % 5; // Alterner entre les états ( à 4)
        lastSwitchTime = millis(); // Mettre à jour lastSwitchTime  
    }

    // Effacer l'écran et ajuster la luminosité  
    matrix.fillScreen(0);
    matrix.setTextColor(matrix.Color(250 * brightness, 0, 0));

            DateTime now = rtc.now();  // Obtenir l'heure actuelle depuis le RTC

    // En fonction de l'état, afficher l'animation ou l'heure/date  
    switch (cycleState) {
        case 0: // Afficher l'heure
             matrix.setCursor(1, 1);
             matrix.print(String(now.hour()) + ":" + (now.minute() < 10 ? "0" + String(now.minute()) : String(now.minute())));
             matrix.show();
             break;
        case 1: // Animation 1 (aurore boréale)
            auroreBoreale(200); // Durée de l'animation  
            break;
        case 2: // Afficher la date  
            matrix.setCursor(5, 1);
            matrix.print(String(now.day()) + "/" + String(now.month()));
            matrix.show();
            break;
        case 3: // pluie de couleur
            pluieDeCouleurs(100); // Durée de l'animation  
            break;
        case 4: // Affichage défilant du texte  
            uint32_t textColor = matrix.Color(250 * brightness, 130 * brightness, 0); // Appliquer la luminosité  
            matrix.setTextColor(textColor);

            for (int x = 31; x >= -81; x -= 1) { 
                matrix.setCursor(x + 5, 1); // Début du texte à x = 5  
                matrix.print("Bon anniversaire");
                matrix.show();
                delay(80); // Délai pour le défilement  
                matrix.fillScreen(0); // Effacer l'écran entre les déplacements  
            }

            // Appliquer la luminosité au texte "DeuDeu"
            uint32_t textColorDeuDeu = matrix.Color(250 * brightness, 0, 0); // Appliquer la luminosité  
            matrix.setTextColor(textColorDeuDeu);
            matrix.setCursor(5, 1); 
            matrix.print("2-2");  
            matrix.show();
            delay(200); // Attente avant la prochaine animation

            // Appliquer la luminosité au texte défilant "DeuDeu" à différentes positions y  
            uint32_t textColorDeuDeu2 = matrix.Color(250 * brightness, 130 * brightness, 0); // Appliquer la luminosité  
            matrix.setTextColor(textColorDeuDeu2);
            for (int y = 1; y <= 8; y += 1) { 
                matrix.setCursor(5, y); // Utilisation de x = 5, y défile de 1 à 8  
                matrix.print("2-2");  
                matrix.show();
                delay(30); // Délai entre chaque ligne  
                matrix.fillScreen(0); // Effacer l'écran entre les déplacements  
            }

            matrix.show();
            break;
    }

    delay(100); // Petite pause pour laisser le temps aux animations de se dérouler  
}
saisissez ou collez du code ici

Virez ces lignes

Ceci est une erreur vous ne pouvez pas déclarer une variable locale dans un case sans {}

Activez les warnings dans les préférences de l’IDE et assurez vous de n’avoir aucun warning quand vous compilez.

merci j'ai enlevé ces lignes, mais cela ne règle pas le problème, en // j'ai activé les warnings et j'ai corrigé et aucune erreur remonte lors du compilage

merci pour votre aide

postez le nouveau code

voici le code merci

#include <ESPAsyncWebServer.h>
#include <WiFiUdp.h>
#include <NTPClient.h>
#include <Wire.h>
#include <RTClib.h>
#include <Adafruit_GFX.h>
#include <Adafruit_NeoMatrix.h>
#include <Adafruit_NeoPixel.h>
#include <EEPROM.h>

#define LED_PIN D3  // Correspond à D4 sur la Wemos D1 Mini  
#define NUM_LEDS 256 // 8x32 = 256 LEDs

// Configuration du panneau LED 8x32  
Adafruit_NeoPixel leds(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);
Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(32, 8, LED_PIN,
  NEO_MATRIX_BOTTOM + NEO_MATRIX_RIGHT +
  NEO_MATRIX_COLUMNS + NEO_MATRIX_ZIGZAG,
  NEO_GRB + NEO_KHZ800);

float brightness = 0.3; // Luminosité initiale (  . à 1.)
int displayDelay = 10; // Temps en secondes avant alternance entre heure et date  
bool showTime = true;

const char* ssid = "ESP8266_AP";
const char* password = "password";

AsyncWebServer server(80);
RTC_DS3231 rtc;
unsigned long lastSwitchTime = 0;

void setup() {
    Serial.begin(115200);
    Wire.begin();
    leds.begin(); // Initialisation des LEDs  
    EEPROM.begin(512); // Initialiser l'EEPROM une seule fois

    loadDateTime(); // Charge l'heure et la date depuis l'EEPROM

    WiFi.softAP(ssid, password);

    loadBrightness();

    server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
        DateTime now = rtc.now();
        String html = "<h1>Affichage LED</h1>";
        html += "<label for='brightness'>Luminosité (-100%) :</label>";
        html += "<input type='number' id='brightness' name='brightness' min='' max='100' value='" + String(brightness * 100) + "'>";
        html += "<button onclick='updateBrightness()'>Valider</button>";
        html += "<script>";
        html += "function updateBrightness() {";
        html += "  var brightnessValue = document.getElementById('brightness').value;";
        html += "  fetch('/setBrightness?value=' + brightnessValue);";
        html += "}";
        html += "</script>";
        html += "<h3>Réglage de l'heure et de la date :</h3>";
        html += "<label for='hour'>Heure : </label><input type='number' id='hour' min='' max='23' value='" + String(now.hour()) + "'><br>";
        html += "<label for='minute'>Minute : </label><input type='number' id='minute' min='' max='59' value='" + String(now.minute()) + "'><br>";
        html += "<label for='day'>Jour : </label><input type='number' id='day' min='1' max='31' value='" + String(now.day()) + "'><br>";
        html += "<label for='month'>Mois : </label><input type='number' id='month' min='1' max='12' value='" + String(now.month()) + "'><br>";
        html += "<label for='year'>Année : </label><input type='number' id='year' min='202' max='210' value='" + String(now.year()) + "'><br>";
        html += "<button onclick='submitDateTime()'>Mettre à jour</button>";
        html += "<script>function submitDateTime() {";
        html += "  let hour = document.getElementById('hour').value;";
        html += "  let minute = document.getElementById('minute').value;";
        html += "  let day = document.getElementById('day').value;";
        html += "  let month = document.getElementById('month').value;";
        html += "  let year = document.getElementById('year').value;";
        html += "  fetch('/setDateTime?hour=' + hour + '&minute=' + minute + '&day=' + day + '&month=' + month + '&year=' + year);";
        html += "}</script>";
        request->send(200, "text/html", html);
    });

    server.on("/setBrightness", HTTP_GET, [](AsyncWebServerRequest *request){
        if (request->hasParam("value")) {
            float newBrightness = request->getParam("value")->value().toFloat() / 100.0;
            brightness = constrain(newBrightness, 0.0, 1.0);
            saveBrightness(brightness);
            for (int i = 0; i < NUM_LEDS; i++) {
                uint8_t r = 255, g = 255, b = 255;
                setPixelColorWithBrightness(i, r, g, b);
            }
            leds.show();
        }
        request->send(200, "text/plain", "Luminosité mise à jour");
    });

    server.on("/setDateTime", HTTP_GET, [](AsyncWebServerRequest *request){
        if (request->hasParam("hour") && request->hasParam("minute") &&
            request->hasParam("day") && request->hasParam("month") &&
            request->hasParam("year")) {
            int hour = request->getParam("hour")->value().toInt();
            int minute = request->getParam("minute")->value().toInt();
            int day = request->getParam("day")->value().toInt();
            int month = request->getParam("month")->value().toInt();
            int year = request->getParam("year")->value().toInt();
            rtc.adjust(DateTime(year, month, day, hour, minute, 0));
            saveDateTime(hour, minute, day, month, year); // Sauvegarde l'heure et la date  
            request->send(200, "text/plain", "Date et heure mises à jour !");
        } else {
            request->send(400, "text/plain", "Paramètres manquants");
        }
    });

    server.begin();
}

void saveBrightness(float newBrightness) {
    int storedBrightness = newBrightness * 255.0;
    EEPROM.write(0, storedBrightness);
    EEPROM.commit();
}

void saveDateTime(int hour, int minute, int day, int month, int year) {
    EEPROM.write(1, hour);   // Adresse 1 pour l'heure  
    EEPROM.write(2, minute); // Adresse 2 pour la minute  
    EEPROM.write(3, day);    // Adresse 3 pour le jour  
    EEPROM.write(4, month);  // Adresse 4 pour le mois  
    EEPROM.write(5, year);   // Adresse 5 pour l'année  
    EEPROM.commit();
}

void loadDateTime() {
    int hour = EEPROM.read(1);
    int minute = EEPROM.read(2);
    int day = EEPROM.read(3);
    int month = EEPROM.read(4);
    int year = EEPROM.read(5);
    rtc.adjust(DateTime(year, month, day, hour, minute, 0)); // Ajuste le RTC  
}

void setPixelColorWithBrightness(int pixel, uint8_t r, uint8_t g, uint8_t b) {
    r = (uint8_t)(r * brightness);
    g = (uint8_t)(g * brightness);
    b = (uint8_t)(b * brightness);
    leds.setPixelColor(pixel, leds.Color(r, g, b));
}

void loadBrightness() {
    int storedBrightness = EEPROM.read(0);
    brightness = storedBrightness / 255.0;
}

int cycleState = 0; // État de la boucle d'animation ( = heure, 1 = animation 1, 2 = date, 3 = animation 2, 4 = texte défilant)

void loop() {

    // Changer d'état à chaque intervalle défini  
    if (millis() - lastSwitchTime > displayDelay * 1000) {
        cycleState = (cycleState + 1) % 3; // Alterner entre les états ( à 4)
        lastSwitchTime = millis(); // Mettre à jour lastSwitchTime  
    }

    // Effacer l'écran et ajuster la luminosité  
    matrix.fillScreen(0);
    matrix.setTextColor(matrix.Color(250 * brightness, 0, 0));

            DateTime now = rtc.now();  // Obtenir l'heure actuelle depuis le RTC

    // En fonction de l'état, afficher l'animation ou l'heure/date  
    switch (cycleState) {
        case 0: // Afficher l'heure
             matrix.setCursor(1, 1);
             matrix.print(String(now.hour()) + ":" + (now.minute() < 10 ? "0" + String(now.minute()) : String(now.minute())));
             matrix.show();
            break;
        case 1: // Afficher la date  
            matrix.setCursor(5, 1);
            matrix.print(String(now.day()) + "/" + String(now.month()));
            matrix.show();
            break;
        case 2: // Affichage défilant du texte  
            uint32_t textColor = matrix.Color(250 * brightness, 130 * brightness, 0); // Appliquer la luminosité  
            matrix.setTextColor(textColor);

            for (int x = 31; x >= -81; x -= 1) { 
                matrix.setCursor(x + 5, 1); // Début du texte à x = 5  
                matrix.print("Bon anniversaire");
                matrix.show();
                delay(80); // Délai pour le défilement  
                matrix.fillScreen(0); // Effacer l'écran entre les déplacements  
            }

            // Appliquer la luminosité au texte "DeuDeu"
            uint32_t textColorDeuDeu = matrix.Color(250 * brightness, 0, 0); // Appliquer la luminosité  
            matrix.setTextColor(textColorDeuDeu);
            matrix.setCursor(5, 1); 
            matrix.print("2-2");  
            matrix.show();
            delay(200); // Attente avant la prochaine animation

            // Appliquer la luminosité au texte défilant "DeuDeu" à différentes positions y  
            uint32_t textColorDeuDeu2 = matrix.Color(250 * brightness, 130 * brightness, 0); // Appliquer la luminosité  
            matrix.setTextColor(textColorDeuDeu2);
            for (int y = 1; y <= 8; y += 1) { 
                matrix.setCursor(5, y); // Utilisation de x = 5, y défile de 1 à 8  
                matrix.print("2-2");  
                matrix.show();
                delay(30); // Délai entre chaque ligne  
                matrix.fillScreen(0); // Effacer l'écran entre les déplacements  
            }

            matrix.show();
            break;
    }

    delay(100); // Petite pause pour laisser le temps aux animations de se dérouler  
}
saisissez ou collez du code ici

Attention à ce genre de multiplication car vous avez deux int. Si displayDelay valait 40, ça ferait 40,000 et ce n’est pas représentable sur 2 octets sur un uno ou mega. Utilisé des unsigned long pour le temps et le suffix ul (comme 1000ul) pour dire que cette valeur doit être codée sur 32 bits et non signée. Ici vous êtes sur une plateforme 32 bits donc pas de souci mais il faut conserver cela à l’esprit.

—-

Vous avez toujours des définitions de variables dans le switch


A quoi sert l’usage de l’eeprom?

ok je reprends la ligne:

if (millis() - lastSwitchTime > displayDelay * 1000) {

bizarre j'ai bien mis le warning sur les préferences et cela ne remonte pas d'erreur la dessus, je regarde de plus prés

      case 2: // Affichage défilant du texte  
            uint32_t textColor = matrix.Color(250 * brightness, 130 * brightness, 0); // Appliquer la luminosité  
            matrix.setTextColor(textColor);

l'eeproom sert a garder le niveau de luminosité voulu pour que lors du démarrage de l'horloge elle soit comme on l'a déterminée sur l'interface web.

void saveBrightness(float newBrightness) {
    int storedBrightness = newBrightness * 255.0;
    EEPROM.write(0, storedBrightness);
    EEPROM.commit();

ce je ne sais plus pourquoi je l'ai mis , j'ai tellement fait des essais que parfois dans le code je me pers et du coup je ne sais même plus si cela est utile

void saveDateTime(int hour, int minute, int day, int month, int year) {
    EEPROM.write(1, hour);   // Adresse 1 pour l'heure  
    EEPROM.write(2, minute); // Adresse 2 pour la minute  
    EEPROM.write(3, day);    // Adresse 3 pour le jour  
    EEPROM.write(4, month);  // Adresse 4 pour le mois  
    EEPROM.write(5, year);   // Adresse 5 pour l'année  
    EEPROM.commit();
}
void loadDateTime() {
    int hour = EEPROM.read(1);
    int minute = EEPROM.read(2);
    int day = EEPROM.read(3);
    int month = EEPROM.read(4);
    int year = EEPROM.read(5);
    rtc.adjust(DateTime(year, month, day, hour, minute, 0)); // Ajuste le RTC  
}

et ca je veux mettre en place un démarrage arrêt selon heure déterminé sur l'interface web mais bon pas encore fini et cela n'aurais pas du être là je sais c'est un gros bordel

oid saveSchedule() {
    EEPROM.write(10, startHour);
    EEPROM.write(11, startMinute);
    EEPROM.write(12, stopHour);
    EEPROM.write(13, stopMinute);
    EEPROM.commit();
}

Ben si vous mettez a jour l’horloge avec une heure sauvée en mémoire …

Essayez de faire un grand ménage de printemps;)

Bonjour @carica
Je n'ai que survolé votre code car je suis en déplacement et sur téléphone mais comme l'a dit @J-M-L vous utilisez la valeur enregistrée en mémoire pour remettre à l'heure votre RTC, ça ne peux pas fonctionner... Le petit ménage de printemps est en effet une bonne idée :slight_smile:

Remarque pour moi même car c'est une évidence, mais c'est peut être pour cela que votre code contient l'importation d'un client NTP, ça vous permettrait d'utiliser un service en ligne pour mettre à l'heure votre ESP8266, mais ça ne sert à rien effectivement vu que vous avez déjà une RTC.

Je vois deux trois choses qui peuvent être améliorées dans le code (je précise que je suis un débutant donc il est tout à fait possible et même probable que je me trompe)... Tout d'abord dans la fonction

void saveBrightness(float newBrightness) {
    int storedBrightness = newBrightness * 255.0;
    EEPROM.write(0, storedBrightness);
    EEPROM.commit();
}

Il me semble qu'il y a une perte de données vu que vous utilisez un int pour stocker le résultat d'une opération sur des float (vous pourriez envisager de ne pas passer par une variable intermédiaire)

Ensuite vous avez deux éléments que vous pourriez simplifier/sécuriser : les adresses mémoire dans l'EEPROM ainsi que les états de la machine à état que je crois avoir identifié pour l'affichage que vous faites dans la loop. Ça peut être stocké dans un enum ?

Enfin je ne sais pas si ça peut impacter quelque chose notamment le serveur web mais votre loop est assez bloquante - peut-être pouvez-vous remplacer tous vos delay par une gestion avec millis sur les points nécessaires ?

Je rappelle que je suis débutant donc je peux me tromper sur tous ce que je viens de dire, sachant qu'en plus je n'ai qu'une connaissance très limitée des technos utilisées ici :woozy_face:

Cordialement,
Pandaroux007