ADF-RTC-DS1307-UTILISER

De MCHobby - Wiki
Sauter à la navigation Sauter à la recherche


MCHobby investit du temps et de l'argent dans la réalisation de traduction et/ou documentation. C'est un travail long et fastidieux réalisé dans l'esprit Open-Source... donc gratuit et librement accessible.
SI vous aimez nos traductions et documentations ALORS aidez nous à en produire plus en achetant vos produits chez MCHobby.

Librairie Arduino

N'importe quel microcontroleur 5V supportant I2C peut facilement utiliser le DS1307. Cette page montrera comment l'utiliser avec un Arduino puisqu'il s'agit d'un microcontroleur vraiment très populaire.

Pour la librairie RTC, AdaFruit à utilisé un dérivé (fork) de l'excellente librairie RTC produit par JeeLab - téléchargement de RTClib ici.

RTCLib est une librairie permettant de lire l'heure du DS1307 ou PCF8523 mais aussi de la modifier :-) . Cette librairie initialement écrite par JeeLab à été modifiée par AdaFruit pour répondre à ses besoin... il est donc préférable d'utiliser la librairie proposée ci-dessus pour assurer une totale compatibilité.

Télécharger l'archive Zip en cliquant sur le lient Download Source (en haut à droite) et renommer le répertoire décompressé "RTClib" pour ensuite l'installer dans le répertoire des librairie Arduino (dans un répertoire nommé RTCLib).

Branchement

Que vous utilisez une horloge DS1307 ou PCF8523 les raccordements sont identiques.

