#include <FastLED.h> //https://github.com/FastLED/FastLED #include <LEDMatrix.h> //https://github.com/Jorgen-VikingGod/LEDMatrix #include <NTPClient.h> #include <ESP8266WiFi.h> #include <WiFiUdp.h> #include "RTClib.h" #define DATA_PIN 2 #define COLOR_ORDER GRB #define CHIPSET WS2812B // initial matrix layout (to get led strip index by x/y) #define MATRIX_WIDTH 8 #define MATRIX_HEIGHT 8 #define MATRIX_TYPE VERTICAL_MATRIX #define MATRIX_SIZE (MATRIX_WIDTH * MATRIX_HEIGHT) #define NUMPIXELS MATRIX_SIZE cLEDMatrix<MATRIX_WIDTH, MATRIX_HEIGHT, MATRIX_TYPE> leds; #include <ESP8266WebServer.h> //pour pouvoir changer les couleurs des leds à partir d'une page web ESP8266WebServer server(80); //déclare le webserver RTC_DS3231 rtc; //déclare le module RTC WiFiUDP ntpUDP; //déclare le serveur de temps externe NTPClient timeClient(ntpUDP, "europe.pool.ntp.org", 7200, 60000); //7200 pour le fuseau horaire + 2h int S, M, H; int hueH = 0; //valeur hue des leds affichant l'heure , hue max avec fast led 255 int hueM = 160; //valeur hue des leds affichant les minutes int hueS = 96; //valeur hue des leds affichant les secondes int saturation = 255; //saturation int bright = 130; //luminosité des leds const char* ssid = "xxxxxxxxxxx"; //nom du wifi const char* password = "yyyyyyyyyyyyy"; //mdp du wifi uint16_t miseAjourHeure = 0; //pour mettre à jour l'heure par le serveur de temps toutes les heures void setup() { Serial.begin(57600); WiFi.begin(ssid, password); //initialise wifi while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } // Imprime l'adresse IP sur la console série Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: " + WiFi.localIP().toString()); if (!rtc.begin()) { //initialise module RTC Serial.println("Couldn't find RTC"); Serial.flush(); while (1) delay(10); } timeClient.begin(); //initialise le serveur de temps updateHeure(); //void pour mettre à jour l'heure avec le serveur de temps server.on("/", HTTP_GET, handleRoot); //initialise le web server server.on("/values", HTTP_GET, handleValues); server.begin(); FastLED.addLeds<CHIPSET, DATA_PIN, COLOR_ORDER>(leds[0], leds.Size()).setCorrection(TypicalSMD5050); FastLED.setCorrection(TypicalLEDStrip); //FastLED.setBrightness(100); FastLED.clear(true); // on éteint toutes les LEDs } void loop() { delay(1000); miseAjourHeure += 1; if (miseAjourHeure == 3600) { //remet à jour l'heure par le serveur de temps à intervalle régulier, ici toutes les heures miseAjourHeure = 0; updateHeure(); } /*pour DEBUG Serial.print(now.hour(), DEC); Serial.print(':'); Serial.print(now.minute(), DEC); Serial.print(':'); Serial.print(now.second(), DEC); Serial.println();*/ server.handleClient(); //pour lire couleurs envoyées au serveur web par la page web d'un navigateur FastLED.clear(true); // on éteint toutes les LEDs DateTime now = rtc.now(); H = now.hour(); M = now.minute(); S = now.second(); //procédure pour mettre chaque valeur sur 2 digits int Hd = (H / 10U) % 10; //premier digit des heures int Hu = (H / 1U) % 10; //deuxieme digit des heures int Md = (M / 10U) % 10; //premier digit des minutes int Mu = (M / 1U) % 10; //deuxieme digit des minutes int Sd = (S / 10U) % 10; //premier digit des secondes int Su = (S / 1U) % 10; //deuxieme digit des secondes switch (Hu) { case 0: leds.DrawPixel(1, 0, CHSV(0, 0, 0)); leds.DrawPixel(1, 2, CHSV(0, 0, 0)); leds.DrawPixel(1, 4, CHSV(0, 0, 0)); leds.DrawPixel(1, 6, CHSV(0, 0, 0)); break; case 1: leds.DrawPixel(1, 0, CHSV(hueH, saturation, bright)); leds.DrawPixel(1, 2, CHSV(0, 0, 0)); leds.DrawPixel(1, 4, CHSV(0, 0, 0)); leds.DrawPixel(1, 6, CHSV(0, 0, 0)); break; case 2: leds.DrawPixel(1, 0, CHSV(0, 0, 0)); leds.DrawPixel(1, 2, CHSV(hueH, saturation, bright)); leds.DrawPixel(1, 4, CHSV(0, 0, 0)); leds.DrawPixel(1, 6, CHSV(0, 0, 0)); break; case 3: leds.DrawPixel(1, 0, CHSV(hueH, saturation, bright)); leds.DrawPixel(1, 2, CHSV(hueH, saturation, bright)); leds.DrawPixel(1, 4, CHSV(0, 0, 0)); leds.DrawPixel(1, 6, CHSV(0, 0, 0)); break; case 4: leds.DrawPixel(1, 0, CHSV(0, 0, 0)); leds.DrawPixel(1, 2, CHSV(0, 0, 0)); leds.DrawPixel(1, 4, CHSV(hueH, saturation, bright)); leds.DrawPixel(1, 6, CHSV(0, 0, 0)); break; case 5: leds.DrawPixel(1, 0, CHSV(hueH, saturation, bright)); leds.DrawPixel(1, 2, CHSV(0, 0, 0)); leds.DrawPixel(1, 4, CHSV(hueH, saturation, bright)); leds.DrawPixel(1, 6, CHSV(0, 0, 0)); break; case 6: leds.DrawPixel(1, 0, CHSV(0, 0, 0)); leds.DrawPixel(1, 2, CHSV(hueH, saturation, bright)); leds.DrawPixel(1, 4, CHSV(hueH, saturation, bright)); leds.DrawPixel(1, 6, CHSV(0, 0, 0)); break; case 7: leds.DrawPixel(1, 0, CHSV(hueH, saturation, bright)); leds.DrawPixel(1, 2, CHSV(hueH, saturation, bright)); leds.DrawPixel(1, 4, CHSV(hueH, saturation, bright)); leds.DrawPixel(1, 6, CHSV(0, 0, 0)); break; case 8: leds.DrawPixel(1, 0, CHSV(0, 0, 0)); leds.DrawPixel(1, 2, CHSV(0, 0, 0)); leds.DrawPixel(1, 4, CHSV(0, 0, 0)); leds.DrawPixel(1, 6, CHSV(hueH, saturation, bright)); break; case 9: leds.DrawPixel(1, 0, CHSV(hueH, saturation, bright)); leds.DrawPixel(1, 2, CHSV(0, 0, 0)); leds.DrawPixel(1, 4, CHSV(0, 0, 0)); leds.DrawPixel(1, 6, CHSV(hueH, saturation, bright)); break; } switch (Hd) { case 0: leds.DrawPixel(0, 0, CHSV(0, 0, 0)); leds.DrawPixel(0, 2, CHSV(0, 0, 0)); break; case 1: leds.DrawPixel(0, 0, CHSV(hueH, saturation, bright)); leds.DrawPixel(0, 2, CHSV(0, 0, 0)); break; case 2: leds.DrawPixel(0, 0, CHSV(0, 0, 0)); leds.DrawPixel(0, 2, CHSV(hueH, saturation, bright)); break; } switch (Mu) { case 0: leds.DrawPixel(4, 0, CHSV(0, 0, 0)); leds.DrawPixel(4, 2, CHSV(0, 0, 0)); leds.DrawPixel(4, 4, CHSV(0, 0, 0)); leds.DrawPixel(4, 6, CHSV(0, 0, 0)); break; case 1: leds.DrawPixel(4, 0, CHSV(hueM, saturation, bright)); leds.DrawPixel(4, 2, CHSV(0, 0, 0)); leds.DrawPixel(4, 4, CHSV(0, 0, 0)); leds.DrawPixel(4, 6, CHSV(0, 0, 0)); break; case 2: leds.DrawPixel(4, 0, CHSV(0, 0, 0)); leds.DrawPixel(4, 2, CHSV(hueM, saturation, bright)); leds.DrawPixel(4, 4, CHSV(0, 0, 0)); leds.DrawPixel(4, 6, CHSV(0, 0, 0)); break; case 3: leds.DrawPixel(4, 0, CHSV(hueM, saturation, bright)); leds.DrawPixel(4, 2, CHSV(hueM, saturation, bright)); leds.DrawPixel(4, 4, CHSV(0, 0, 0)); leds.DrawPixel(4, 6, CHSV(0, 0, 0)); break; case 4: leds.DrawPixel(4, 0, CHSV(0, 0, 0)); leds.DrawPixel(4, 2, CHSV(0, 0, 0)); leds.DrawPixel(4, 4, CHSV(hueM, saturation, bright)); leds.DrawPixel(4, 6, CHSV(0, 0, 0)); break; case 5: leds.DrawPixel(4, 0, CHSV(hueM, saturation, bright)); leds.DrawPixel(4, 2, CHSV(0, 0, 0)); leds.DrawPixel(4, 4, CHSV(hueM, saturation, bright)); leds.DrawPixel(4, 6, CHSV(0, 0, 0)); break; case 6: leds.DrawPixel(4, 0, CHSV(0, 0, 0)); leds.DrawPixel(4, 2, CHSV(hueM, saturation, bright)); leds.DrawPixel(4, 4, CHSV(hueM, saturation, bright)); leds.DrawPixel(4, 6, CHSV(0, 0, 0)); break; case 7: leds.DrawPixel(4, 0, CHSV(hueM, saturation, bright)); leds.DrawPixel(4, 2, CHSV(hueM, saturation, bright)); leds.DrawPixel(4, 4, CHSV(hueM, saturation, bright)); leds.DrawPixel(4, 6, CHSV(0, 0, 0)); break; case 8: leds.DrawPixel(4, 0, CHSV(0, 0, 0)); leds.DrawPixel(4, 2, CHSV(0, 0, 0)); leds.DrawPixel(4, 4, CHSV(0, 0, 0)); leds.DrawPixel(4, 6, CHSV(hueM, saturation, bright)); break; case 9: leds.DrawPixel(4, 0, CHSV(hueM, saturation, bright)); leds.DrawPixel(4, 2, CHSV(0, 0, 0)); leds.DrawPixel(4, 4, CHSV(0, 0, 0)); leds.DrawPixel(4, 6, CHSV(hueM, saturation, bright)); break; } switch (Md) { case 0: leds.DrawPixel(3, 0, CHSV(0, 0, 0)); leds.DrawPixel(3, 2, CHSV(0, 0, 0)); leds.DrawPixel(3, 4, CHSV(0, 0, 0)); break; case 1: leds.DrawPixel(3, 0, CHSV(hueM, saturation, bright)); leds.DrawPixel(3, 2, CHSV(0, 0, 0)); leds.DrawPixel(3, 4, CHSV(0, 0, 0)); break; case 2: leds.DrawPixel(3, 0, CHSV(0, 0, 0)); leds.DrawPixel(3, 2, CHSV(hueM, saturation, bright)); leds.DrawPixel(3, 4, CHSV(0, 0, 0)); break; case 3: leds.DrawPixel(3, 0, CHSV(hueM, saturation, bright)); leds.DrawPixel(3, 2, CHSV(hueM, saturation, bright)); leds.DrawPixel(3, 4, CHSV(0, 0, 0)); break; case 4: leds.DrawPixel(3, 0, CHSV(0, 0, 0)); leds.DrawPixel(3, 2, CHSV(0, 0, 0)); leds.DrawPixel(3, 4, CHSV(hueM, saturation, bright)); break; case 5: leds.DrawPixel(3, 0, CHSV(hueM, saturation, bright)); leds.DrawPixel(3, 2, CHSV(0, 0, 0)); leds.DrawPixel(3, 4, CHSV(hueM, saturation, bright)); break; } switch (Su) { case 0: leds.DrawPixel(7, 0, CHSV(0, 0, 0)); leds.DrawPixel(7, 2, CHSV(0, 0, 0)); leds.DrawPixel(7, 4, CHSV(0, 0, 0)); leds.DrawPixel(7, 6, CHSV(0, 0, 0)); break; case 1: leds.DrawPixel(7, 0, CHSV(hueS, saturation, bright)); leds.DrawPixel(7, 2, CHSV(0, 0, 0)); leds.DrawPixel(7, 4, CHSV(0, 0, 0)); leds.DrawPixel(7, 6, CHSV(0, 0, 0)); break; case 2: leds.DrawPixel(7, 0, CHSV(0, 0, 0)); leds.DrawPixel(7, 2, CHSV(hueS, saturation, bright)); leds.DrawPixel(7, 4, CHSV(0, 0, 0)); leds.DrawPixel(7, 6, CHSV(0, 0, 0)); break; case 3: leds.DrawPixel(7, 0, CHSV(hueS, saturation, bright)); leds.DrawPixel(7, 2, CHSV(hueS, saturation, bright)); leds.DrawPixel(7, 4, CHSV(0, 0, 0)); leds.DrawPixel(7, 6, CHSV(0, 0, 0)); break; case 4: leds.DrawPixel(7, 0, CHSV(0, 0, 0)); leds.DrawPixel(7, 2, CHSV(0, 0, 0)); leds.DrawPixel(7, 4, CHSV(hueS, saturation, bright)); leds.DrawPixel(7, 6, CHSV(0, 0, 0)); break; case 5: leds.DrawPixel(7, 0, CHSV(hueS, saturation, bright)); leds.DrawPixel(7, 2, CHSV(0, 0, 0)); leds.DrawPixel(7, 4, CHSV(hueS, saturation, bright)); leds.DrawPixel(7, 6, CHSV(0, 0, 0)); break; case 6: leds.DrawPixel(7, 0, CHSV(0, 0, 0)); leds.DrawPixel(7, 2, CHSV(hueS, saturation, bright)); leds.DrawPixel(7, 4, CHSV(hueS, saturation, bright)); leds.DrawPixel(7, 6, CHSV(0, 0, 0)); break; case 7: leds.DrawPixel(7, 0, CHSV(hueS, saturation, bright)); leds.DrawPixel(7, 2, CHSV(hueS, saturation, bright)); leds.DrawPixel(7, 4, CHSV(hueS, saturation, bright)); leds.DrawPixel(7, 6, CHSV(0, 0, 0)); break; case 8: leds.DrawPixel(7, 0, CHSV(0, 0, 0)); leds.DrawPixel(7, 2, CHSV(0, 0, 0)); leds.DrawPixel(7, 4, CHSV(0, 0, 0)); leds.DrawPixel(7, 6, CHSV(hueS, saturation, bright)); break; case 9: leds.DrawPixel(7, 0, CHSV(hueS, saturation, bright)); leds.DrawPixel(7, 2, CHSV(0, 0, 0)); leds.DrawPixel(7, 4, CHSV(0, 0, 0)); leds.DrawPixel(7, 6, CHSV(hueS, saturation, bright)); break; } switch (Sd) { case 0: leds.DrawPixel(6, 0, CHSV(0, 0, 0)); leds.DrawPixel(6, 2, CHSV(0, 0, 0)); leds.DrawPixel(6, 4, CHSV(0, 0, 0)); break; case 1: leds.DrawPixel(6, 0, CHSV(hueS, saturation, bright)); leds.DrawPixel(6, 2, CHSV(0, 0, 0)); leds.DrawPixel(6, 4, CHSV(0, 0, 0)); break; case 2: leds.DrawPixel(6, 0, CHSV(0, 0, 0)); leds.DrawPixel(6, 2, CHSV(hueS, saturation, bright)); leds.DrawPixel(6, 4, CHSV(0, 0, 0)); break; case 3: leds.DrawPixel(6, 0, CHSV(hueS, saturation, bright)); leds.DrawPixel(6, 2, CHSV(hueS, saturation, bright)); leds.DrawPixel(6, 4, CHSV(0, 0, 0)); break; case 4: leds.DrawPixel(6, 0, CHSV(0, 0, 0)); leds.DrawPixel(6, 2, CHSV(0, 0, 0)); leds.DrawPixel(6, 4, CHSV(hueS, saturation, bright)); break; case 5: leds.DrawPixel(6, 0, CHSV(hueS, saturation, bright)); leds.DrawPixel(6, 2, CHSV(0, 0, 0)); leds.DrawPixel(6, 4, CHSV(hueS, saturation, bright)); break; } FastLED.show(); } void handleRoot() { //landing page quand on entre uniquement l'IP de la carte sur une page web String phrase = "<html><head><title>Horloge binaire server</title><style>body {font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;background-color:#121212;color: #eee;line-height:1.5;}"; phrase += "button { width: 100%; padding: 7px; background-color: #007BFF; color: #eeeeee; border: none; border-radius: 4px; font-size: 16px; cursor: pointer; }"; phrase += "button:hover { background-color: #0056b3; }"; phrase += "form { max-width: 250px; margin: auto; padding: 20px; background-color: #1e1e1e; border-radius: 8px;}"; phrase += "h1 { text-align: center; }"; phrase += "</style></head><body>"; phrase += "<h1>Bienvenue sur le serveur web de l'horloge binaire (Wemos D1 Mini)</h1>"; phrase += "<form id='urlForm'><button type='button' onclick='rediriger()'>Param&egrave;tres</button></form>"; phrase += "<script type='text/javascript'>"; phrase += "function rediriger() {window.location.href = 'http://" + WiFi.localIP().toString() + "/values?hueH=70&hueM=170&hueS=250&saturation=255&bright=180';}"; phrase += "</script></body></html>"; server.send(200, "text/html", phrase); //si on met "text/plain" ça écrit litéralement le texte sans mise en forme html } void handleValues() { // Récupérer les paramètres de l'URL hueH = server.arg("hueH").toInt(); hueM = server.arg("hueM").toInt(); hueS = server.arg("hueS").toInt(); saturation = server.arg("saturation").toInt(); bright = server.arg("bright").toInt(); // Répondre à la requête String response = "<html><head><title>Horloge binaire server</title><style>body {font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;background-color:#121212;color: #eee;line-height:1.1;}"; response += "form{ max-width: 230px; margin: auto; padding: 20px; background-color: #1e1e1e; border-radius: 8px;}"; response += "input[type='text'] {width:100%; padding: 5px; margin-bottom: 5px; border: 1px solid #444;background-color: #2c2c2c; color: #eeeeee; border-radius: 4px; box-sizing: border-box; font-size: 16px;}"; response += "button { width: 100%; padding: 10px; background-color: #007BFF; color: #eeeeee; border: none; border-radius: 4px; font-size: 16px; cursor: pointer; }"; response += "button:hover { background-color: #0056b3; }"; response += "h1,h2,p{ text-align: center; }"; response += "label { display: block; margin-bottom: 5px; font-weight: bold;color: #eeeeee; }"; response += ".center {display:block;margin:auto;}"; response += "</style></head><body>"; response += "<h1>Bienvenue sur le serveur web de la Wemos D1 Mini</h1>"; response += "<form id='urlForm'>"; response += "<label for='IP'>IP de la carte </label>"; response += "<input type='text' id='IP' name='IP' placeholder='" + WiFi.localIP().toString() + "' required>"; response += "<label for='hueH'>Couleur des heures </label>"; response += "<input type='text' id='hueH' name='hueH' placeholder='0 -> 255' required>"; response += "<label for='hueM'>Couleur des minutes </label>"; response += "<input type='text' id='hueM' name='hueM' placeholder='0 -> 255' required>"; response += "<label for='hueS'>Couleur des secondes </label>"; response += "<input type='text' id='hueS' name='hueS' placeholder='0 -> 255' required>"; response += "<label for='saturation'>Saturation </label>"; response += "<input type='text' id='saturation' name='saturation' placeholder='0 -> 255' required>"; response += "<label for='bright'>Luminosit&eacute; </label>"; response += "<input type='text' id='bright' name='bright' placeholder='0 -> 255' required>"; response += "<button type='button' onclick='generateURL()'>Confirmer</button>"; response += "</form>"; response += "<script>"; response += "function generateURL() {"; response += " var IP = document.getElementById('IP').value;"; response += " var hueH = document.getElementById('hueH').value;"; response += " var hueM = document.getElementById('hueM').value;"; response += " var hueS = document.getElementById('hueS').value;"; response += " var saturation = document.getElementById('saturation').value;"; response += " var bright = document.getElementById('bright').value;"; response += " if (!IP || !hueH || !hueM || !hueS || !saturation || !bright) {alert('Veuillez remplir toutes les cases.');return;}"; response += " var url = 'http://' + IP + '/values?hueH=' + hueH + '&hueM=' + hueM + '&hueS=' + hueS + '&saturation=' + saturation + '&bright=' + bright;"; response += " window.location.href = url;}"; response += "window.onload = function() {"; //pour pré-remplir les cases response += " document.getElementById('IP').value = '" + WiFi.localIP().toString() + "';"; response += " document.getElementById('hueH').value = '" + String(hueH) + "';"; response += " document.getElementById('hueM').value = '" + String(hueM) + "';"; response += " document.getElementById('hueS').value = '" + String(hueS) + "';"; response += " document.getElementById('saturation').value = '" + String(saturation) + "';"; response += " document.getElementById('bright').value = '" + String(bright) + "';}"; response += "</script>"; response += "<h2>Quelques informations :</h2>"; response += "<p>Heure actuelle : " + timeClient.getFormattedTime() + "</p>"; response += "<p>Nom de la carte : Wemos D1 mini ESP-60A572</p>"; response += "<p>SSID connect&eacute; : " + WiFi.SSID() + "</p>"; response += "<p>Adresse IP : " + WiFi.localIP().toString() + "</p>"; response += "<p>Version du SDK : " + String(ESP.getSdkVersion()) + "</p>"; response += "<h2>Palette des couleurs Fastled</h2>"; response += "<img src=https://i.goopics.net/paklx5.jpg class='center'>"; //image response += "</body></html>"; server.send(200, "text/html", response); } void updateHeure() { timeClient.update(); rtc.adjust(DateTime(2024, 2, 8, timeClient.getHours(), timeClient.getMinutes(), timeClient.getSeconds())); }