2017-03-14
2017-05-15
 

Lors d'une tempête, nous avons été privés d'électricité pendant 18 heures. Une fois le courant rétabli, il y a eu un délai de trois jours avant que ne soit réinstauré le lien avec le câblo-diffuseur. Pendant cette période sans télévision, téléphone et, surtout, sans Internet une lacune du Raspberry Pi comme serveur domotique est devenue apparente. Puisque ce petit ordinateur n'a pas d'horloge matérielle et qu'il était impossible d'obtenir l'heure juste d'un serveur NTP sur le réseau, les planifications liées à des moments précis de la journée ne fonctionnaient plus correctement dans Domoticz. Au redémarrage, le code d'amorçage du Raspberry Pi avait fixé l'heure à une valeur par défaut, quelque chose comme midi le 1 septembre 1969, ne sachant ni l'heure ni la date actuelle.

La solution évidente était d'installer une horloge matérielle dite horloge temps réel (RTC ou « Real Time Clock » en anglais). L'horloge matérielle, munie d'une pile, est indépendante du système et fonctionne même lorsque l'ordinateur est éteint. J'ai ajouté un module DS3231 pour le Raspberry Pi qu'on trouve facilement chez des fournisseurs outre-mer.


Source : inconnue, ces photographies ont été « empruntées » de sites oubliés sur l'Internet.

Très bon marché, ce module a deux défauts. Premièrement, la pile est fixée de façon permanente et ne sera donc pas facilement remplacée. Deuxièmement, on perd accès à la broche 7 (GPIO4) du Raspberry Pi. Le module utilise le protocole I2C (ou I2C) avec les connexions SDA et SCL aux broches 3 et 5 respectivement du connecteur GPIO du Raspberry Pi. L'alimentation est obtenue des broches 1 (3,3V) et 9 (mise à terre). La broche 7 est recouverte par le connecteur du module sans être utilisée par ce dernier.

La photo ci-dessus montre comment brancher le module horloge au connecteur GPIO du Raspberry Pi. Ce ne pourrait difficilement être plus simple. Il faut cependant activer l'interface I2C utilisée par le module, ajouter une bibliothèque et prendre en charge le nouveau matériel au démarrage.

Activation de l'interface I2C

L'activation de l'interface est faite avec l'outil de configuration raspi-config. J'ai réalisé cette activation sur deux modèles du Raspberry Pi.

I) Activation de l'interface I2C sur un Raspberry Pi Modèle B+ v1.2 en mars 2017.

