Skip to content

Technik Blog

IoT, Smart Home & Mikrocontroller einfach erklärt

Menu
  • Smarthome
  • Gartenautomation
  • Mikrocontroller
    • Arduino
    • ESP32 & Co.
    • Calliope Mini
    • Raspberry Pi & Pico
  • Solo Mining
  • Über mich
Menu

XIAO Expansion Board: RTC mit MicroPython einstellen und auslesen

Veröffentlicht am 14. September 202614. September 2026 von Stefan Draeger

Den kleinen Seeed Studio XIAO ESP32-C6 habe ich bereits in einem separaten Beitrag vorgestellt. Dieses Mal geht es um das passende XIAO Expansion Board, das den Mikrocontroller um einige nützliche Funktionen erweitert. Dazu gehören unter anderem ein OLED-Display, ein Buzzer, verschiedene Grove-Schnittstellen und eine Echtzeituhr – kurz RTC.

XIAO Expansion Board: RTC mit MicroPython einstellen und auslesen
Dieses Video auf YouTube ansehen.

In diesem Beitrag beschäftigen wir uns ausschließlich mit dieser RTC. Ich zeige dir, wie du Datum und Uhrzeit mit MicroPython einstellst, anschließend wieder ausliest und die Zeitdaten in deinen eigenen Projekten weiterverwendest.

Ausgabe von Datum und Uhrzeit am XIAO Expansion Board mit XIAO ESP32-C6
RTC PCF8563 auf dem XIAO Expansion Board
Rückseite des XIAO Expansion Board mit Halterung für CR1220 Batterie
XIAO ESP32-C6 auf dem Expansion Board von Seeed Studio

Transparenzhinweis: Das Seeed Studio XIAO Expansion Board inklusive XIAO ESP32-C6 wurde mir von OpenELAB kostenfrei für diesen Beitrag zur Verfügung gestellt. Auf den Inhalt und meine Bewertung wurde kein Einfluss genommen.

Du findest den XIAO ESP32-C6 hier:

  • bei OpenELAB (Affiliate-Link)
  • direkt bei Seeed Studio

Inhaltsverzeichnis

  • Was ist eine RTC?
  • Benötigte Hard- und Software
    • Hardware
    • Software
  • RTC und OLED über I²C ansprechen
    • I²C-Geräte suchen
  • RTC zum ersten Mal auslesen
  • Datum und Uhrzeit der RTC einstellen
    • Bedeutung des Wochentags
    • Hinweis zur Zeitzone
  • Wiederverwendbare Bibliothek für die RTC
    • Bibliothek auf den XIAO übertragen
    • I²C und Zeitzone festlegen
    • Hinweis zur Sommer- und Winterzeit
    • Zeitstempel setzen
    • Zeitstempel auslesen
    • Vorgegebene Datumsformate verwenden
    • Eigenes Format festlegen
    • Einzelne Zeitwerte verwenden
    • Gültigkeit der RTC-Zeit prüfen
    • Welche Aufgaben übernimmt die Bibliothek?
  • Datum und Uhrzeit auf dem OLED anzeigen
    • Programm für die OLED-Anzeige
    • Zeitzone anpassen
  • Häufige Probleme und mögliche Lösungen
    • RTC verliert nach dem Ausschalten die Uhrzeit
    • Angezeigte Uhrzeit weicht um eine oder zwei Stunden ab
    • RTC-Zeit wird als ungültig erkannt
    • OLED-Display bleibt leer
  • Fazit und Ausblick

Was ist eine RTC?

Die Abkürzung RTC steht für Real-Time Clock, auf Deutsch Echtzeituhr. Dabei handelt es sich um einen speziellen Baustein, der Datum und Uhrzeit unabhängig vom eigentlichen Programm des Mikrocontrollers verwaltet.

Auf dem XIAO Expansion Board ist dafür eine PCF8563-RTC verbaut. Eine eingesetzte CR1220-Knopfzelle versorgt die Echtzeituhr auch dann, wenn der XIAO ESP32-C6 nicht über USB oder eine andere Stromquelle mit Energie versorgt wird. Dadurch läuft die eingestellte Uhrzeit weiter und muss nicht nach jedem Neustart erneut gesetzt werden.

Die RTC kennt allerdings weder eine Zeitzone noch die Sommer- und Winterzeit. Sie speichert und zählt lediglich die Werte weiter, die wir zuvor eingestellt haben. Die Umrechnung in eine bestimmte Zeitzone muss deshalb bei Bedarf durch das Programm erfolgen.

Benötigte Hard- und Software

Für dieses Projekt benötigst du neben dem XIAO ESP32-C6 das passende Expansion Board. Auf diesem befinden sich sowohl die PCF8563-Echtzeituhr als auch das OLED-Display, auf dem wir später Datum und Uhrzeit anzeigen.

Hardware

Für dieses Projekt benötigst du:

  • einen Mikrocontroller aus der Seeed-Studio-XIAO-Familie
  • das XIAO Expansion Board
  • eine CR1220-Knopfzelle für die RTC
  • ein USB-C-Datenkabel
  • einen Computer mit einem freien USB-Anschluss

Das XIAO Expansion Board ist nicht ausschließlich für den XIAO ESP32-C6 vorgesehen. Es kann auch mit verschiedenen anderen Mikrocontrollern aus der XIAO-Familie verwendet werden, beispielsweise dem XIAO ESP32-S3, XIAO ESP32-C3 oder XIAO RP2040. Wichtig ist vor allem der einheitliche Formfaktor des XIAO-Ökosystems.

