Raspberry PI : Tiny RTC (Real Time Clock), horloge temps réel

Le Raspberry Pi ne possède pas d'horloge interne, lorsque celui ci est allumé il écrit régulièrement le temps dans un fichier. Au démarrage le système recharge le temps depuis ce fichier, histoire que le temps ne récule pas. Même si l'heure n'est pas bonne cela permet de ne pas avoir de timestamp dans le futur. L'utilisation d'une horloge temps réel n'est pas indispensable mais c'est quand même bien mieux avec. C'est le package fake-hwclock qui permet cela, sans ce package le Raspberry serait à chaque démarrage en 1970.

Ce type module Tiny RTC I²C sur base de DS1307 (1) est très facile à trouver pour quelques euros. Il faut savoir néanmoins qu'un module de ce type 'made in RPC' dérive un peu, dans les 4 secondes sur une journée. Il est possible suivant les constructeurs que la dérive soit plus ou moins importante (2). L'horloge temps réel n'empêche donc pas d'avoir une solution de mise à l'heure automatique (connexion Internet, GPS ou DCF77).




Avant de connecter ce module au Raspberry il est indispensable de procéder à une petite modification avec la suppression des résistances de pull-up R3 et R2 (en bas de l'image ci dessus) pour que la connexion au Raspberry sur le GPIO soit faite en 3,3V au lieu de 5V. Utiliser le module sans cette modification pourrait être dangereuse pour le Raspberry.

La connexion du Tiny RTC au port GPIO du Raspberry se fait avec 4 fils.

Tiny RTC / P1 Raspberry / GPIO
SDA Pin 3
SCL Pin 5
VCC Pin 2 (5V)
GND Pin 6

Les opérations suivantes ont été faites sur un Raspberry PI B+, pour la série A il est possible que certaines commandes soient différentes en ce qui concerne la gestion des devices sur le bus I²C.

Première action à mener lancer une mise à jour de la liste des packages. 

$ sudo aptitude update


Puis installer de quoi utiliser le bus I²C avec le package i2c-tools

$ sudo aptitude install i2c-tools


Modifier le fichier /etc/modprobe.d/raspi.blacklist.conf, commenter la ligne 'blacklist i2c-bcm2708' en ajoutant un # en début de ligne. Dans le cas où le fichier n'existe pas ne rien faire.

Ajouter au fichier /etc/modules les lignes suivantes :
i2c-bcm2708
i2c-dev
rtc-ds1307
Ajouter au fichier /boot/config.txt les lignes suivantes (kernel 3.18 et +)
device_tree=bcm2708-rpi-b-plus.dtb
dtparam=i2c_arm=on

Rebooter le Raspberry

$ sudo reboot


L'exécution des commandes suivantes demandent les droits root, pour cela éxecuter la commande :

$ sudo bash

Vérifier que le module Tiny RTC et plus particulièrement le DS1307 est bien détecté sur le bus I²C avec la commande :

# i2cdetect -y 1    # pour un Raspberry PI B

Il doit s'afficher un tableau comme celui-ci après, le DS1307 est bien présent à l'adresse 0x68.

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: 50 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --


A titre d'information le device présent à l'adresse 0x50 est l'IC ATMEL (EEPROM 32KB) présent sur le module Tiny RTC (composant U3). Ce composant est surtout utilisé dans les montages à base d'Arduino ou de PIC.

Activer le module avec la commande :

# echo ds1307 0x68 > /sys/class/i2c-adapter/i2c-1/new_device 

Vérifier que le système est bien à l'heure et à la bonne date avec la commande 'date' : 

# date
Sat Aug 15 22:08:49 CEST 2015

Puis initialiser l'horloge matérielle

# hwclock --systohc -D --noadjfile --utc

Il doit s'afficher diverses informations comme les suivantes :

hwclock from util-linux 2.20.1
Using /dev interface to clock.
Assuming hardware clock is kept in UTC time.
Time elapsed since reference time has been 0.172327 seconds.
Delaying further to reach the new time.
Setting Hardware Clock to 20:09:02 = 1439669342 seconds since 1969
ioctl(RTC_SET_TIME) was successful.


Tout est fonctionnel à ce stade, il faut maintenant activer le module au démarrage du Raspberry et au bon moment c'est à dire après l'activation du bus I²C et avant hwclock, pour cela créer un fichier /etc/init.d/rtcdev (3) avec les lignes suivantes :
#! /bin/sh

### BEGIN INIT INFO
# Provides: rtcdev
# Required-Start: kmod
# Required-Stop:
# X-Start-Before: hwclock
# X-Stop-After:
# Default-Start: S
# Default-Stop:
# Short-Description: creates RTC device
### END INIT INFO

. /lib/lsb/init-functions

case "$1" in
start)
if [ ! -e /dev/rtc0 ]; then
log_action_msg "Creating RTC device..."
echo ds1307 0x68 > /sys/class/i2c-adapter/i2c-1/new_device
fi
;;
restartreloadforce-reload)
echo "Error: argument '$1' not supported" >&2
exit 3
;;
stop)
# No-op
;;
*)
echo "Usage: $0 startstop" >&2
exit 3
;;