pi@rpi2b:~ $ sudo raspi-config ┌─────────┤ Raspberry Pi Software Configuration Tool (raspi-config) ├──────────┐ │ │ │ 1 Expand Filesystem Ensures that all of the SD card s │ │ 2 Change User Password Change password for the default u │ │ 3 Boot Options Configure options for start-up │ │ 4 Localisation Options Set up language and regional sett │ │ 5 Interfacing Options Configure connections to peripher │ │ 6 Overclock Configure overclocking for your P │ │ 7 Advanced Options Configure advanced settings │ │ 8 About raspi-config Information about this configurat │ │ │ │ <Select> <Finish> │ │ │ └──────────────────────────────────────────────────────────────────────────────┘ Choisir l'option 5. ┌─────────┤ Raspberry Pi Software Configuration Tool (raspi-config) ├──────────┐ │ │ │ P1 Camera Enable/Disable connection to the │ │ P2 SSH Enable/Disable remote command lin │ │ P3 VNC Enable/Disable graphical remote a │ │ P4 SPI Enable/Disable automatic loading │ │ P5 I2C Enable/Disable automatic loading │ │ P6 Serial Enable/Disable shell and kernel m │ │ P7 1-Wire Enable/Disable one-wire interface │ │ P8 Remote GPIO Enable/Disable remote access to G │ │ │ │ <Select> <Back> │ │ │ └──────────────────────────────────────────────────────────────────────────────┘ Choisir l'option P5. ┌─────────┤ Raspberry Pi Software Configuration Tool (raspi-config) ├──────────┐ │ │ │ 1 Expand Filesystem Ensures that all of the SD card s │ │ 2 Change User Password Change password for the default u │ │ 3 Boot Options Configure options for start-up │ │ 4 Localisation Options Set up language and regional sett │ │ 5 Interfacing Options Configure connections to peripher │ │ 6 Overclock Configure overclocking for your P │ │ 7 Advanced Options Configure advanced settings │ │ 8 About raspi-config Information about this configurat │ │ │ │ <Select> <Finish> │ │ │ └──────────────────────────────────────────────────────────────────────────────┘ Si ce n'est pas déja fait, choisir l'option 4 pour définir le fuseau horaire (time zone) local. ┌─────────┤ Raspberry Pi Software Configuration Tool (raspi-config) ├──────────┐ │ │ │ I1 Change Locale Set up language and regional sett │ │ I2 Change Timezone Set up timezone to match your loc │ │ I3 Change Keyboard Layout Set the keyboard layout to match │ │ I4 Change Wi-fi Country Set the legal channels used in yo │ │ │ │ <Select> <Back> │ │ │ └──────────────────────────────────────────────────────────────────────────────┘ Choisir l'option I2. La ville la plus proche de ma demeure est Moncton au Canada. J'ai donc sélectionné l'Amérique (America) comme zone géographique puis la ville. ┌─────────────────────────┤ Configuring tzdata ├──────────────────────────┐ │ Please select the geographic area in which you live. Subsequent │ │ configuration questions will narrow this down by presenting a list of │ │ cities, representing the time zones in which they are located. │ │ │ │ Geographic area: │ │ │ │ Africa │ │ America │ │ Antarctica │ │ Australia │ │ System V timezones │ │ US │ │ None of the above │ │ │ │ │ │ <Ok> <Cancel> │ │ │ └─────────────────────────────────────────────────────────────────────────┘ Package configuration ┌───────────────────────┤ Configuring tzdata ├───────────────────────┐ │ Please select the city or region corresponding to your time zone. │ │ │ │ Time zone: │ │ │ │ Jamaica │ │ Juneau ▒ │ │ Kentucky/Louisville ▒ │ │ Kentucky/Monticello ▒ │ │ Metlakatla ▒ │ │ Mexico_City ▒ │ │ Miquelon ▒ │ │ Moncton ▒ │ │ │ │ <Ok> <Cancel> │ │ │ └────────────────────────────────────────────────────────────────────┘ Current default time zone: 'America/Moncton' Local time is now: Fri Mar 24 13:28:34 ADT 2017. Universal Time is now: Fri Mar 24 16:28:34 UTC 2017. pi@rpi2b:~ $ date Fri 24 Mar 13:30:34 ADT 2017

II) Activation de l'interface I2C sur un Raspberry Pi 3 en mai 2017.

La procédure est essentiellement la même, il y a une petite différence dans l'écran de configuration initial.

