Network Time Protokoll (NTP) – Die Atomuhr des Internets
NTP ist die Abkürzung von Network Time Protokoll. Der Client, in unserem Fall die Uhr bzw. der auf der Platine verbaute ESP8266, holt sich die aktuelle Zeit von einem Zeitserver aus dem Internet. Bei guter Anbindung ist damit eine Ganggenauigkeit von 10 Millisekunden möglich.
Der oben erwähnte Mikrocontroller (ESP8266) ist also das Herzstück der Uhr. Dazu noch ein Display für die Stunden- bzw. Minutenanzeige und ein LED-Pixelring für die Anzeige der Sekunden. In der Vergangenheit hätte die Herstellung des LED-Ringes einen großen Aufwand an Bohr- und Lötarbeiten bedeutet. Aber Dank NEOPIXEL reichen bereits 3 Drähte, um die 60 LEDs anzusteuern.
Die Einkaufsliste ist kurz
• 1 WEMOS D1 mini => 1,50€
• 1 MAX7219 Dot Matrix Modul (4-stellig) => Rot 2,30€ oder Grün 3,30€
• 1 WS2812B 60er LED-Pixelring => 9,60€ (aufpassen, es gibt sie preiswerter, aber dann kommen 4 Teile, die man zum Ring löten muss)
• 1 Fotowiderstand LDR 5516 => (aus der Bastelkiste oder 50 Teile mit 5 verschiedenen Typen für 1,21€)
• 1 Widerstand 10K => je nach LDR-Typ andere Werte möglich (aus der Bastelkiste oder kleines Sortiment kaufen)
Also mit 15-20€ muss man rechnen. Die Preise können sich aber ändern.
Maße in mm
LED-Ring: ⌀ Innen 156, ⌀ Außen 172, Höhe Platine 1,7 + LED 1,7 = 3,4 dazu 4 Bohrungen ⌀ 2 im Abstand von 15 LEDs
Dotmatrix: 132 x 32, 14,5 hoch, Bohrung ⌀ 3,5
WEMOS: 34,5 x 25,6, 5,3 hoch, Bohrung ⌀ 2,5
Wenn man von den 14,5 mm Höhe der Dotmatrix die rund 3,5 mm des LED-Rings abzieht, kommt man auf 11 mm Abstandshalter zu befestigen des LED-Rings. Für den WEMOS reichen 3 mm (Auf der Unterseite ist noch ein Chip) oder besser 6 mm, da ist mehr Platz für die Verdrahtung auf der Unterseite.
© 3/2021
Die NTP-Uhr wird zur Wetterstation
Ich konnte es mir nicht verkneifen und habe noch einen BME280 hinzugefügt. Damit wird die Uhr zur Wetterstation, denn es stehen Temperatur, Luftfeuchte und Luftdruck zur Verfügung.
Um den Luftdruck auf Meereshöhe (DruckNN=NormalNull) zu erhalten, addiert man einfach 1 hPa je 8m Höhe dazu oder verwendet die etwas genauere Formel:
DruckNN = ((Druck) / pow((1 - ((float)(alititude in m)) / 44330), 5.255));
Mit einer zusätzlichen Variable im Programmcode merkt man sich jede halbe Stunde den Luftdruck und vergleicht ihn mit dem aktuellen Luftdruck.
if(min % 30 == 0) merkeDruck = (merkeDruck + aktuellerDruck) / 2;
Somit kann man zusätzliche Infos wie steigend↑, fallend↓ und gleichbleibend→ ausgeben.
© 4/2021
Der erste Prototyp
Zum BME280 (ca. 4,50€) kam noch ein SGP30 (Luftgütesensor ca. 5,50€).
Beide Sensoren werden über den I2C-Bus ausgelesen. Damit sind die Sensoren im Grunde genommen parallel geschalten.
Man kann dem SGP30 die Werte vom BME280 (Temperatur, Luftfeuchte) zuführen.
Damit erzielt man eine höhere Genauigkeit bei der Berechnung der Luftgüte.
Der SGP30 färbt mittels seiner Werte den Sekundenzeiger entsprechend der Luftgüte von grün über gelb zu rot.
Sensoren
BME280-Sensor
SGP30-Sensor
Leider werden die Farben des Sekundenzeigers im Video nicht so optimal dargestellt, wie sie in Wirklichkeit sind.
Ich habe aller 15s eine rote LED, aller 5 s eine blaue LED. Alle anderen sind grün.
Da man dies per Software einstellen kann, kann man beliebige Farben verwenden.
Hauptplatine
Der direkt auf der WEMOS-Platine verlötete Fotowiderstand regelt die Helligkeit der Dot-Matrix und des LED-Pixelringes.
Pixelring
Auch die Art und Weise des Sekundenzeigers kann man per Software ändern. So füllt sich beispielsweise von 22 Uhr bis 6 Uhr der Sekundenkreis nicht mehr, sondern es leuchtet immer nur die aktuelle Sekunde. Damit verringert sich die Helligkeit in den Nachtstunden zusätzlich.