XIAO Expansion Board mit ESP32-C6, USB-Kabel und CR1220-Knopfzelle für die RTC
XIAO Expansion Board mit XIAO ESP32-C6 und CR1220-Knopfzelle zur Pufferung der PCF8563-Echtzeituhr.

In diesem Beitrag verwende ich den Seeed Studio XIAO ESP32-C6. Wenn du einen anderen XIAO einsetzt, können sich die GPIO-Nummern und damit die Initialisierung der I²C-Schnittstelle unterscheiden. Die grundsätzliche Kommunikation mit der PCF8563-RTC bleibt jedoch gleich.

Blister mit verschiedenen Mikrocontrollern aus der Seeed Studio XIAO-Familie
Verschiedene Mikrocontroller aus der Seeed Studio XIAO-Familie im einheitlichen XIAO-Formfaktor.

Falls dein XIAO noch keine Stiftleisten besitzt, musst du diese zunächst anlöten. Nur so kann der Mikrocontroller auf das Expansion Board gesteckt werden. Achte beim Einsetzen darauf, den XIAO richtig ausgerichtet und mittig in die beiden Buchsenleisten zu stecken.

Die CR1220-Knopfzelle sorgt dafür, dass die RTC auch bei unterbrochener USB-Stromversorgung weiterläuft. Für einen ersten Funktionstest ist sie nicht zwingend erforderlich. Ohne Knopfzelle kann die eingestellte Uhrzeit jedoch verloren gehen, sobald das Expansion Board nicht mehr mit Strom versorgt wird.

Software

Für die Programmierung verwende ich MicroPython und die Entwicklungsumgebung Thonny. Folgende Software beziehungsweise Dateien werden benötigt:

  • eine aktuelle MicroPython-Firmware für den XIAO ESP32-C6
  • die Entwicklungsumgebung Thonny
  • der MicroPython-Treiber ssd1306.py für das OLED-Display
  • die im Laufe dieses Beitrags erstellte Datei xiao_rtc.py

Mit der Datei xiao_rtc.py greife ich später aus eigenen Projekten auf die RTC zu. Die darin enthaltene Klasse XiaoRTC stellt mir einfache Methoden bereit, mit denen ich Datum und Uhrzeit setzen, auslesen, prüfen und als formatierten Zeitstempel ausgeben kann.

RTC und OLED über I²C ansprechen

Sowohl die PCF8563-RTC als auch das OLED-Display des XIAO Expansion Boards werden über I²C angesprochen. Bei I²C können mehrere Geräte dieselben beiden Datenleitungen verwenden. Damit der Mikrocontroller sie unterscheiden kann, besitzt jedes Gerät eine eigene Adresse.

Beim XIAO ESP32-C6 werden dafür die folgenden Anschlüsse verwendet:

FunktionXIAO-PinGPIO
SDAD4GPIO22
SCLD5GPIO23

Das OLED-Display und die RTC sind auf dem Expansion Board bereits mit diesen Anschlüssen verbunden. Zusätzliche Kabel werden daher nicht benötigt.

I²C-Geräte suchen

Mit einem kurzen I²C-Scan prüfe ich nun, welche Geräte der XIAO ESP32-C6 am gemeinsamen Bus erkennt.

from machine import I2C, Pin

i2c = I2C(
    0,
    sda=Pin(22),
    scl=Pin(23),
    freq=100000
)

devices = i2c.scan()

print("Gefundene I2C-Geräte:")

for address in devices:
    print(hex(address))

Nachdem du das Skript gestartet hast, werden die gefundenen Geräte in der MicroPython-Konsole ausgegeben. Bei meinem XIAO Expansion Board in der Revision 1.2 erscheint folgende Ausgabe:

Ausgabe des I2C-Scanners für das XIAO Expansion Board unter MicroPython
Der I²C-Scan erkennt auf dem XIAO Expansion Board die Adressen 0x3C, 0x51 und 0x6B.

Für unser Projekt sind vor allem die folgenden beiden Adressen wichtig:

I²C-AdresseKomponente
0x3COLED-Display
0x51PCF8563-Echtzeituhr

Die zusätzlich erkannte Adresse 0x6B wird für das Auslesen der RTC und die spätere Anzeige auf dem OLED nicht benötigt. Seeed stellt in der offiziellen Dokumentation derzeit lediglich den Schaltplan der älteren Boardrevision 1.0 bereit. Eine eindeutige Zuordnung des zusätzlichen I²C-Geräts auf meiner Revision 1.2 ist daher anhand der verfügbaren Unterlagen nicht möglich.

Der MicroSD-Kartenleser ist nicht für die Adresse 0x6B verantwortlich. Er wird über die SPI-Schnittstelle angesprochen und verwendet D2 als Chip-Select-Leitung. SPI-Geräte erscheinen bei einem I²C-Scan nicht.

Für den weiteren Verlauf ist entscheidend, dass mindestens die Adressen 0x3C und 0x51 erkannt werden. Damit wissen wir, dass der XIAO sowohl das OLED-Display als auch die PCF8563-RTC über den gemeinsamen I²C-Bus erreichen kann.

Sollte eine der beiden Adressen fehlen, überprüfe zunächst, ob der XIAO richtig auf dem Expansion Board sitzt. Verwendest du einen anderen Mikrocontroller aus der XIAO-Familie, musst du gegebenenfalls die GPIO-Nummern für SDA und SCL anpassen.

RTC zum ersten Mal auslesen

Nachdem die PCF8563 beim I²C-Scan unter der Adresse 0x51 gefunden wurde, können wir erstmals ihre Zeitregister auslesen. Dabei erhalten wir bereits Werte für Datum und Uhrzeit – auch wenn die RTC noch nicht korrekt eingestellt wurde.