Il y a seulement 5 broches/pins à raccorder: 5V, GND, SCL, SDA, SQW.

  • 5V est utilisé pour alimenter le circuit intégré du RTC quand vous avez besoin de dialoguer avec lui (par exemple: pour demander l'heure). S'il n'y a pas d'alimentation 5V alors le C.I. passe en mode veille et utilise la pile bouton comme alimentation de secour.
  • GND est la masse commune et son raccordement est obligatoire
  • SCL est le signal d'horloge (clock) du bus I2C - il est nécessaire pour dialoguer avec le RTC.
  • SDA est le signal de donnée (data) du bis I2C - il est également nécessaire pour dialoguer avec le RTC
  • SQW est une broche optionnel. Sortie d'une onde carrée (square-wave output) que vous pouvez obtenir du module RTC si vous l'avez configuré pour qu'il le produise. La plupart des utilisateur n'ont pas besoin de cette broche et ne l'utilise pas.

{{{2}}}
Crédit: AdaFruit Industries www.adafruit.com

Truc et astuce: Avec le branchement ci-dessous, il est possible d'alimenter le module RTC directement depuis les broches analogiques en utilisant la configuration suivante:

  • Placer la broche analogique 3 (digitale 17) sur OUTPUT et au niveau logique HIGH (haut)
  • Placer la broche analogique 2 (digitale 16) sur OUTPUT et niveau logique LOW (bas)

{{{2}}}
Crédit: AdaFruit Industries www.adafruit.com

Premier test RTC

La première chose que nous allons réaliser avec ce sketch de démonstration, c'est de lire l'heure depuis le module RTC une fois toutes les secondes.

Nous allons aussi voir ce qu'il arrive lorsque nous retirons et remplaçons la pile... cette opération interrompant le fonctionnement du RTC.

Donc, pour commencer, retirez la pile du son emplacement pendant qu'Arduino n'est pas alimenté (ou raccordé via USB). Attendez 3 secondes et ensuite, replacez la pile. Cela fait une remise-à-zéro (reset) du circuit RTC.

Maintenant ouvrez le sketch suivant sur votre Arduino.

L'exemple à charger dépend de l'horloge RTC présent sur la carte:

  • Horloge à base de DS1307: Examples->RTClib->ds1307
  • Horloge à base de PCF8523: Examples->RTClib->pcf8523

Puis compilez et téléchargez le sur votre Arduino avec breakout DS1307 branché OU votre shield Datalogger raccordé.

// fonctions Date et heure en utilisant 
// le RTC DS1307 RTC via bus I2C et librairie Wire

#include <Wire.h>
#include "RTClib.h"

# RTC_DS1307 ou RTC_PCF8523 en fonction du module utilsé
RTC_DS1307 RTC;

void setup () {
    Serial.begin(57600);
    Wire.begin();
    RTC.begin();

  if (! RTC.isrunning()) {
    Serial.println("RTC n est pas en cours de fonctionnement!");
    // La ligne suivante fixe la date et l'heure du RTC avec les date et heur de compilation du sketch
    //RTC.adjust(DateTime(__DATE__, __TIME__));
  }

}

void loop () {
    DateTime now = RTC.now();
    
    Serial.print(now.year(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.day(), DEC);
    Serial.print(' ');
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();
    
    Serial.print(" since 1970 = ");
    Serial.print(now.unixtime());
    Serial.print("s = ");
    Serial.print(now.unixtime() / 86400L);
    Serial.println("d");
    
    // Calcule une date dans le future, date ayant
    // 7 jours et 30 secondes de plus
    DateTime future (now.get() + 7 * 86400L + 30);
    
    Serial.print(" maintenant + 7d + 30s: ");
    Serial.print(future.year(), DEC);
    Serial.print('/');
    Serial.print(future.month(), DEC);
    Serial.print('/');
    Serial.print(future.day(), DEC);
    Serial.print(' ');
    Serial.print(future.hour(), DEC);
    Serial.print(':');
    Serial.print(future.minute(), DEC);
    Serial.print(':');
    Serial.print(future.second(), DEC);
    Serial.println();
    
    Serial.println();
    delay(3000);
}

Démarrer le moniteur série et assurez vous qu'il soit bien configuré sur un débit de 57600 bauds.

Vous devriez voir les messages suivants:

{{{2}}}
Crédit: AdaFruit Industries www.adafruit.com

A chaque fois que le composant RTC perd toutes ses sources d'alimentation (incluant donc la pile de secours) l'heure repasse à 0:0:0 et ne recommence pas à compter les secondes (c'est à l'arrêt).

A chaque fois que vous initialisez l'heure, le RTC commence immédiatement à égrainer le temps.

La règle fondamentale à retenir est donc qu'il ne faut au grand jamais retirer la pile un fois que l'heure est initialisée dans le module RTC. Vous ne devriez jamais avoir la pile qui tombe hors de sont emplacement (la carte et le support de pile sont prévus pour que cela n'arrive pas... a moins que la carte ne soit littéralement "écrasée").

Fixer l'heure

Avec le même sketch, vous pouvez decommenter la ligne qui commence avec RTC.adjust (comme ci-dessous):

// La ligne suivante initialise la date du RTC avec la 
// date et heure de compilation du sketch
RTC.adjust(DateTime(__DATE__, __TIME__));

Cette ligne est vraiment courte. Ce qu'elle fait, c'est qu'elle utilise la date et l'heure de votre ordinateur (pour être précis, au moment de la compilation du scketch) et l'utilise pour programmer le module RTC. Si l'heure de votre ordinateur n'est pas correcte, il faut la corriger avant de compiler le sketch. Ensuite, vous pouvez presser le bouton "Upload" pour compiler et charger le programme directement sur votre Arduino. Si vous compilez et chargez le programme en deux opérations, alors l'horloge RTC aura du retard (le temps que vous aurez perdu pour cliquer de l'un à l'autre).

Ensuite, ouvrez le moniteur série pour constater que l'heure est bien initialisée.

{{{2}}}
Crédit: AdaFruit Industries www.adafruit.com

A partir de maintenant, vous n'aurez plus besoin d'initialiser le temps. La pile devrait suffire pour maintenir la date et l'heure pendant 5 ans ou plus.

Lire l'heure

Maintenant que le RTC égraine le temps, nous allons l'utiliser pour récupérer l'heure. Retournons à notre sketch pour voir comment c'est fait

void loop () {
    DateTime now = RTC.now();
    
    Serial.print(now.year(), DEC);   // Affichage ANNEE
    Serial.print('/');
    Serial.print(now.month(), DEC);  // Affichage MOIS
    Serial.print('/');
    Serial.print(now.day(), DEC);    // Affichage JOUR
    Serial.print(' ');
    Serial.print(now.hour(), DEC);   // Affichage HEURES
    Serial.print(':');
    Serial.print(now.minute(), DEC); // Affichage MINUTES
    Serial.print(':');
    Serial.print(now.second(), DEC); // Affichage SECONDES
    Serial.println();

Il n'y a qu'une seule façon d'obtenir l'heure avec RTCLib, c'est d'appeler now(), une fonction qui retourne un objet DateTime qui contient/décrit l'année (year), le mois (month), le jour (day), l'heure (hour), les minutes (minute) et secondes (second) au moment de l'appel de now().

Ne pas tomber dans le piège de simplicité

Il existe des librairie RTC qui permettent d'obtenir les différentes informations par l'intermédiaire de différentes fonctions "plus directes". Vous pouvez donc faire des appels comme RTC.year() et RTC.hour() pour obtenir l'année courant et l'heure courante.

Cependant, il y a un problème si vous êtes sur le point de demander les minutes juste au moment où il est 3:14:59 et que la prochaines minute prend place. Donc vous lisez les minutes (soit 14 pour 3:14:59), le RTC égraine la prochaine seconde et il est maintenant 3:15:00 et votre programme lit les secondes (soit 00 pour 3:15:00).

Résultat, le programme à lut 14 minutes et 0 secondes alors qu'il était 3:14:59... pire, si l'on interprète les deux valeurs obtenue il serait x:14:00 alors qu'il est en fait x:14:59. Il y a a donc une erreur d'une minute.

Et en utilisant les fonctions dans l'autre sens (lecture des secondes avant les minute), cette fois nous pourrions avoir une minute d'avance et obtenir 3:15:59 alors qu'il est 3:14:59.

Utiliser l'approche cohérente

Pour poursuivre le point précédent, une mauvaise méthode d'acquisition du temps risque d'introduire des erreurs récurrentes dans votre projet... surtout si vous lisez souvent l'heure depuis le module RTC.

Une approche beaucoup plus fiable et offrant un résultat cohérent consiste a "capturer une copie de l'heure" du RTC en une seule opération. Ensuite, cette copie étant figée, vous pouvez en extraire les différents éléments (jour, mois, minutes, secondes...) sans le risque de voir une incohérence apparaître.

C'est exactement ce qui à été fait dans l'exemple précédent lorsque nous avons exécuté les lignes suivantes:

    DateTime now = RTC.now(); // Faire un copie 'figée' de l'heure du RTC
    
    Serial.print(now.year(), DEC);   // Affichage ANNEE - extraire l'information de la copie figée
    Serial.print('/');
    Serial.print(now.month(), DEC);  // Affichage MOIS - extraire l'information de la copie figée
    Serial.print('/');

Cela représente un peu plus d'effort mais cela nous met également à l'abri des erreurs :-) !

Timestamp

"Timestamp" est un terme fort répandu en informatique... nous le traduirions par "Horodatage".

Dans le monde informatique, 'TimeStamp' à surtout la particularité d'avoir une valeur unique (de préférence sous forme de valeur numerique) à/pour chaque instant.

Il est également possible d'obtenir un 'TimeStamp' depuis l'objet DateTime en appelant la fonction get. Get retourne le nombre de secondes écoulées (en totalité) depuis le premier janvier 2000 à minuit.

    Serial.print(" depuis 1 jan. 2000 = ");
    Serial.print(now.get());
    Serial.print("secondes = ");
    Serial.print(now.get() / 86400L);
    Serial.println(" jours");

Evaluer le temps qui passe

Puisqu'il y a 60*60*24 = 86400 secondes dans un jours, nous pouvons facilement compter le nombre de jours (aussi).

Cela peut être particulièrement utile pour savoir combien de temps a passé:

  • entre les deux fois où un événement particulier s'est produit.
  • depuis la dernière fois que le avons interrogé un capteur (ou sous-système).

Rendant les chose plus facile dans de nombreux cas.

Par exemple, pour savoir si 5 minutes sont passées, il suffit d'attendre que la différence entre l'appel initial de get() et notre appel de vérification soit soit plus grand de 300 (=5 min * 60 secondes)... même pas besoin de vérifier les changements d'heures.

// Attendre 5 minutes pour envoyer un message.
// Comme loop est exécuté constamment, le message sera envoyé toutes les 5 minutes
function loop() {
   DateTime depart = RTC.now();
   DateTime maintenant = RTC.now();
   while( (maintenant.get() - depart.get()) < 300 ) {
     maintenant = RTC.now(); // Re-capturer l'heure
   }
   Serial.println( "5 minutes viennent de passer" );
}

Source: DS1307 Real Time Clock Breakout Board Kit. Ecrit par Tyler Cooper pour AdaFruit. Crédit AdaFruit Industries

Traduit par Meurisse D. pour MCHobby.be

Traduit avec l'autorisation d'AdaFruit Industries - Translated with the permission from Adafruit Industries - www.adafruit.com

Toute référence, mention ou extrait de cette traduction doit être explicitement accompagné du texte suivant : «  Traduction par MCHobby (www.MCHobby.be) - Vente de kit et composants » avec un lien vers la source (donc cette page) et ce quelque soit le média utilisé.

L'utilisation commercial de la traduction (texte) et/ou réalisation, même partielle, pourrait être soumis à redevance. Dans tous les cas de figures, vous devez également obtenir l'accord du(des) détenteur initial des droits. Celui de MC Hobby s'arrêtant au travail de traduction proprement dit.