Skip to content

Latest commit

 

History

6 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

WILHELM 1 – digitale Uhr

Eine digitale Uhr auf Basis des Wemos D1 Mini (ESP8266) mit 7-Segment-Display, RTC-Modul, WLAN-Zeitsynchronisation, OTA-Updates und einem einfachen Menüsystem mit Laufschrift.

Claude AI von Anthropic half mir dabei, meine Ansprüche und Ideen umzusetzen.

Aktuelle Version: 1.1.0

Die fertig aufgebaute Uhr WILHELM 1


Hardware

Komponente Beschreibung
Wemos D1 Mini Mikrocontroller (ESP8266, 4 MB Flash)
TM1637 4-stelliges 7-Segment-Display mit Doppelpunkt
DS3231 RTC-Modul mit Temperaturmessung und Pufferbatterie
2× Taster Navigation (Menü / Enter)

Pinbelegung

Signal GPIO Wemos Pin
TM1637 CLK 14 D5
TM1637 DIO 0 D3
DS3231 SDA 4 D2 (I²C)
DS3231 SCL 5 D1 (I²C)
Button Menü 12 D6
Button Enter 13 D7

Schaltplan: Verdrahtung von Wemos D1 Mini, TM1637, DS3231 und Tastern

Hinweis zu GPIO0 (D3): Das ist ein Strapping-Pin – er muss beim Booten HIGH sein, sonst startet der ESP8266 in den Flash-Modus. Mit dem TM1637 funktioniert es in der Praxis, weil DIO im Ruhezustand hoch bleibt. Wer umverdrahtet, sollte das im Hinterkopf behalten.

Hinweis zur RTC-Batterie: Viele ZS-042-Module haben eine Ladeschaltung für LIR2032-Akkus. Steckt eine normale CR2032 drin, wird sie dauerhaft geladen. Entweder eine wiederaufladbare LIR2032 verwenden oder die Ladeschaltung (Diode / 200 Ω) auslöten.


Features

  • Uhrzeitanzeige mit sekündlich blinkendem Doppelpunkt – der Sekundenwechsel wird per Polling des DS3231 erkannt, kein Hardware-Interrupt nötig
  • Startbildschirm: Der Gerätename läuft beim Booten als Laufschrift über das Display
  • NTP-Zeitsynchronisation via WLAN bei jedem Start, inklusive korrekter Zeitzone und Sommerzeit (CET-1CEST,M3.5.0,M10.5.0/3) – danach wird das WLAN wieder abgeschaltet
  • WLAN-Konfiguration über WiFiManager-Captive-Portal (kein hardcodiertes Passwort nötig)
  • Fallback ohne WLAN: Läuft das Portal in den Timeout, arbeitet die Uhr einfach mit der gepufferten RTC-Zeit weiter
  • OTA-Update über GitHub Releases mit Versionsvergleich, Bestätigungs-Countdown und Fortschrittsanzeige in Prozent
  • Temperaturanzeige über den integrierten Sensor des DS3231
  • Helligkeitseinstellung (0–7) mit persistenter Speicherung via Preferences (NVS)
  • Menüsystem mit Laufschrift für lange Einträge und automatischem Rücksprung zur Uhr nach Inaktivität
  • Long-Press auf den Enter-Button springt jederzeit zur Uhr zurück

Menüstruktur

Uhr (Standardanzeige)
│
└── [Enter kurz] → Hauptmenü
        │
        ├── HELLIGKEIT             → Helligkeit 0–7 (Menü-Button zum Verstellen)
        ├── TEMPERATUR             → Temperaturanzeige des DS3231
        ├── RESET INTERNET CONFIG  → WLAN-Daten löschen & Neustart
        │
        └── [Enter lang] → zurück zur Uhr

Menüeinträge mit mehr als vier Zeichen laufen automatisch als Laufschrift über das Display. Der Inaktivitäts-Timeout pausiert, solange gescrollt wird – ein Eintrag wird also immer vollständig angezeigt, bevor die Uhr zurückkehrt.


Bibliotheken

Folgende Arduino-Bibliotheken werden in der jeweiligen Version benötigt: (❗wichtig und unbedingt beachten❗)

Bibliothek Version Link
TM1637Display 1.2.0 avishorp/TM1637
⚠️ DS3231-RTC 1.1.0 hasenradball/DS3231-RTC
WiFiManager 2.0.17 tzapu/WiFiManager
Preferences 2.2.2 vshymanskyy/Preferences

Projektstruktur

digital-clock/
├── digital-clock.ino        – Einstiegspunkt (setup & loop)
├── config.h                 – Zentrale Konfiguration: Pins, Timings, Texte, URLs
├── globals.h / .cpp         – Globale Objekte & Menüdefinition
├── displayHelper.h          – Segment-Encoding, showTime(), showLabel()
└── src/
    ├── lib/                 – Wiederverwendbare, hardwarenahe Klassen
    │   ├── Button.h         – Interrupt-basierte Button-Klasse (inkl. Long-Press)
    │   ├── Menu.h           – Generische Menü-Klasse (Zustandsautomat)
    │   ├── Marquee.h        – Laufschrift für 4-stellige Displays
    │   └── RTC.h            – DS3231-Wrapper mit Sekundenerkennung per Polling
    ├── hal/                 – Hardware Abstraction Layer
    │   ├── display.h / .cpp – Display-Ausgabe, Menü-Callbacks, Textmeldungen
    │   └── input.h / .cpp   – Button-Callbacks & Menüsteuerung
    └── services/            – Anwendungslogik
        ├── boot.h / .cpp    – Start-Sequenz (Begrüßung)
        ├── clock.h / .cpp   – RTC-Tick & Uhrzeitanzeige
        ├── settings.h / .cpp– Persistente Einstellungen (Preferences/NVS)
        ├── wifi.h / .cpp    – WLAN, WiFiManager, NTP-Sync
        └── ota.h / .cpp     – Versionsprüfung & Firmware-Update