Die PCF8563 speichert ihre Zeitinformationen in sieben aufeinanderfolgenden Registern. Die einzelnen Werte liegen im sogenannten BCD-Format vor. Damit wir sie als normale Zahlen verwenden können, müssen wir sie nach dem Auslesen zunächst umwandeln.

Erstelle in Thonny ein neues Skript und füge den folgenden Code ein:

from machine import I2C, Pin

RTC_ADDRESS = 0x51

i2c = I2C(
    0,
    sda=Pin(22),
    scl=Pin(23),
    freq=100000
)


def bcd_to_decimal(value):
    return (value >> 4) * 10 + (value & 0x0F)


data = i2c.readfrom_mem(RTC_ADDRESS, 0x02, 7)

second = bcd_to_decimal(data[0] & 0x7F)
minute = bcd_to_decimal(data[1] & 0x7F)
hour = bcd_to_decimal(data[2] & 0x3F)
day = bcd_to_decimal(data[3] & 0x3F)
weekday = data[4] & 0x07
month = bcd_to_decimal(data[5] & 0x1F)
year = 2000 + bcd_to_decimal(data[6])

voltage_low = bool(data[0] & 0x80)

print("Ausgelesene RTC-Daten:")
print("Datum: {:02d}.{:02d}.{:04d}".format(day, month, year))
print("Uhrzeit: {:02d}:{:02d}:{:02d}".format(hour, minute, second))
print("Wochentag:", weekday)

if voltage_low:
    print("Warnung: Die RTC-Zeit ist möglicherweise nicht gültig.")

Die Ausgabe kann beispielsweise wie folgt aussehen:

MicroPython-Ausgabe der noch nicht eingestellten RTC auf dem XIAO Expansion Board
Die PCF8563-RTC liefert bereits Daten, der Zeitstempel ist jedoch noch nicht gültig.

Das ausgelesene Datum 10.14.2142 kann offensichtlich nicht stimmen: Einen Monat 14 gibt es nicht und auch das Jahr liegt außerhalb des erwarteten Bereichs. Die PCF8563 liefert zwar bereits Inhalte aus ihren Zeitregistern, diese wurden jedoch noch nicht korrekt initialisiert.

Zusätzlich ist das Voltage-Low-Flag gesetzt. Damit signalisiert die RTC, dass ihre Versorgungsspannung zwischenzeitlich zu niedrig war und die gespeicherten Zeitwerte nicht zuverlässig sind. Die ausgelesenen Daten dürfen daher noch nicht als gültiges Datum verwendet werden.

Unsere I²C-Kommunikation funktioniert trotzdem: Der XIAO ESP32-C6 konnte die sieben Zeitregister der PCF8563 erfolgreich auslesen. Im nächsten Schritt stellen wir Datum und Uhrzeit korrekt ein und prüfen die Werte anschließend erneut.

Datum und Uhrzeit der RTC einstellen

Nachdem wir die vorhandenen, aber noch ungültigen Registerinhalte ausgelesen haben, stellen wir nun ein korrektes Datum und die aktuelle Uhrzeit ein.

Auch beim Schreiben erwartet die PCF8563 die Werte im BCD-Format. Deshalb benötigen wir dieses Mal eine Funktion, die normale Dezimalzahlen in das entsprechende Format umwandelt.

Im folgenden Skript werden Datum und Uhrzeit zunächst über mehrere Konstanten festgelegt. Passe diese Werte vor dem Start an die aktuelle Zeit an:

from machine import I2C, Pin

RTC_ADDRESS = 0x51

i2c = I2C(
    0,
    sda=Pin(22),
    scl=Pin(23),
    freq=100000
)

# Datum und Uhrzeit vor dem Start anpassen
YEAR = 2026
MONTH = 8
DAY = 19

HOUR = 18
MINUTE = 45
SECOND = 0

# Montag = 0, Dienstag = 1, ..., Sonntag = 6
WEEKDAY = 2