pi@rpi2b:~ $ sudo raspi-config ┌─────────┤ Raspberry Pi Software Configuration Tool (raspi-config) ├──────────┐ │ │ │ 1 Change User Password Change password for the default u │ │ 2 Hostname Set the visible name for this Pi │ │ 3 Boot Options Configure options for start-up │ │ 4 Localisation Options Set up language and regional sett │ │ 5 Interfacing Options Configure connections to peripher │ │ 6 Overclock Configure overclocking for your P │ │ 7 Advanced Options Configure advanced settings │ │ 8 Update Update this tool to the latest ve │ │ 9 About raspi-config Information about this configurat │ │ │ │ <Select> <Finish> │ │ │ └──────────────────────────────────────────────────────────────────────────────┘ ┌─────────┤ Raspberry Pi Software Configuration Tool (raspi-config) ├──────────┐ │ │ │ P1 Camera Enable/Disable connection to the │ │ P2 SSH Enable/Disable remote command lin │ │ P3 VNC Enable/Disable graphical remote a │ │ P4 SPI Enable/Disable automatic loading │ │ P5 I2C Enable/Disable automatic loading │ │ P6 Serial Enable/Disable shell and kernel m │ │ P7 1-Wire Enable/Disable one-wire interface │ │ P8 Remote GPIO Enable/Disable remote access to G │ │ │ │ <Select> <Back> │ │ │ └──────────────────────────────────────────────────────────────────────────────┘ ┌──────────────────────────────────────────────────────────┐ │ │ │ Would you like the ARM I2C interface to be enabled? │ │ │ │ <Yes> <No> │ │ │ └──────────────────────────────────────────────────────────┘ ┌──────────────────────────────────────────────────────────┐ │ │ │ The ARM I2C interface is enabled │ │ │ │ <Ok> │ │ │ └──────────────────────────────────────────────────────────┘ Sélectionner le fuseau horaire si ce n'est pas déjà fait. C'est l'option 4. ┌─────────┤ Raspberry Pi Software Configuration Tool (raspi-config) ├──────────┐ │ │ │ 1 Change User Password Change password for the default u │ │ 2 Hostname Set the visible name for this Pi │ │ 3 Boot Options Configure options for start-up │ │ 4 Localisation Options Set up language and regional sett │ │ 5 Interfacing Options Configure connections to peripher │ │ 6 Overclock Configure overclocking for your P │ │ 7 Advanced Options Configure advanced settings │ │ 8 Update Update this tool to the latest ve │ │ 9 About raspi-config Information about this configurat │ │ │ │ <Select> <Finish> │ │ │ └──────────────────────────────────────────────────────────────────────────────┘ Choisir l'option I2. La ville la plus proche de ma demeure est Moncton au Canada. J'ai donc sélectionné l'Amérique (America) comme zone géographique puis la ville. ┌─────────┤ Raspberry Pi Software Configuration Tool (raspi-config) ├──────────┐ │ │ │ I1 Change Locale Set up language and regional sett │ │ I2 Change Timezone Set up timezone to match your loc │ │ I4 Change Wi-fi Country Set the legal channels used in yo │ │ │ │ <Select> <Back> │ │ │ └──────────────────────────────────────────────────────────────────────────────┘ Package configuration ┌─────────────────────────┤ Configuring tzdata ├──────────────────────────┐ │ Please select the geographic area in which you live. Subsequent │ │ configuration questions will narrow this down by presenting a list of │ │ cities, representing the time zones in which they are located. │ │ │ │ Geographic area: │ │ │ │ Africa │ │ America ▮ │ │ Antarctica ▒ │ │ Australia ▒ │ │ Arctic Ocean ▒ │ │ Asia ▒ │ │ Atlantic Ocean ▒ │ │ Europe │ │ │ │ <Ok> <Cancel> │ │ │ └─────────────────────────────────────────────────────────────────────────┘

Installation de la bibliothèque I2C

D'une manière formelle, nous installerons un pilote, python-smbus, pour le protocole System Management Bus qui gère un sous-ensemble du protocole I2C. "[Le] module Python permet l'accès SMBus via l'interface I2C/dev sur les hôtes Linux. Le noyau hôte doit posséder un support I2C, un support d'interface de périphérique I2C et un pilote d'adaptateur de bus. (ref)". Je ne suis pas trop sûr de ce que tout cela signifie, mais les commandements suivants fonctionnent :

pi@rpi2b:~ $ sudo apt-get update pi@rpi2b:~ $ sudo apt-get install -y python-smbus i2c-tools pi@rpi2b:~ $ sudo reboot

Vérification que l'interface I2C est activée.

pi@rpi2b:~ $ lsmod | grep i2c_ i2c_bcm2708 5740 0 i2c_dev 6578 0
Les valeur des deux dernière colonnes ne sont pas importantes. Nous ne faisons que vérifier que les deux services sont actifs.

À strictement parler, i2c-tools n'est pas obligatoire. Cependant les outils peuvent être utilisés pour vérifier la présence de périphériques I2C :

pi@rpi2b:~ $ sudo 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: -- -- -- -- -- -- -- --

Voilà qui confirme que l'horloge fonctionne et que son adresse est 0x68 ($68). Il se peut que UU s'affiche à la place du 68 dans le tableau. Cela veut dire que l'horloge matérielle fonctionne déjà. Evidemment, cette dernière doit être branchée au connecteur GPIO sinon rien ne sera détecté.

Si vous avez un Raspberry Pi original (avant octobre 2012) alors le port I2C est 0, pas 1, donc la commande précédente devrait être sudo i2cdetect -y 0.

Prise en charge du nouveau matériel

Il faut maintenant ajouter les modules appropriés au noyau Linux au démarrage. On le fait en ajoutant leur nom dans un fichier texte nommé modules dans le répertoire /etc. Il se peut que ce fichier n'existe pas ou qu'il est vide jusqu'ici :

pi@rpi2b:~ $ sudo nano /etc/modules
# /etc/modules: kernel modules to load at boot time. # # This file contains the names of kernel modules that should be loaded # at boot time, one per line. Lines beginning with "#" are ignored. i2c-dev rtc-ds1307

