/* * Created by Laurent CLaude * https://www.laurentclaude.fr/ * * My code is under license GPL v3 * * Horloge Nixie basée sur ESP + module RTC-DS1307, avec fonctionnalités wifi pour synchro NTP */ #include "hardware.h" #include "secrets.h" #include // https://github.com/tzapu/WiFiManager #include #include // Date and time functions using a DS1307 RTC connected via I2C and Wire lib. https://github.com/adafruit/RTClib #include // The NTP library allows you to receive time information from the Internet. https://github.com/sstaub/NTP #include "nixie.h" // Mes routines de pilotage d'affichage Nixie #include // Number of leds in your strip #define NUM_LEDS 4 #define LEDS_PIN 43 // Define the array of leds CRGB leds[NUM_LEDS]; RTC_DS1307 rtc; char daysOfTheWeek[7][12] = { "Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi" }; bool wifiOK, ntpOK, rtcOK; unsigned long LastRTCUpdate; // le temps de dernière MAJ de l'horloge interne RTC unsigned long LastNixieUpdate; // le temps de dernière MAJ affichage Nixie unsigned long LastDotUpdate; // le temps de dernière MAJ de l'affichage du point des secondes int heu_d, heu_u, min_d, min_u, sec_d, sec_u; int brightnessInput, brightnessLeds ; //for RGB led brightness const long intervalRTCUpdate = 3600000; // 86400000 = 24 heures / 3600000 = 1 heure const long intervalNixieUpdate = 1000; // 1000 = 1 seconde WiFiUDP wifiUdp; NTP ntp(wifiUdp); ///////////////////////////////////////////////////// //////////// FONCTIONS //////////////// ///////////////////////////////////////////////////// // bool initWIFI() { //WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP WiFiManager wm; bool reso; wm.setConfigPortalTimeout(60); wm.setHostname("HorlogeNixie"); //reset settings if switch pressed on startup if (!digitalRead(Rotary_SW)) { Serial.println("RAZ wifi"); wm.resetSettings(); } reso = wm.autoConnect("NixieClockAP"); // Création d'un AP ou connexion mémorisée //reso = wm.autoConnect(SECRET_WIFI_SSID, SECRET_WIFI_PASS); if (reso) { //if you get here you have connected to the WiFi Serial.println("Connected...yeey :)"); } else { Serial.println("Failed to connect"); } return (reso); } bool initRTC() { //// Initialisation RTC Serial.print("Initialisation de l'horloge interne RTC"); rtcOK = rtc.begin(); if (!rtcOK) { Wire.begin(I2C_SDA, I2C_SCL); // Broches (SDA,SCL) de l'I2C pour la RTC delay(1000); if (!rtc.begin()) { Serial.println(" --> RTC introuvable !"); return (false); } else { Serial.println(" : OK"); return (true); } } else { Serial.println(" : déjà démarrée !"); return (true); } } void printRTC() { //// Affichage du temps RTC en console série pour débug DateTime now = rtc.now(); Serial.print("Heure de l'horloge interne (RTC) : "); Serial.print(daysOfTheWeek[now.dayOfTheWeek()]); Serial.print(" "); Serial.print(now.day(), DEC); Serial.print('/'); Serial.print(now.month(), DEC); Serial.print('/'); Serial.print(now.year(), DEC); Serial.print(" "); Serial.print(now.hour(), DEC); Serial.print(':'); Serial.print(now.minute(), DEC); Serial.print(':'); Serial.println(now.second(), DEC); } void initNTP() { // Paramétrage NTP avec prise en compte de l'heure d'été pour la France Serial.print("Initialisation NTP"); ntp.ruleDST("CEST", Last, Sun, Mar, 2, 120); // last sunday in march 2:00, timetone +120min (+1 GMT + 1h summertime offset) ntp.ruleSTD("CET", Last, Sun, Oct, 3, 60); // last sunday in october 3:00, timezone +60min (+1 GMT) ntp.begin(); Serial.println(" : OK"); //ntp.updateInterval(1000); // update every second Serial.print("Le temps Internet (NTP) indique : "); ntp.update(); Serial.println(ntp.formattedTime("%A %d/%m/%Y %T")); // www dd/mm/yyyy hh:mm:ss } void syncNTPtoRTC() { //// Récupération du temps Internet par NTP Serial.println("Synchro temps NTP vers RTC :"); Serial.print("- récupération du temps Internet : "); ntp.update(); // récupération du temps NTP Serial.println(ntp.formattedTime("%A %d/%m/%Y %T")); // www dd/mm/yyyy hh:mm:ss //// Mise à jour du temps RTC de l'horloge locale Serial.print("- enregistrement du temps Internet dans l'horlore RTC"); rtc.adjust(DateTime(ntp.year(), ntp.month(), ntp.day(), ntp.hours(), ntp.minutes(), ntp.seconds())); Serial.println(" : OK."); LastRTCUpdate = millis(); } ///////////////////////////////////////////////////// /////////////////// setup //////////////////// ///////////////////////////////////////////////////// // void setup() { //// Initialisation hardware pinMode(Rotary_SW, INPUT_PULLUP); // Encodeur rotatif : switch pinMode(Rotary_A, INPUT_PULLUP); // Encodeur rotatif : voie A pinMode(Rotary_B, INPUT_PULLUP); // Encodeur rotatif : voie B pinMode(BCD_D, OUTPUT); // D Pour digits afficheurs Nixie pinMode(BCD_C, OUTPUT); // C pinMode(BCD_B, OUTPUT); // B pinMode(BCD_A, OUTPUT); // A pinMode(NX1A, OUTPUT); // Nixie 1 pinMode(NX2A, OUTPUT); // Nixie 2 pinMode(NX3A, OUTPUT); // Nixie 3 pinMode(NX4A, OUTPUT); // Nixie 4 // Démarrage de l'I2C : Wire.begin(I2C_SDA, I2C_SCL); // Broches (SDA,SCL) de l'I2C pour la RTC //// Initialisation de la liaison série Serial.begin(115200); Serial.println(""); Serial.println("Liaison série OK"); //// Initialisation des LEDs RGB FastLED.addLeds(leds, NUM_LEDS); // GRB ordering is typical FastLED.setBrightness(16); leds[0] = CRGB::Black; FastLED.show(); wifiOK = initWIFI(); // initialisation du wifi initNTP(); // récupération du temps Internet rtcOK = initRTC(); // initialisation de l'horloge interne if (wifiOK && rtcOK) { printRTC(); // Affichage du temps RTC en console série syncNTPtoRTC(); // Mise à l'heure de l'horloge RTC locale avec l'heure Internet printRTC(); // Affichage du temps RTC en console série } Serial.print("Pour info, le temps de compil : "); Serial.print(__DATE__); Serial.print(" - "); Serial.println(__TIME__); Serial.println("Fin des initialisations."); printRTC(); // Affichage du temps RTC en console série Serial.println("------------------------"); } ///////////////////////////////////////////////////// ///////////////// loop ////////////////// ///////////////////////////////////////////////////// // void loop() { unsigned long currentMillis = millis(); // Mise à jour de l'affichage Nixie if ((currentMillis - LastNixieUpdate >= intervalNixieUpdate) || (currentMillis < LastNixieUpdate)) { LastNixieUpdate = currentMillis; DateTime now = rtc.now(); heu_d = (now.hour()) / 10; heu_u = (now.hour()) % 10; min_d = (now.minute()) / 10; min_u = (now.minute()) % 10; sec_d = (now.second()) / 10; sec_u = (now.second()) % 10; printRTC(); brightnessInput = analogRead(IN_PHOTO_R); // read the input pin FastLED.setBrightness(brightnessInput/16); int aupif = random(0, 4); int randomR = random(255); int randomG = random(255); int randomB = random(255); leds[aupif] = CRGB(randomR, randomG, randomB); FastLED.show(); } // allumage du point une seconde puis éteint une seconde // utilisation du digit "9" du Nixie 3 (dizaines de minutes) if ((currentMillis - LastDotUpdate < 1000) || (currentMillis < LastDotUpdate)) { printNixie3(9); delay(5); digitalWrite(NX3A, 0); //Switch OFF Anode Nixie 1 } else { if ((currentMillis - LastDotUpdate < 2000) || (currentMillis < LastDotUpdate)) { delay(5); } else { LastDotUpdate = currentMillis; } } printNixie1(heu_d); delay(5); digitalWrite(NX1A, 0); //Switch OFF Anode Nixie 1 printNixie2(heu_u); delay(5); digitalWrite(NX2A, 0); //Switch OFF Anode Nixie 1 printNixie3(min_d); delay(5); digitalWrite(NX3A, 0); //Switch OFF Anode Nixie 1 printNixie4(min_u); delay(5); digitalWrite(NX4A, 0); //Switch OFF Anode Nixie 1 // Mise à jour de l'horloge interne RTC. Une fois par 24H if ((currentMillis - LastRTCUpdate >= intervalRTCUpdate) || (currentMillis < LastRTCUpdate)) { LastRTCUpdate = currentMillis; syncNTPtoRTC(); // Mise à l'heure de l'horloge RTC locale avec l'heure Internet printRTC(); // Affichage du temps RTC en console série } }