Software
In der Soft- bzw. Firmware habe ich ein Webinterface integriert, welches man über die IP-Adresse der Uhr erreichen kann.
Dort sind detaillierte Infos und Sensorwerte enthalten.
Weiteres folgt wahrscheinlich nicht mehr, da dazu weitere Hardwareänderungen notwendig wären.
Da man Softwareänderungen über die OTA-Schnittstelle (Over The Air) übertragen kann, wird es in Zukunft sicher noch ein bisschen Codeoptimierung geben.
Am Ende mein Dank an alle Entwickler, die auf GitHub all die Bibliotheken zur Verfügung stellen und damit vielen bei der Entwicklung eigener Ideen unterstützen.
© 5/2021
Update Preise:
Seit 1. Juli 2021 wird in Fernost die deutsche Einfuhrumsatzsteuer während des Bestellprozesses angezeigt und mit berechnet. Auf die obigen Preise sind also jeweils 19% aufzuschlagen. Des Weiteren werden immer öfter Versandkosten berechnet bzw. im Artikelpreis versteckt. Was am Ende nicht relevant ist, da auch Versandkosten steuerpflichtig sind.
© 7/2021
Serienfertigung für den
Die erste Kleinserie ist fertig und wird vom Weihnachtsmann ausgeliefert 🙂
Jede Uhr hat einen anderen Geburtstags/Terminkalender so das die Berechnungszeit der nächsten Termine unterschiedlich lang dauert. Deshalb der etwas asynchrone Bootvorgang.
Falls die Beschenkten die Bedienungsanleitung mal nicht zur Hand haben sollten, könnt ihr auch hier nachlesen.
Preisupdate:
Mittlerweile sind die Chip- und Versandkosten stark gestiegen. Die Beschaffungskosten des Luftgütesensors (SGP30) haben sich fast verdoppelt. Er kostet jetzt fast 10€. Auch der Preis für den Temperatursensor (BME280) ist stark gestiegen. Beide Sensor-Chips werden von Bosch hergestellt. Andere Bauteile, wie der LED-Pixelring, sind nur moderat gestiegen.
Unnützes Wissen:
Im Mai 2021 bekam die ESP8266-Entwicklungsumgebung ein lang ersehntes Update. Es wurde die Zeit- bzw. Datumsberechnung von 32 auf 64-Bit umgestellt. Vor dieser Umstellung, wäre die Uhr am 19.01.2038 stehen geblieben bzw. hätte sinnlose Zeiten angezeigt. Die 2.147.483.647 (231-1) Sekunden seit dem 01.01.1970 wären vorbei und es käme zum 32-Bit-Ganzzahl-Zählerüberlauf.
Aber dies war nicht die einzige Gefahr. Am 7. Februar 2036 um 06:28:16 Uhr UTC wäre der Zähler des Zeitsynchronisations-Protokolls NTP (Network Time Protocol) übergelaufen. Jedoch wurde mit Einführung des NTP-Protokolls Version 4 das Problem behoben (im Jahr 2010).
Aber keine Angst, mit der 64-Bit-Umstellung ist man jetzt auf der ganz sicheren Seite. Damit sind Berechnungen bis zu 292 Milliarden Jahren möglich (Das Universum ist zurzeit ca. 15 Milliarden Jahre alt). Selbstverständlich erinnert euch die Uhr an diese IT-technisch wichtigen Ereignisse.
© 12/2021
Source code snippet:
Es gibt nur zwei bewegliche Tage/Feiertage, die man mit etwas höheren Aufwand berechnen muss.
#define secDay 86400 // 1 Tag = 86.400,003 Atomsekunden, auf Grund // ständiger Schwankungen der Erdrotation // alle 2-5 Jahre eine Schaltsekunde // Ostersonntag int getOstern(int jahr) { int k, m, s, a, d, r, og, sz, oe, os, tag; k = jahr / 100; m = 15 + (3 * k + 3) / 4 - (8 * k + 13) / 25; s = 2 - (3 * k + 3) / 4; a = jahr % 19; d = (19 * a + m) % 30; r = d / 29 + (d / 28 - d / 29) * a / 11; og = 21 + d - r; sz = 7 - ((jahr + jahr / 4 + s) % 7); oe = 7 - ((og - sz) % 7); os = og + oe; if (os <= 31) { tag = time2sek(jahr, 3, os, 0, 0, 0, 0); } else { tag = time2sek(jahr, 4, os - 31, 0, 0, 0, 0); } if (debug) { Serial.print(F("getOstern: ")); Serial.println(DateFormatter::format("%A %d.%m.%Y", tag)); } return tag; } // Erster Advent int getErsterAdvent(int jahr) { int heiligabend = time2sek(jahr, 12, 24); int wt = DateFormatter::format("%w", heiligabend).toInt(); int tage = wt + 21; int tag = heiligabend - (tage * secDay); if (debug) { Serial.print(F("getErsterAdvent: ")); Serial.println(DateFormatter::format("%A %d.%m.%Y", tag)); } return tag; } // Umrechnung Zeit in Sekunden uint64_t time2sek(int i_year, byte b_month, byte b_day, byte b_hour = 0, byte b_min = 0, byte b_sec = 0, byte b_dst = 0) { struct tm zeit; zeit.tm_year = i_year - 1900; zeit.tm_mon = b_month - 1; zeit.tm_mday = b_day; zeit.tm_hour = b_hour; zeit.tm_min = b_min; zeit.tm_sec = b_sec; zeit.tm_isdst = b_dst; return mktime(&zeit); }
Weitere bewegliche Feiertage orientieren sich alle an Ostersonntag oder dem 1. Advent.
Fastnacht = Ostersonntag – 47
Himmelfahrt = Ostersonntag + 39
Pfingstsonntag = Ostersonntag + 49
Buß- und Bettag = 1. Advent – 11
Schaltjahrberechnung:
Der Perfektion geschuldet, hier die Berechnung der Schaltjahre, obwohl für dieses Jahrhundert eigentlich nur noch die Regel gilt, alle Jahre die durch vier teilbar sind, sind Schaltjahre.
bool isSchaltjahr(int jahr) { // Alle Jahre, die durch 4 teilbar sind, sind ein Schaltjahr. // Es sei denn, das Jahr ist durch 100 teilbar, dann ist es kein Schaltjahr. // Aber, wenn das Jahr durch 400 teilbar ist, dann ist es doch wieder ein Schaltjahr. if ((jahr % 400) == 0) { return true; } else if ((jahr % 100) == 0) { return false; } else if ((jahr % 4) == 0) { return true; } else { return false; } //return (jahr % 4 == 0 && jahr % 100 != 0 || jahr % 400 == 0); // Kurzform }
© 3/2024
Die nächste Kleinserie
Wegen ein paar runder Geburtstage, habe ich die nächsten drei hardwaregleichen Uhren zusammengelötet.
Preisupdate:
Die Preise sind gegenüber 2021 wieder gefallen.
• 1 Wemos D1 MINI V3.0 => 2,50€
• 1 WS2812B 60er LED-Pixelring => 9,50€
• 1 MAX7219 Dot Matrix (4-stellig, grün) => 4,50€
• 1 SGP30 => 7€
• 1 BME280 => 3€
Bedienungsanleitung überarbeitet.
Die Uhr verbraucht ca. 1,8 Watt. Daraus ergibt sich ein Jahresverbrauch von ca. 16 kWh.
16 kWh x 0,31 €/kWh = 4,96 € Jahreskosten Stromverbrauch.
© 3/2025