Ce n'est pas une erreur, le micrologiciel rtc-ds1307 fonctionne avec l'horloge DS3231 aussi bien qu'avec la puce plus ancienne qu'est la DS1307. Il reste à ajouter deux lignes dans le fichier rc.local qui seront exécutées au démarrage. La première ajoute le module ds1307 dans la liste des dispositifs I2C, la seconde met à jour la date et l'heure du système à partir de l'horloge temps réel.

pi@rpi2b:~ $ sudo nano /etc/rc.local
#!/bin/sh -e # # rc.local # # This script is executed at the end of each multiuser runlevel. # Make sure that the script will "exit 0" on success or any other # value on error. # # In order to enable or disable this script just change the execution # bits. # # By default this script does nothing. # Print the IP address #_IP=$(hostname -I) || true #if [ "$_IP" ]; then # printf "My IP address is %s\n" "$_IP" #fi echo ds1307 0x68 > /sys/class/i2c-adapter/i2c-1/new_device hwclock -s exit 0

Si au démarrage, il y a une erreur au sujet de echo dans rc.local, pour une question de permissions par exemple, alors essayez

pi@rpi2b:~ $ sudo apt-get update pi@rpi2b:~ $ sudo apt-get dist-upgrade

Cela a été nécessaire lorsque j'ai installé l'horloge sur le Raspberry Pi 3. C'est probablement parce que j'avais simplement copier la carte SD du Raspberry Pi modèle B+ puis fait un apt-get update et apt-get upgrade plutôt qu'installer le système d'exploitation directement.

hwclock

L'utilitaire hwclock est utilisé à la dernière ligne de rc.local pour synchroniser la date du système à partir de l'horloge matérielle. Avec cet utilitaire on peut

Afficher l'heure et la date actuelles de l'horloge matérielle
sudo hwclock [-r | --show]
Ce sont toujours l'heure et la date locales, en fonction du fuseau horaire du système, qui sont affichées.

Fixer l'heure et la date de l'horloge matérielle
sudo hwclock --set --date "29 Oct 1997 13:00"
Format : jj mmm aaaa hh:mm
jj est le jour du mois - 2 chiffres
mmm est le mois - 3 lettres
aaaa est l'année - 4 chiffres
hh est l'heure - 2 chiffres
mm est la minute - 2 chiffres. Il ne faut pas spécifier de secondes.
Ceci ne change pas l'heure et la date du système. On peut afficher les valeurs de ces paramètres système avec la commande date.

Copier l'heure et la date de l'horloge matérielle vers le système
sudo hwclock (-s | --hctosys)

Copier l'heure et la date du système vers l'horloge matérielle
sudo hwclock (-w | --systohc)

On doit être root pour accéder à l'horloge matérielle comme l'exemple suivant le démontre.

pi@rpi2b:~ $ hwclock hwclock: Cannot access the Hardware Clock via any known method. hwclock: Use the --debug option to see the details of our search for an access method. pi@rpi2b:~ $ sudo hwclock Mon 15 May 2017 19:38:06 ADT -0.656742 seconds

hwclock possède d'autres fonctionnalités; voir la page man pour plus d'information.

NTP et l'horloge matérielle

On peut mettre à jour l'heure et la date du système à partir du réseau avec le service ntpd. Lorsque ces paramètres systèmes sont à jour, on peut utiliser hwclock pour mettre à jour l'horloge matérielle comme expliqué ci-dessus.

pi@rpi2b:~ $ sudo ntpd -gq pi@rpi2b:~ $ sudo hwclock -w

Ce serait peut-être une bonne chose d'ajouter ces deux commandements à crontab pour exécution à intervalle régulier si l'horloge matérielle avait tendance à trop s'écarter de l'heure juste.

J'imagine que quelque chose comme ceci devrait fonctionner :

pi@rpi2b:~ $ crontab -e ... select the editor you want to use, the default is nano which has been used throught this guide.
# For more information see the manual pages of crontab(5) and cron(8) # # m h dom mon dow command 45 * * * * sudo ntpd -gq; sudo hwclock -w

Systématiquement, l'horloge matérielle sera mise à jour d'après l'heure et la date obtenu du réseau, quarante-cinq minutes après le début de chaque heure.

Références