def decimal_to_bcd(value):
    return ((value // 10) << 4) | (value % 10)


def bcd_to_decimal(value):
    return (value >> 4) * 10 + (value & 0x0F)


# Uhr anhalten
control = i2c.readfrom_mem(RTC_ADDRESS, 0x00, 1)[0]
i2c.writeto_mem(
    RTC_ADDRESS,
    0x00,
    bytes([control | 0x20])
)

# Zeitregister vorbereiten
rtc_data = bytes([
    decimal_to_bcd(SECOND),
    decimal_to_bcd(MINUTE),
    decimal_to_bcd(HOUR),
    decimal_to_bcd(DAY),
    WEEKDAY,
    decimal_to_bcd(MONTH),
    decimal_to_bcd(YEAR - 2000)
])

# Register 0x02 bis 0x08 schreiben
i2c.writeto_mem(RTC_ADDRESS, 0x02, rtc_data)

# Uhr wieder starten
i2c.writeto_mem(
    RTC_ADDRESS,
    0x00,
    bytes([control & 0xDF])
)

print("Datum und Uhrzeit wurden gesetzt.")

# Werte zur Kontrolle erneut auslesen
data = i2c.readfrom_mem(RTC_ADDRESS, 0x02, 7)

second = bcd_to_decimal(data[0] & 0x7F)
minute = bcd_to_decimal(data[1] & 0x7F)
hour = bcd_to_decimal(data[2] & 0x3F)
day = bcd_to_decimal(data[3] & 0x3F)
weekday = data[4] & 0x07
month = bcd_to_decimal(data[5] & 0x1F)
year = 2000 + bcd_to_decimal(data[6])

voltage_low = bool(data[0] & 0x80)

print("Gespeicherte RTC-Daten:")
print("Datum: {:02d}.{:02d}.{:04d}".format(day, month, year))
print("Uhrzeit: {:02d}:{:02d}:{:02d}".format(hour, minute, second))
print("Wochentag:", weekday)

if voltage_low:
    print("Warnung: Die RTC-Zeit ist möglicherweise nicht gültig.")
else:
    print("Die RTC-Zeit ist gültig.")

Die Uhr wird vor dem Schreiben kurz angehalten. Anschließend übertragen wir alle sieben Zeitwerte gemeinsam in die Register 0x02 bis 0x08 und starten die RTC wieder.

Nach dem Start des Skripts sollte eine Ausgabe ähnlich der folgenden erscheinen:

Ausgabe des gesetzten Zeitstempels der PCF8563-RTC auf dem XIAO Expansion Board
MicroPython bestätigt den gesetzten Zeitstempel und die gültige RTC-Zeit auf dem XIAO Expansion Board.

Die Meldung bestätigt, dass das zuvor gesetzte Voltage-Low-Flag gelöscht wurde und die Zeitwerte jetzt verwendet werden können. Wenn du das reine Ausleseskript aus dem vorherigen Abschnitt erneut startest, sollte die Uhrzeit inzwischen weitergelaufen sein.

Bedeutung des Wochentags

In diesem Beispiel verwenden wir für die Wochentage Zahlen von 0 bis 6:

WertWochentag
0Montag
1Dienstag
2Mittwoch
3Donnerstag
4Freitag
5Samstag
6Sonntag

Der Wochentag muss zum eingestellten Datum passen. Für den 19. August 2026 verwende ich den Wert 2, da dieser Tag ein Mittwoch ist.

Hinweis zur Zeitzone

Die PCF8563 kennt weder Zeitzonen noch die automatische Umstellung zwischen Sommer- und Winterzeit. Sie zählt lediglich die Werte weiter, die wir in ihren Registern speichern.

Für eine einfache Uhr auf dem OLED kannst du die aktuelle lokale Uhrzeit einstellen. Wenn die Zeit später für Berechnungen oder für den Datenaustausch mit anderen Systemen verwendet werden soll, ist es häufig sinnvoller, die RTC auf UTC einzustellen und die lokale Uhrzeit erst im Programm zu berechnen.

Da ich die Werte in diesem Beispiel noch direkt im Quellcode eintragen muss, verwende ich im nächsten Schritt die wiederverwendbare Bibliothek xiao_rtc.py. Sie stellt eine einfache Schnittstelle bereit, über die ich Zeitstempel setzen, auslesen, prüfen und in unterschiedlichen Formaten ausgeben kann.

Wiederverwendbare Bibliothek für die RTC

Bisher habe ich die Register der PCF8563 direkt gelesen und beschrieben. Für die ersten Tests war das sinnvoll, weil dadurch sichtbar wurde, wie die Echtzeituhr im Hintergrund arbeitet. In meinen späteren Projekten möchte ich mich jedoch nicht jedes Mal erneut mit I²C-Adressen, Registern, Bitmasken und der Umwandlung des BCD-Formats beschäftigen.

Deshalb habe ich die Datei xiao_rtc.py erstellt. Die darin enthaltene Klasse XiaoRTC bildet eine einfache Schnittstelle zwischen meinem MicroPython-Programm und der PCF8563. Zum Setzen und Auslesen der Zeit benötige ich dadurch nur noch wenige verständliche Methoden. Die Kommunikation mit den Registern, die BCD-Umwandlung und die Behandlung der Zeitzone übernimmt die Klasse im Hintergrund.

Die fertige Datei kannst du hier herunterladen:

MicroPython-Bibliothek zum Ansteuern der PCF8563-RTC herunterladenHerunterladen

Die Bibliothek enthält zusätzlich eine ausführliche Dokumentation mit mehreren Anwendungsbeispielen. Dadurch findest du die wichtigsten Informationen auch direkt in der Datei, wenn du sie später in einem anderen Projekt verwendest.

Bibliothek auf den XIAO übertragen

Lade zunächst die Datei xiao_rtc.py herunter und öffne sie anschließend in Thonny. Die Bibliothek wird auf dem Mikrocontroller im Verzeichnis lib gespeichert.

Die Dateistruktur auf dem XIAO sieht anschließend folgendermaßen aus:

MicroPython-Projektdateien in Thonny
Die Dateien xiao_rtc.py und ssd1306.py befinden sich im Verzeichnis lib, während main.py im Hauptverzeichnis liegt.

Falls das Verzeichnis lib noch nicht vorhanden ist, kannst du es über die Dateiansicht von Thonny auf dem MicroPython-Gerät anlegen. Speichere die Datei anschließend unter folgendem Pfad: /lib/xiao_rtc.py

erstellen eines Verzeichnisses in Thonny - Step #1
erstellen eines Verzeichnisses in Thonny - Step #2
kopieren einer Datei auf den Mikrocontroller unter Thonny

Das eigentliche Projektprogramm bleibt als main.py im Hauptverzeichnis des Mikrocontrollers.

MicroPython durchsucht das Verzeichnis lib automatisch nach importierbaren Modulen. Deshalb kann ich die Klasse anschließend wie gewohnt in meinem Programm importieren:

from xiao_rtc import XiaoRTC

Eine Angabe des vollständigen Pfades ist beim Import nicht erforderlich.

I²C und Zeitzone festlegen

Zunächst initialisiere ich die I²C-Schnittstelle und erzeuge ein Objekt der Klasse XiaoRTC:

from machine import I2C, Pin
from xiao_rtc import XiaoRTC

i2c = I2C(
    0,
    sda=Pin(22),
    scl=Pin(23),
    freq=100000
)

rtc = XiaoRTC(
    i2c,
    timezone="+02:00"
)

Mit timezone="+02:00" lege ich einen festen Versatz von zwei Stunden gegenüber UTC fest. Die Bibliothek speichert die Zeit intern als UTC in der PCF8563 und rechnet sie beim Setzen und Auslesen automatisch um.

Verwende ich beispielsweise die lokale Uhrzeit 12:30 Uhr mit der Zeitzone +02:00, speichert die Bibliothek intern 10:30 Uhr in der RTC.

Diese Trennung ist besonders praktisch, wenn ich den Zeitstempel später für Berechnungen oder den Datenaustausch mit anderen Systemen benötige.

Hinweis zur Sommer- und Winterzeit

Die Bibliothek verwendet einen festen UTC-Versatz. Eine automatische Umstellung zwischen Sommer- und Winterzeit findet nicht statt, da MicroPython normalerweise keine vollständige Zeitzonendatenbank mitbringt.

Für Deutschland verwende ich üblicherweise:

ZeitraumZeitzone
Winterzeit+01:00
Sommerzeit+02:00

Den Versatz kann ich jederzeit ändern:

rtc.set_timezone("+01:00")

Dabei wird die in der RTC gespeicherte UTC-Zeit nicht verändert. Lediglich die daraus berechnete lokale Uhrzeit wird mit dem neuen Versatz ausgegeben.

Zeitstempel setzen

Zum Einstellen von Datum und Uhrzeit verwende ich die Methode set_timestamp():

rtc.set_timestamp("2026-08-19 19:22:54")

Der Zeitstempel muss dabei in folgendem Format übergeben werden:

YYYY-MM-DD HH:MM:SS

Die einzelnen Bestandteile bedeuten:

BestandteilBedeutung
YYYYvierstelliges Jahr
MMMonat
DDTag
HHStunde
MMMinute
SSSekunde

Die Bibliothek interpretiert den übergebenen Wert standardmäßig als lokale Zeit. Bei der zuvor eingestellten Zeitzone +02:00 wird der Zeitstempel daher vor dem Speichern automatisch in UTC umgerechnet.

Möchte ich direkt einen UTC-Zeitstempel speichern, kann ich die Umrechnung deaktivieren:

rtc.set_timestamp(
    "2026-08-19 17:22:54",
    local=False
)

Beide Beispiele speichern in diesem Fall denselben Zeitpunkt in der PCF8563.

Zeitstempel auslesen

Mit get_timestamp() lese ich die Zeit wieder aus:

print(rtc.get_timestamp())

Die Ausgabe erfolgt standardmäßig im ISO-ähnlichen Format:

2026-08-19 19:22:54

Dabei wird die in der RTC gespeicherte UTC-Zeit automatisch mit dem eingestellten Zeitzonenversatz in die lokale Zeit umgerechnet.

Benötige ich stattdessen den unveränderten UTC-Zeitstempel, verwende ich:

print(rtc.get_utc_timestamp())

Die Ausgabe lautet bei diesem Beispiel:

2026-08-19 17:22:54

Vorgegebene Datumsformate verwenden

Die Bibliothek enthält mehrere häufig verwendete Formatvorlagen:

KonstanteBeispiel
FORMAT_ISO2026-08-19 19:22:54
FORMAT_RFC33392026-08-19T19:22:54+02:00
FORMAT_GERMAN19.08.2026 19:22:54
FORMAT_DATE_ISO2026-08-19
FORMAT_DATE_GERMAN19.08.2026
FORMAT_TIME19:22:54

Das deutsche Datumsformat gebe ich beispielsweise folgendermaßen aus:

print(
    rtc.get_timestamp(
        XiaoRTC.FORMAT_GERMAN
    )
)

Die Ausgabe lautet:

19.08.2026 19:22:54

Für einen Zeitstempel mit Zeitzonenangabe verwende ich das RFC-3339-Format:

print(
    rtc.get_timestamp(
        XiaoRTC.FORMAT_RFC3339
    )
)

Ausgabe:

2026-08-19T19:22:54+02:00

Eigenes Format festlegen

Neben den vorgegebenen Formaten kann ich auch ein eigenes Muster übergeben:

print(
    rtc.get_timestamp(
        "%A, %d. %B %Y - %H:%M:%S"
    )
)

Das Ergebnis lautet:

Mittwoch, 19. August 2026 - 19:22:54

Die Bibliothek unterstützt unter anderem folgende Platzhalter:

PlatzhalterBedeutungBeispiel
%YJahr, vierstellig2026
%yJahr, zweistellig26
%mMonat08
%dTag19
%HStunde19
%MMinute22
%SSekunde54
%akurzer WochentagMi
%Avollständiger WochentagMittwoch
%bkurzer MonatsnameAug
%Bvollständiger MonatsnameAugust
%zUTC-Versatz+02:00
%ZZeitzonenbezeichnungUTC+02:00
%%Prozentzeichen%

Damit kann ich die Ausgabe an das jeweilige Projekt anpassen, ohne die Bibliothek selbst verändern zu müssen.

Einzelne Zeitwerte verwenden

Benötige ich nicht den formatierten Zeitstempel, sondern die einzelnen Bestandteile, verwende ich get_datetime():

year, month, day, hour, minute, second = (
    rtc.get_datetime()
)

print("Jahr:", year)
print("Monat:", month)
print("Tag:", day)
print("Stunde:", hour)
print("Minute:", minute)
print("Sekunde:", second)

Diese Variante ist besonders hilfreich, wenn ich das Datum für weitere Berechnungen benötige. In meinem späteren Projekt kann ich damit beispielsweise die aktuelle Mondphase bestimmen.

Für die UTC-Werte rufe ich die Methode mit local=False auf:

year, month, day, hour, minute, second = (
    rtc.get_datetime(local=False)
)

Gültigkeit der RTC-Zeit prüfen

Die Bibliothek prüft beim Auslesen unter anderem das Voltage-Low-Flag und die Plausibilität der gespeicherten Werte. Vor der weiteren Verarbeitung kann ich deshalb kontrollieren, ob die RTC eine gültige Zeit enthält:

if rtc.is_valid():
    print(rtc.get_timestamp())
else:
    print("Die RTC muss zunächst eingestellt werden.")

Damit verhindere ich, dass ungültige Werte wie der zuvor ausgelesene Monat 14 in meinem eigentlichen Projekt weiterverarbeitet werden.

Welche Aufgaben übernimmt die Bibliothek?

Mit der Klasse XiaoRTC verstecke ich die technischen Details der PCF8563 hinter einer einfachen Schnittstelle. Die Bibliothek übernimmt für mich unter anderem:

  • die Kommunikation mit der I²C-Adresse 0x51
  • das Lesen und Schreiben der RTC-Register
  • die Umwandlung zwischen Dezimalzahlen und BCD
  • die automatische Berechnung des Wochentags
  • die Prüfung von Datum und Uhrzeit
  • die Erkennung eines Spannungsverlusts
  • die Speicherung der RTC-Zeit in UTC
  • die Umrechnung in eine lokale Zeitzone
  • die Formatierung des Zeitstempels

Dadurch kann ich die Datei xiao_rtc.py in meinen späteren Projekten wiederverwenden, ohne mich erneut mit dem internen Aufbau der PCF8563 beschäftigen zu müssen.

Datum und Uhrzeit auf dem OLED anzeigen

Zum Abschluss zeige ich das aktuelle Datum und die Uhrzeit auf dem OLED-Display des XIAO Expansion Boards an. Da sowohl das Display als auch die PCF8563 am selben I²C-Bus angeschlossen sind, benötige ich keine zusätzlichen Kabel oder eine zweite Schnittstelle.

Für dieses Beispiel müssen sich die beiden Bibliotheken xiao_rtc.py und ssd1306.py im Verzeichnis lib befinden. Das eigentliche Programm speichere ich als main.py im Hauptverzeichnis des XIAO:

MicroPython-Projektdateien in Thonny
Die Dateien xiao_rtc.py und ssd1306.py befinden sich im Verzeichnis lib, während main.py im Hauptverzeichnis liegt.

Programm für die OLED-Anzeige

In der Datei main.py initialisiere ich zunächst die gemeinsame I²C-Schnittstelle. Anschließend erzeuge ich jeweils ein Objekt für das OLED-Display und die RTC:

MicroPython-Quellcode zur Anzeige von Datum & Uhrzeit auf dem OLED-Display
from machine import I2C, Pin
from time import sleep
from ssd1306 import SSD1306_I2C
from xiao_rtc import XiaoRTC

OLED_WIDTH = 128
OLED_HEIGHT = 64

i2c = I2C(
    0,
    sda=Pin(22),
    scl=Pin(23),
    freq=100000
)

oled = SSD1306_I2C(
    OLED_WIDTH,
    OLED_HEIGHT,
    i2c,
    addr=0x3C
)

rtc = XiaoRTC(
    i2c,
    timezone="+02:00"
)


def centered_x(text):
    text_width = len(text) * 8
    return max(0, (OLED_WIDTH - text_width) // 2)


while True:
    if rtc.is_valid():
        values = rtc.get_datetime()

        date_text = rtc.format_datetime(
            values,
            XiaoRTC.FORMAT_DATE_GERMAN
        )

        time_text = rtc.format_datetime(
            values,
            XiaoRTC.FORMAT_TIME
        )

        oled.fill(0)

        oled.text(
            "XIAO RTC",
            centered_x("XIAO RTC"),
            4
        )

        oled.text(
            date_text,
            centered_x(date_text),
            26
        )

        oled.text(
            time_text,
            centered_x(time_text),
            46
        )

        oled.show()
    else:
        oled.fill(0)
        oled.text("RTC-Zeit", 32, 20)
        oled.text("ungueltig!", 24, 38)
        oled.show()

    sleep(0.5)

Nach dem Start zeigt das OLED beispielsweise folgende Inhalte an:

Ausgabe von Datum und Uhrzeit am XIAO Expansion Board mit XIAO ESP32-C6

Die Methode get_datetime() liest alle Bestandteile von Datum und Uhrzeit gemeinsam aus. Dadurch stammen Datum und Uhrzeit garantiert aus demselben Lesevorgang. Das ist vor allem während eines Tageswechsels wichtig.

Anschließend formatiere ich die Werte mit den bereits in der Bibliothek vorhandenen Formatvorlagen:

XiaoRTC.FORMAT_DATE_GERMAN
XiaoRTC.FORMAT_TIME

Mit der Hilfsfunktion centered_x() berechne ich die horizontale Position der Texte. Die Standardschrift des SSD1306-Treibers ist acht Pixel breit. Aus der Anzahl der Zeichen kann ich deshalb näherungsweise bestimmen, an welcher Position der Text beginnen muss, damit er mittig auf dem 128 Pixel breiten Display erscheint.

Zeitzone anpassen

In diesem Beispiel verwende ich für die deutsche Sommerzeit den UTC-Versatz +02:00:

rtc = XiaoRTC(
    i2c,
    timezone="+02:00"
)

Während der Winterzeit ändere ich den Wert auf +01:00:

rtc = XiaoRTC(
    i2c,
    timezone="+01:00"
)

Die in der RTC gespeicherte UTC-Zeit muss dabei nicht erneut gesetzt werden. Die Bibliothek berechnet die angezeigte lokale Uhrzeit aus dem gewählten Versatz.

Wenn auf dem Display stattdessen die Meldung RTC-Zeit ungueltig! erscheint, konnte die Bibliothek keinen plausiblen Zeitwert auslesen. In diesem Fall muss ich Datum und Uhrzeit zunächst erneut setzen.

Damit kann ich die PCF8563 nun nicht nur einstellen und auslesen, sondern ihre Zeitdaten auch direkt in einem eigenen MicroPython-Projekt verwenden. Die Bibliothek xiao_rtc.py bildet dabei die wiederverwendbare Grundlage für weitere Projekte – beispielsweise für meine geplante Berechnung und Darstellung der aktuellen Mondphase.

Häufige Probleme und mögliche Lösungen

RTC verliert nach dem Ausschalten die Uhrzeit

Gehen Datum und Uhrzeit nach dem Trennen der USB-Verbindung verloren, überprüfe ich die CR1220-Knopfzelle. Sie versorgt die PCF8563 weiter, wenn das Expansion Board keine andere Stromversorgung erhält.

Mögliche Ursachen sind:

  • es wurde keine CR1220-Knopfzelle eingesetzt
  • die Knopfzelle ist leer
  • die Knopfzelle wurde falsch herum eingesetzt

Nach einem Spannungsverlust kann das Voltage-Low-Flag gesetzt sein. In diesem Fall muss ich die RTC erneut einstellen.

Der JST-Anschluss und der Batterieschalter dienen dagegen der LiPo-Stromversorgung des XIAO und des Expansion Boards. Sie sind nicht für die Pufferung der RTC zuständig.

Angezeigte Uhrzeit weicht um eine oder zwei Stunden ab

Eine Abweichung um genau eine oder zwei Stunden deutet meistens auf einen falsch eingestellten UTC-Versatz hin. Für Deutschland verwende ich normalerweise:

  • +01:00 während der Winterzeit
  • +02:00 während der Sommerzeit

Die Bibliothek nimmt keine automatische Umstellung zwischen Sommer- und Winterzeit vor. Den verwendeten Versatz muss ich deshalb bei Bedarf selbst anpassen:

rtc.set_timezone("+01:00")

oder:

rtc.set_timezone("+02:00")

Die in der RTC gespeicherte UTC-Zeit wird dabei nicht verändert.

RTC-Zeit wird als ungültig erkannt

Gibt rtc.is_valid() den Wert False zurück, sind entweder die gespeicherten Datumswerte unplausibel oder das Voltage-Low-Flag ist gesetzt. Das kann beispielsweise nach einer fehlenden oder unterbrochenen Stromversorgung auftreten.

In diesem Fall stelle ich Datum und Uhrzeit erneut ein:

rtc.set_timestamp("2026-08-19 19:22:54")

Anschließend kann ich die Gültigkeit erneut prüfen:

if rtc.is_valid():
   print(rtc.get_timestamp())
else:
   print("Die RTC-Zeit ist weiterhin ungültig.")

OLED-Display bleibt leer

Bleibt das OLED-Display leer, prüfe ich zunächst mit dem I²C-Scanner, ob die Adresse 0x3C gefunden wird. Anschließend kontrolliere ich, ob sich der benötigte Treiber unter diesem Pfad auf dem Mikrocontroller befindet:

/lib/ssd1306.py

Die Initialisierung muss außerdem zur erkannten Displayadresse passen:

oled=SSD1306_I2C(128,64,i2c,addr=0x3C)

Da sich RTC und OLED denselben I²C-Bus teilen, muss für beide Komponenten dasselbe I2C-Objekt verwendet werden.

Fazit und Ausblick

In diesem Beitrag habe ich gezeigt, wie ich die PCF8563-RTC auf dem XIAO Expansion Board mit MicroPython anspreche. Datum und Uhrzeit lassen sich nun einstellen, auslesen, als Zeitstempel formatieren und auf dem OLED-Display anzeigen. Mit der Bibliothek xiao_rtc.py steht mir dafür eine wiederverwendbare Grundlage für weitere XIAO-Projekte zur Verfügung.

Die manuelle Einstellung hat allerdings einen kleinen Nachteil: Ich muss die gewünschte Uhrzeit zunächst im Quellcode eintragen und anschließend das Programm starten. Zwischen dem Eintragen, Übertragen und Ausführen vergehen einige Sekunden. Dadurch kann die gespeicherte RTC-Zeit leicht von der tatsächlichen Uhrzeit abweichen.

Eine genauere und komfortablere Lösung besteht darin, die aktuelle Uhrzeit während der Laufzeit von einem NTP-Server abzurufen. Der XIAO ESP32-C6 verbindet sich dafür kurz mit dem WLAN, übernimmt die Netzwerkzeit und speichert sie in der RTC. Anschließend kann ich die WLAN-Schnittstelle wieder deaktivieren und die weitere Zeitmessung der stromsparenden Echtzeituhr überlassen.

Wie die automatische Synchronisierung über einen NTP-Server funktioniert und wie ich das WLAN danach wieder abschalte, zeige ich dir im kommenden Beitrag.

Transparenzhinweis: Dieser Beitrag wurde mit Unterstützung künstlicher Intelligenz erstellt und redaktionell geprüft. Mehr zur Nutzung von KI

Letzte Aktualisierung am: 14. September 2026

Foto von Stefan Draeger
Über den Autor

Stefan Draeger — Entwickler & Tech-Blogger

Ich zeige praxisnah, wie du Projekte mit Arduino, ESP32 und Smarthome-Komponenten umsetzt – Schritt für Schritt, mit Code und Schaltplänen.

Mehr Artikel von Stefan →

Schreibe einen Kommentar Antwort abbrechen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Kategorien

Kontakt & Hilfe

Fragen oder Feedback?

Du hast eine Idee, brauchst Hilfe oder möchtest Feedback loswerden? Erstelle einfach ein Support-Ticket.

Support-Ticket erstellen
Keine Beiträge verpassen

Newsletter abonnieren

Erhalte regelmäßig Updates zu neuen Projekten, Tutorials und Tipps rund um Arduino, ESP32, Smarthome und IoT direkt in dein Postfach.

Newsletter abonnieren
Videos & Tutorials

Draeger-IT auf YouTube

Entdecke meine Videos zu Arduino, ESP32, Raspberry Pi, Smarthome und spannenden Elektronikprojekten – mit Tutorials, Tests und Praxisbeispielen.

YouTube-Kanal besuchen
Freiwillige Unterstützung

Unterstütze meinen Blog

Wenn dir meine Inhalte gefallen, freue ich mich über deine Unterstützung auf Tipeee. So hilfst du dabei, den Blog am Leben zu halten und neue Beiträge zu ermöglichen.

Auf Tipeee unterstützen

Vielen Dank für deinen Support!
– Stefan Draeger

Kostenlose Online-Werkzeuge

Tools

Praktische Generatoren, Rechner und Hilfsmittel für deine Elektronik- und Entwicklungsprojekte.

Generatoren & Konverter

  • QR-Code Generator
  • Passwort Generator
  • PNG zu WebP konvertieren
  • Bilder online komprimieren
  • Code online formatieren

Rechner & Tabellen

  • Unix-Zeitstempel-Rechner
  • ASCII-Tabelle
  • Spannung, Strom, Widerstand und Leistung berechnen
  • Widerstandsrechner

LED-Matrix

  • 8×8 LED Matrix Tool
  • 8×16 LED Matrix Modul von Keyestudio
  • 16×16 LED Matrix Generator
Kontakt

Anschrift & Kontaktdaten

Stefan Draeger

Königsberger Str. 13
38364 Schöningen

Telefon 01556 5432686

E-Mail info@draeger-it.blog

Blogverzeichnis Bloggerei.de TopBlogs.de das Original - Blogverzeichnis | Blog Top Liste Blogverzeichnis trusted-blogs.com
Social Media

Folge mir auf

Weitere Projekte, Videos und Neuigkeiten findest du auch auf meinen Social-Media-Kanälen.

  • f Facebook
  • in LinkedIn
  • ▶ YouTube
  • ♪ TikTok
  • P Pinterest
  • ◎ Instagram
Rechtliche Informationen

Rechtliches

  • Impressum
  • Datenschutzerklärung
  • Disclaimer
  • Cookie-Richtlinie (EU)
  • KI-Transparenz bei draeger-it.blog
©2026 Technik Blog | Built using WordPress and Responsive Blogily theme by Superb
Cookie-Zustimmung verwalten
Wir verwenden Technologien wie Cookies, um Geräteinformationen zu speichern und/oder darauf zuzugreifen. Wir tun dies, um das Surferlebnis zu verbessern und um personalisierte Werbung anzuzeigen. Wenn Sie diesen Technologien zustimmen, können wir Daten wie das Surfverhalten oder eindeutige IDs auf dieser Website verarbeiten. Wenn Sie Ihre Zustimmung nicht erteilen oder zurückziehen, können bestimmte Funktionen beeinträchtigt werden.
Funktional Immer aktiv
Die technische Speicherung oder der Zugang ist unbedingt erforderlich für den rechtmäßigen Zweck, die Nutzung eines bestimmten Dienstes zu ermöglichen, der vom Teilnehmer oder Nutzer ausdrücklich gewünscht wird, oder für den alleinigen Zweck, die Übertragung einer Nachricht über ein elektronisches Kommunikationsnetz durchzuführen.
Vorlieben
Die technische Speicherung oder der Zugriff ist für den rechtmäßigen Zweck der Speicherung von Präferenzen erforderlich, die nicht vom Abonnenten oder Benutzer angefordert wurden.
Statistiken
Die technische Speicherung oder der Zugriff, der ausschließlich zu statistischen Zwecken erfolgt. Die technische Speicherung oder der Zugriff, der ausschließlich zu anonymen statistischen Zwecken verwendet wird. Ohne eine Vorladung, die freiwillige Zustimmung deines Internetdienstanbieters oder zusätzliche Aufzeichnungen von Dritten können die zu diesem Zweck gespeicherten oder abgerufenen Informationen allein in der Regel nicht dazu verwendet werden, dich zu identifizieren.
Marketing
Die technische Speicherung oder der Zugriff ist erforderlich, um Nutzerprofile zu erstellen, um Werbung zu versenden oder um den Nutzer auf einer Website oder über mehrere Websites hinweg zu ähnlichen Marketingzwecken zu verfolgen.
  • Optionen verwalten
  • Dienste verwalten
  • Verwalten von {vendor_count}-Lieferanten
  • Lese mehr über diese Zwecke
Einstellungen anzeigen
  • {title}
  • {title}
  • {title}