Hinweis: Ich habe mich ganz bewusst für diese Struktur entschieden, da damit das Projekt vollständig in der Arduino IDE 2.x.x geöffnet werden kann.

Startreihenfolge

Die Reihenfolge in setup() ist nicht beliebig:

  1. settingsSetup() – Preferences öffnen
  2. clockSetup() – RTC und Wire.begin(), muss vor allen I²C-Zugriffen laufen
  3. displaySetup() – Display mit gespeicherter Helligkeit
  4. bootSplash() – Begrüßung, Display gehört hier exklusiv der Laufschrift
  5. inputSetup() – Buttons registrieren
  6. wifiSetup() – WLAN, NTP-Sync und OTA-Check bei bestehender Verbindung
  7. otaSetup() – Version im Serial-Log ausgeben

Erstinbetriebnahme

  1. Bibliotheken installieren (siehe oben)
  2. Sketch auf den Wemos D1 Mini flashen
  3. Beim ersten Start öffnet der Controller einen WLAN-Access-Point namens WILHELM 1
  4. Mit dem Handy oder Laptop mit WILHELM 1 verbinden
  5. Im Browser öffnet sich automatisch das Konfigurationsportal
  6. Heimnetzwerk auswählen und WLAN-Passwort eingeben
  7. Nach erfolgreicher Verbindung synchronisiert sich die Uhr automatisch via NTP
  8. WLAN wird danach wieder getrennt – die Uhr läuft offline weiter

Die WLAN-Zugangsdaten bleiben dauerhaft gespeichert. Bei jedem weiteren Start verbindet sich der Controller automatisch und synchronisiert die Zeit.

Wird innerhalb von 120 Sekunden nichts konfiguriert, schließt das Portal und die Uhr läuft mit der Zeit aus dem gepufferten DS3231 weiter.

WLAN zurücksetzen

Im Menü den Punkt RESET INTERNET CONFIG auswählen und mit Enter bestätigen. Der Controller löscht die gespeicherten WLAN-Daten und startet neu – das Konfigurationsportal öffnet sich automatisch.


OTA-Update

Beim Start prüft die Uhr – solange das WLAN noch verbunden ist – ob im GitHub-Repository ein neueres Release vorliegt. Verglichen wird FIRMWARE_VERSION aus config.h mit dem Inhalt von version.txt aus dem letzten Release.

Ist ein Update verfügbar, zeigt das Display eine Meldung und anschließend einen Countdown. Ein Druck auf Enter startet den Download, ohne Bestätigung läuft der Countdown ab und die Uhr startet normal. Nach dem Flashen rebootet der Controller selbstständig.

Ein Release veröffentlichen

  1. FIRMWARE_VERSION in config.h erhöhen
  2. Sketch → Kompilierte Binärdatei exportieren (Strg+Alt+S), die .bin nach firmware.bin umbenennen
  3. version.txt mit exakt derselben Versionsnummer anlegen (nur die Zahl, z. B. 1.1.0)
  4. Auf GitHub ein Release anlegen und beide Dateien als Assets hochladen

Ein als Pre-Release markiertes Release wird nicht gefunden – releases/latest/download/… überspringt Pre-Releases.

Lokal testen ohne GitHub

In config.h OTA_TEST_MODE auf 1 setzen und unter OTA_TEST_HOST die IP des eigenen Rechners eintragen. Dann einen Ordner mit version.txt und firmware.bin anlegen und darin einen Webserver starten:

python -c "open('version.txt','w').write('1.1.0')"
python -m http.server 8000 --bind 0.0.0.0

version.txt bewusst mit Python schreiben – PowerShell erzeugt mit echo > eine UTF-16-Datei mit BOM, die der Parser auf dem ESP nicht lesen kann.

Wichtig beim Testen: Die Versionsnummer in version.txt muss zu der Version passen, mit der firmware.bin kompiliert wurde. Sonst bietet die Uhr nach dem Update dasselbe Update erneut an.


Bekannte Einschränkungen

  • Sommerzeitwechsel: Die lokale Zeit wird in den DS3231 geschrieben und nur beim Start synchronisiert. Nach der Umstellung im März und Oktober geht die Uhr eine Stunde falsch, bis sie neu gestartet wird.
  • Lesbarkeit auf 7 Segmenten: Die Buchstaben K, M, W, X, V und Z lassen sich nicht sinnvoll darstellen. Displaytexte in config.h sollten ohne sie auskommen.
  • Laufschrift: Die Fensterposition ist als uint8_t gehalten, Texte über 252 Zeichen laufen über.

Lizenz

MIT License – feel free to use, modify and share.

About

WILHELM 1

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages