DS1307 RTC am Raspberry Pi

Aus cryCode Wiki
Wechseln zu: Navigation, Suche

Eine Echtzeituhr (realtimeclock) misst die physikalische Uhrzeit. Sie hat einen Quarz der den Takt der Uhr vorgibt und einen Chip, der daraus sie aktuelle Uhrzeit berechnet.

Normalerweise wird die aktuelle Uhrzeit des Raspberry Pi über das Internet via ntp synchronisiert. Wenn jedoch kein Netzwerk zur Verfügung steht und man eine aktuelle Uhrzeit benötigt greift man zu einer RTC.


Der hier verwendete Chip DS1307 wird über den I2C-Bus mit dem Raspberry Pi verbunden.

Über eine Batterie (z.B. CR2032) wird die Stromversorgung des DS1307 gepuffert, sodass die interne Uhr auch weiter läuft, wenn die normale Stromversorgung weg fällt.


Bauteile

Benötigt werden neben dem Raspberry Pi:

  • DS1307 RTC
  • Quarz mit 32,768 kHz
  • Batterie (mit Halter), z.B. CR2032


Anschluss

Der Anschluss an den Raspberry Pi erfolgt nach folgender Schaltung:

Pi DS1307.png

Zu beachten ist hierbei, dass der Quarz so nahe wie möglich an den Pins 1 und 2 des DS1307 sein sollte. Wird dies nicht beachtet ergeben sich Ungenauigkeiten in der Uhr.


Software

Der I2C-Bus muss auf dem Raspberry Pi aktiviert/eingerichtet sein.

Wenn alles richtig angeschlossen ist sollte bei einem i2cdetect der DS1307 mit der Adresse 0x68 angezeigt werden:

pi@raspi ~ $ i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --

Hinweis: Wenn das Kernel-Modul für den DS1307 bereits aktiviert ist, dann wird anstelle der 68 hier UU angezeigt. Die beutetet, dass es funktioniert!


Aktivieren des Kernel-Moduls

Aktuelle Raspbian-Versionen bringen des benötigte Kernel-Modul rtc-ds1307 schon von hause aus mit und wir müssen es nur noch aktivieren.

pi@raspi ~ $ sudo modprobe rtc-ds1307

Hat dies ohne Fehler geklappt können wir das Modul in die Datei /etc/modules eintragen, damit es in Zukunft beim Systemstart automatisch geladen wird.

pi@raspi ~ $ echo "rtc-ds1307" | sudo tee -a /etc/modules
rtc-ds1307
pi@raspi ~ $ cat /etc/modules
snd-bcm2835
i2c_bcm2708
i2c-dev
rtc-ds1307


Uhr im System einbinden

Damit die RTC vom System verwendet werden kann müssen wir den DS1307 als Device definieren:

pi@raspi ~ $ echo ds1307 0x68 | sudo tee /sys/class/i2c-adapter/i2c-1/new_device

Anschließend können wir die Uhrzeit der RTC mit Hilfe von hwclock auslesen und mit der aktuellen Uhrzeit des Pi vergleichen:

pi@raspi ~ $ sudo hwclock -r && date
Mo 08 Feb 2016 10:05:23 CET  -0.887520 seconds
Mo 8. Feb 10:05:23 CET 2016

Wurde in dem DS1307 noch keine Zeit gesetzt, dann wird der 01. Januar 2000 zurückgegeben.

Die aktuelle Uhrzeit des Raspberry Pi in die RTC schreiben ist ebenso einfach:

pi@raspi ~ $ sudo hwclock -w

Die Uhrzeit der RTC als Systemzeit übernehmen:

pi@raspi ~ $ sudo hwclock -s


Damit bei einem (Neu-)Start des Raspberry Pi die Uhrzeit automatisch von der RTC gelesen werden kann, fügen wir in der Datei /etc/rc.local das Erzeugen des Devices vor exit 0 hinzu:

pi@raspi ~ $ sudo sed -s -i.bak 's/^exit 0$/# RTC DS1307\necho ds1307 0x68 > \/sys\/class\/i2c-adapter\/i2c-1\/new_device\n\nexit 0/' /etc/rc.local
pi@raspi ~ $ tail /etc/rc.local # Ergebnis ansehen
# [...]
# RTC DS1307
echo ds1307 0x68 > /sys/class/i2c-adapter/i2c-1/new_device

exit 0
pi@raspi ~ $ sudo rm /etc/rc.local.bak # Backup von 'sed' löschen

Den Rest übernehmen dann die udev-Regeln, genauer gesagt /lib/udev/rules.d/85-hwclock.rules bzw. /lib/udev/hwclock-set.

Falsche Uhrzeit nach Neustart

Auf manchen Systemen kann es vorkommen, dass nach einem Neustart die Uhrzeit falsch, bzw. die vom letzten Herunterfahren ist.

In diesem Fall wird die hwclock nicht richtig initialisiert und beim Booten überschreibt die fake-hwclock des Pi die Uhrzeit in der echten hwclock.

Nach einigen Tests zeigte sich die folgende Lösung als funktionierend:

In der Datei /lib/udev/hwclock-set müssen die Zeilen

if [ -e /run/systemd/system ] ; then
    exit 0
fi

auskommentiert werden, sodass es dann so aussieht:

#if [ -e /run/systemd/system ] ; then
#    exit 0
#fi

Anschließend sollte die Uhrzeit dann bei einem (Neu-) Start richtig aus der RTC übernommen werden.


Testen

Um die RTC zu testen fahren wir unseren Raspberry Pi herunter und trennen die Stromversorgung, sowie alle möglichen Netzwerkverbindungen.

Nun starten wir den Pi wieder (ohne Netzwerk!) und prüfen anschließend die Uhrzeit der RTC und die Systemzeit:

pi@raspi ~ $ sudo hwclock -r && date
Mo 08 Feb 2016 10:25:25 CET  -0.874667 seconds
Mo 8. Feb 10:25:25 CET 2016