Analog clock with the Wemos D1 Mini

FunduinoLast updated on

Die Uhrzeit per NTP aus dem Internet holen

Eine Uhr braucht nicht zwingend ein Echtzeitmodul. Wenn der Mikrocontroller ins WLAN kommt, holt er sich die Zeit einfach aus dem Internet – über das NTP (Network Time Protocol).

Genau das macht dieses Projekt: Ein Wemos D1 Mini mit ESP8266-Chip verbindet sich mit deinem Router, fragt einen öffentlichen NTP-Server ab und zeigt Datum und Uhrzeit auf einem OLED-Display an. Sommer- und Winterzeit berücksichtigt das Programm automatisch.

Gebraucht werden nur zwei Bauteile: das Wemos D1 Mini und ein OLED mit I²C-Anschluss.

OLED-Display mit Datum und Uhrzeit
Datum und Uhrzeit auf dem OLED

Wemos D1 Mini und NTP

Das Wemos D1 Mini ist ein Mikrocontroller mit ESP8266-Chip und damit WLAN-fähig. Genau das braucht dieses Projekt: Die Uhrzeit kommt nicht aus einem Echtzeitmodul, sondern aus dem Internet.

Dafür sorgt das NTP (Network Time Protocol), ein Protokoll zur Synchronisierung von Uhren in Computersystemen. Im Internet stehen öffentliche NTP-Server bereit, die jeder abfragen kann.

Was angezeigt werden soll

Zeit und Datum erscheinen auf einem OLED-Display: oben das Datum, darunter eine Trennlinie und darunter die Uhrzeit in großer Schrift.

Benötigte Bauteile:

  • Wemos D1 Mini
  • OLED-Display 0,96 Zoll, 128x64, I²C

Der Artikel heißt „Analoge Uhr“, das Programm zeigt die Zeit aber in Ziffern an – also digital. Ein Zifferblatt mit Zeigern wird nicht gezeichnet.

OLED-Display mit Datum und Uhrzeit
Datum und Uhrzeit auf dem OLED

Das Board installieren

Trage unter Datei → Einstellungen eine zusätzliche Boardverwalter-URL ein:

https://arduino.esp8266.com/stable/package_esp8266com_index.json

Öffne danach den Boardverwalter über Werkzeuge → Board → Boardverwalter, suche nach esp8266 und installiere das Paket.

Wird das Wemos D1 Mini nicht automatisch erkannt, klicke auf „Wähle ein anderes Board und einen anderen Port“ und suche dort nach Wemos D1. Der USB-Port heißt je nach Betriebssystem anders.

Eingabefeld für zusätzliche Boardverwalter-URLs in den Einstellungen
Datei → Einstellungen → Boardverwalter-URL
ESP8266-Paket im Boardverwalter
Das Paket esp8266 installieren
Dialog zur Auswahl von Board und Port
Board und Port wählen
Auswahl des Wemos D1 Mini in der Boardliste
Wemos D1 Mini auswählen
1 / 4

Die Bibliotheken installieren

Zwei Bibliotheken werden gebraucht:

  • U8g2 – für die Ausgabe auf dem OLED
  • NTP – für die Zeitabfrage beim NTP-Server

Beide findest du in der Bibliotheksverwaltung. Eine ausführliche Referenz zur U8g2 liegt im GitHub-Wiki des Projekts.

Bibliothek U8g2 in der Bibliotheksverwaltung
Die Bibliothek U8g2
Bibliothek NTP in der Bibliotheksverwaltung
Die Bibliothek NTP
1 / 2

Der Schaltplan

Das OLED wird über I²C angeschlossen: VCC, GND, SCL und SDA – mehr braucht es nicht.

Verkabelung von Wemos D1 Mini und OLED über I2C
Der Schaltplan

Das Programm

Das Programm baut per DHCP eine Verbindung zum lokalen WLAN auf. Trage vorher SSID und Passwort deines Routers in den Sketch ein.

Hat die Verbindung geklappt, zeigt der Serielle Monitor den Namen des Routers und die zugewiesene IP-Adresse an. Danach erscheinen Datum und Uhrzeit auf dem Display und werden alle 30 Sekunden aktualisiert.

SSID und Passwort stehen im Klartext im Sketch. Teile den Sketch also nicht unverändert weiter.

SSID und IP-Adresse im Seriellen Monitor
Verbindung erfolgreich hergestellt
Datum und Uhrzeit per NTP auf dem OLED anzeigen
// Bibliotheken einbinden
# include <ESP8266WiFi.h>
# include <NTP.h>
# include <WiFiUdp.h>
# include <NTP.h>
# include <U8g2lib.h>

/*
  Typbezeichnung mit Bildschirmgröße in Pixeln
  1 = page buffer mode
  Hardware I2C
  Name des OLEDs
  Rotation R0 (keine)
*/
U8G2_SSD1306_128X64_NONAME_1_HW_I2C oled(U8G2_R0, U8X8_PIN_NONE);

// SSID des Routers und Passwort
char Router[] = "SSID_des_Routers";
char Passwort[] = "xxxxxxx";

// NTP starten
WiFiUDP wifiUdp;
NTP ntp(wifiUdp);

// Zeit bis zur nächsten Messung
static unsigned long GesicherteStartZeit = 0;
unsigned long Startzeit;

// 30 Sekunden Intervall, kann angepasst werden
int Intervall = 30000;

void setup()
{
  Serial.begin(9600);
  delay(500);

  // WiFi starten DHCP
  WiFi.begin(Router, Passwort);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
  }

  // SSID des Routers im Seriellen Monotor anzeigen
  Serial.print("Verbunden mit ");
  Serial.println(WiFi.SSID());

  // IP anzeigen
  Serial.print("IP: ");
  Serial.println(WiFi.localIP());

  /*
    Zeitzone
    CEST: Central European Summertime
    Beginn europäische Sommerzeit letzter Sonntag im März 2 Uhr GMT + 2 Stunden
  */
  ntp.ruleDST("CEST", Last, Sun, Mar, 2, 120);

  // CET: Central European Time
  // Beginn Normalzeit letzter Sonntag im Oktober 3 Uhr GMT + 1 Stunde
  ntp.ruleSTD("CET", Last, Sun, Oct, 3, 60);

  // ntp starten
  ntp.begin();

  // OLED starten
  oled.begin();

  // Schriftart
  oled.setFont(u8g2_font_courB24_tf);

  // Zeichenfarbe weiß
  oled.setDrawColor(1);

  // horizontale Schrift
  oled.setFontDirection(0);

  // Datum und Zeit beim Start anzeigen
  ntp.update();
  oled.clearDisplay();
  oled.firstPage();
  do
  {
    oled.setCursor(2, 15);
    oled.setFont(u8g2_font_t0_22_te);

    // Tag: führende 0 ergänzen
    if (ntp.day() < 10) oled.print("0");
    oled.print(ntp.day());
    oled.print(".");

    // Monat: führende 0 ergänzen
    if (ntp.month() < 10) oled.print("0");
    oled.print(ntp.month());
    oled.print(".");

    // Jahr
    oled.print(ntp.year());

    // horizontale Linie
    oled.drawHLine(1, 22, oled.getDisplayWidth());
    oled.setCursor(2, 63);

    // Uhrzeit
    // Stunden: führende 0 ergänzen
    oled.setFont(u8g2_font_logisoso32_tf);
    if (ntp.hours() < 10) oled.print("0");
    oled.print(String(ntp.hours()) + ":");

    // Minuten: führende 0 ergänzen
    if (ntp.minutes() < 10) oled.print("0");
    oled.print(String(ntp.minutes()));
  }
  while (oled.nextPage());
}

void loop()
{
  // Startzeit setzen
  Startzeit = millis();

  // wenn das festgelegte Intervall erreicht ist
  if (Startzeit - GesicherteStartZeit > Intervall)
  {
    // Zeit aktualisieren
    ntp.update();
    oled.clearDisplay();

    // Startzeit zurücksetzen
    GesicherteStartZeit = Startzeit;

    // Datum und Zeit auf dem OLED anzeigen
    oled.setCursor(3, 20);
    oled.firstPage();
    do
    {
      oled.setCursor(2, 15);
      oled.setFont(u8g2_font_t0_22_te);

      // Tag: führende 0 ergänzen
      if (ntp.day() < 10) oled.print("0");
      oled.print(ntp.day());
      oled.print(".");

      // Monat: führende 0 ergänzen
      if (ntp.month() < 10) oled.print("0");
      oled.print(ntp.month());
      oled.print(".");
      oled.print(ntp.year());

      // horizontale Linie
      oled.drawHLine(1, 22, oled.getDisplayWidth());
      oled.setCursor(2, 63);

      // Uhrzeit
      // Stunden: führende 0 ergänzen
      oled.setFont(u8g2_font_logisoso32_tf);
      if (ntp.hours() < 10) oled.print("0");
      oled.print(String(ntp.hours()) + ":");

      // Minuten: führende 0 ergänzen
      if (ntp.minutes() < 10) oled.print("0");
      oled.print(String(ntp.minutes()));
    }
    while (oled.nextPage());
  }
}
Rate the instructions

Comments

Ask a question or share an experience

Contact us if something doesn’t work. Please include your board and the error message.

We review every comment before publication. Your email address remains with us.