From deb5f3e50024c00d718dec2f552880d32da8c84d Mon Sep 17 00:00:00 2001 From: Claude Code Date: Mon, 19 Oct 2026 19:07:09 +0200 Subject: [PATCH] Auswahl von Board (D1 mini/NodeMCU) und RTC (DS3231/DS1307/keine) vor dem Kompilieren Co-Authored-By: Claude Sonnet 5.5 --- README.md | 4 +++ software/arduino/arduino.ino | 57 ++++++++++++++++++++++++++++++++++++ software/pio/platformio.ini | 36 +++++++++++++++++++++-- software/pio/src/main.cpp | 57 ++++++++++++++++++++++++++++++++++++ 4 files changed, 152 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 463d5d4..474f8e2 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,9 @@ Am Anfang den ESP anlöten: ## Flashen + +**Board und RTC wählen:** PlatformIO: Umgebung `_` mit Board `d1_mini` oder `nodemcu` und RTC `ds3231`, `ds1307` oder `keine` (z. B. `pio run -e nodemcu_ds3231 -t upload`). Arduino IDE: Board unter Werkzeuge wählen und oben in `arduino.ino` `RTC_MODUL_DS3231`, `RTC_MODUL_DS1307` oder `RTC_MODUL_KEINE` definieren (Standard: DS3231). Die RTC hängt an D2 (SDA) / D1 (SCL); der DS1307 braucht 5 V. + 1. Dieses Repo clonen (`git clone https://github.com/c3e/wordclock.git`) 2. Die Arduino IDE installieren (https://www.arduino.cc/en/Main/Software) 3. Die Datei `wordclock/wordclock.ino` in der Arduino IDE öffnen @@ -45,6 +48,7 @@ Am Anfang den ESP anlöten: 8. Folgende installieren: * FastLED * WiFiManager + * RTClib (Adafruit) 9. Folgende Zip-Dateien herunterladen: * https://github.com/PaulStoffregen/Time/archive/master.zip * https://github.com/JChristensen/Timezone/archive/master.zip diff --git a/software/arduino/arduino.ino b/software/arduino/arduino.ino index 66e626e..8e5f6a9 100644 --- a/software/arduino/arduino.ino +++ b/software/arduino/arduino.ino @@ -5,6 +5,31 @@ #include #include #include +#include +#include + +// ================= RTC ================= +// RTC-Modul waehlen (vor dem Kompilieren): RTC_MODUL_DS3231, RTC_MODUL_DS1307 oder RTC_MODUL_KEINE. +// PlatformIO: ueber die Umgebung (siehe platformio.ini). Arduino IDE: hier eintragen. +// Das Board (D1 mini / NodeMCU) waehlt man in der IDE bzw. ebenfalls ueber die Umgebung; +// die Pinnamen D1/D2/D4 sind bei beiden identisch. +#if !defined(RTC_MODUL_DS3231) && !defined(RTC_MODUL_DS1307) && !defined(RTC_MODUL_KEINE) +#define RTC_MODUL_DS3231 +#endif +#if defined(RTC_MODUL_DS3231) || defined(RTC_MODUL_DS1307) +#include +#define RTC_VORHANDEN +#endif +#if defined(RTC_MODUL_DS3231) +RTC_DS3231 rtc; +#elif defined(RTC_MODUL_DS1307) +RTC_DS1307 rtc; +#endif +#define RTC_SDA D2 +#define RTC_SCL D1 +bool rtcOk = false; +volatile bool ntpJustSynced = false; +void onTimeSet(){ ntpJustSynced = true; } // ================= LED ================= #define LED_PIN D4 @@ -105,6 +130,35 @@ void loadSettings(){ configTime(tzString.c_str(), ntpServer.c_str()); } +// Zeit aus der RTC uebernehmen (bis NTP erreichbar ist). Die RTC laeuft in UTC. +void initRtc(){ +#ifdef RTC_VORHANDEN + Wire.begin(RTC_SDA, RTC_SCL); + if(!rtc.begin()) return; + rtcOk = true; +#if defined(RTC_MODUL_DS3231) + bool valid = !rtc.lostPower(); +#else + bool valid = rtc.isrunning(); +#endif + DateTime n = rtc.now(); + if(valid && n.year() >= 2024){ + struct timeval tv = { (time_t)n.unixtime(), 0 }; + settimeofday(&tv, nullptr); + ntpJustSynced = false; // der eigene Aufruf ist keine NTP-Zeit + } +#endif +} + +// Nach jeder NTP-Synchronisation die RTC nachstellen. +void updateRtcFromNtp(){ +#ifdef RTC_VORHANDEN + if(!ntpJustSynced) return; + ntpJustSynced = false; + if(rtcOk && timeSynced()) rtc.adjust(DateTime((uint32_t)time(nullptr))); +#endif +} + // ================= HELFER ================= bool isNightTime(struct tm *t){ if(!autoNight) return false; @@ -431,7 +485,9 @@ void setup(){ pixels.clear(); pixels.show(); + settimeofday_cb(onTimeSet); loadSettings(); + initRtc(); WiFiManager wm; wm.autoConnect("Wortuhr"); @@ -455,6 +511,7 @@ void setup(){ void loop(){ server.handleClient(); + updateRtcFromNtp(); // Erst anzeigen, wenn die Zeit per NTP synchronisiert ist if(!timeSynced()) return; diff --git a/software/pio/platformio.ini b/software/pio/platformio.ini index 6cf958a..1b4b808 100644 --- a/software/pio/platformio.ini +++ b/software/pio/platformio.ini @@ -1,8 +1,40 @@ -[env:d1_mini] +; Umgebung = Board + RTC-Modul waehlen, z.B.: pio run -e nodemcu_ds3231 -t upload +; Board: d1_mini | nodemcu RTC: ds3231 | ds1307 | keine +[common] platform = espressif8266 -board = d1_mini framework = arduino monitor_speed = 115200 lib_deps = adafruit/Adafruit NeoPixel tzapu/WiFiManager + adafruit/RTClib + +[board_d1_mini] +board = d1_mini + +[board_nodemcu] +board = nodemcuv2 + +[env:d1_mini_ds3231] +extends = common, board_d1_mini +build_flags = -DRTC_MODUL_DS3231 + +[env:d1_mini_ds1307] +extends = common, board_d1_mini +build_flags = -DRTC_MODUL_DS1307 + +[env:d1_mini_keine] +extends = common, board_d1_mini +build_flags = -DRTC_MODUL_KEINE + +[env:nodemcu_ds3231] +extends = common, board_nodemcu +build_flags = -DRTC_MODUL_DS3231 + +[env:nodemcu_ds1307] +extends = common, board_nodemcu +build_flags = -DRTC_MODUL_DS1307 + +[env:nodemcu_keine] +extends = common, board_nodemcu +build_flags = -DRTC_MODUL_KEINE diff --git a/software/pio/src/main.cpp b/software/pio/src/main.cpp index 66e626e..8e5f6a9 100644 --- a/software/pio/src/main.cpp +++ b/software/pio/src/main.cpp @@ -5,6 +5,31 @@ #include #include #include +#include +#include + +// ================= RTC ================= +// RTC-Modul waehlen (vor dem Kompilieren): RTC_MODUL_DS3231, RTC_MODUL_DS1307 oder RTC_MODUL_KEINE. +// PlatformIO: ueber die Umgebung (siehe platformio.ini). Arduino IDE: hier eintragen. +// Das Board (D1 mini / NodeMCU) waehlt man in der IDE bzw. ebenfalls ueber die Umgebung; +// die Pinnamen D1/D2/D4 sind bei beiden identisch. +#if !defined(RTC_MODUL_DS3231) && !defined(RTC_MODUL_DS1307) && !defined(RTC_MODUL_KEINE) +#define RTC_MODUL_DS3231 +#endif +#if defined(RTC_MODUL_DS3231) || defined(RTC_MODUL_DS1307) +#include +#define RTC_VORHANDEN +#endif +#if defined(RTC_MODUL_DS3231) +RTC_DS3231 rtc; +#elif defined(RTC_MODUL_DS1307) +RTC_DS1307 rtc; +#endif +#define RTC_SDA D2 +#define RTC_SCL D1 +bool rtcOk = false; +volatile bool ntpJustSynced = false; +void onTimeSet(){ ntpJustSynced = true; } // ================= LED ================= #define LED_PIN D4 @@ -105,6 +130,35 @@ void loadSettings(){ configTime(tzString.c_str(), ntpServer.c_str()); } +// Zeit aus der RTC uebernehmen (bis NTP erreichbar ist). Die RTC laeuft in UTC. +void initRtc(){ +#ifdef RTC_VORHANDEN + Wire.begin(RTC_SDA, RTC_SCL); + if(!rtc.begin()) return; + rtcOk = true; +#if defined(RTC_MODUL_DS3231) + bool valid = !rtc.lostPower(); +#else + bool valid = rtc.isrunning(); +#endif + DateTime n = rtc.now(); + if(valid && n.year() >= 2024){ + struct timeval tv = { (time_t)n.unixtime(), 0 }; + settimeofday(&tv, nullptr); + ntpJustSynced = false; // der eigene Aufruf ist keine NTP-Zeit + } +#endif +} + +// Nach jeder NTP-Synchronisation die RTC nachstellen. +void updateRtcFromNtp(){ +#ifdef RTC_VORHANDEN + if(!ntpJustSynced) return; + ntpJustSynced = false; + if(rtcOk && timeSynced()) rtc.adjust(DateTime((uint32_t)time(nullptr))); +#endif +} + // ================= HELFER ================= bool isNightTime(struct tm *t){ if(!autoNight) return false; @@ -431,7 +485,9 @@ void setup(){ pixels.clear(); pixels.show(); + settimeofday_cb(onTimeSet); loadSettings(); + initRtc(); WiFiManager wm; wm.autoConnect("Wortuhr"); @@ -455,6 +511,7 @@ void setup(){ void loop(){ server.handleClient(); + updateRtcFromNtp(); // Erst anzeigen, wenn die Zeit per NTP synchronisiert ist if(!timeSynced()) return;