esac

exit 0
Puis lancer les commandes suivantes :

# chmod 755 /etc/init.d/rtcdev

# update-rc.d rtcdev defaults

# update-rc.d rtcdev enable



Maintenant que tout fonctionne il est possible de désactiver ou désinstaller le package fake-hwclock avec la commande suivante

$ sudo aptitude purge fake-hwclock
   
Voila c'est terminé, le module est fonctionnel, le Raspberry ne perdra pas son heure et sa date.

Fonctionnalités supplémentaires :
# Ce module offre également la possibilité de programmer des alarmes, par exemple pour réveiller une machine.

# Le PCB propose une emplacement pour ajouter un capteur de température DS18B20 (composant U1) le signal est récupérable sur la pin DS.

M.Lee & Michel Src, le 17/08/2015.


13/03/2016 : Pour une raison inexpliquée le Raspberry prend la date du 1er janvier 2066 (01/01/2066), malgré le RTC.

Ce souci n'est pas forcément visible si le Raspberry est connecté à internet et si le service ntp fait son travail. Je suis tombé sur ce problème en regardant le fichier syslog où il y avait uu saut de dates entre le boot et les messages après l'éxécution du service ntp.

Pour régler ce souci, il suffit de modifier le fichier /lib/udev/hwclock-set et remplacer

--systz par --hctosys

Vérifier que la date et l'heure du Raspberry sont bonnes et initisaliser la RTC :

$ sudo hwclock -w --debug

Vérifier que la RTC est bien à la bonne date et heure :

$ sudo hwclock -r --debug

Rebooter ou faire un arrêt / marche et vérifier le syslog.

Dans le cas où le souci est toujours présent, éxécuter les commandes suivantes :

$ sudo i2cdump -y -f -r 0-6 1 0x68 c

$ sudo i2cset -y -f 1 0x68 0x00

$ sudo hwclock -w -f /dev/rtc0

Rebooter ou faire un arrêt / marche et vérifier le syslog.


29/07/2018 : Pour informations en suivant cette procédure cela fonctionne sous Raspian Stretch (June 2018 / 2018.06.27 / Kernel 4.14.



Informations complémentaires :

(1) :
DS1307 Datasheet : http://datasheets.maximintegrated.com/en/ds/DS1307.pdf

(2) :
Application Note 58 : Crystal Considerations with Maxim Real-Time Clocks (RTCs) :
http://www.maximintegrated.com/en/app-notes/index.mvp/id/58


(3) : http://rayshobby.net/mediawiki/index.php/Real_Time_Clock_%28RTC%29_Set_up#3._Edit_.22.2Flib.2Fudev.2Fhwclock-set.22

RTC / Real Time Clock : https://en.wikipedia.org/wiki/Real-time_clock


> Sommaire Page créée le 17/08/2015, maj le 29/07/2018