Modifications

Sauter à la navigation Sauter à la recherche
11 669 octets ajoutés ,  8 février 2018 à 19:14
Ligne 2 : Ligne 2 :     
== Librairie Arduino ==
 
== Librairie Arduino ==
Any 5V microcontroller with I2C built-in can easily use the DS1307. We will demonstrate how to use it with an Arduino since it is a popular microcontroller platform.
+
La RTC est un périphérique I2C, ce qui signifie qu'il ne faut que 2 fils pour communiquer avec la RTC. Ces deux fils sont utilisés pour fixer l'heure ou l'extraire de la RTC. Sur un Arduino UNO, les broches I2C sont également raccordées sur les broches analogiques analogique A4 et A5.
   −
For the RTC library, we'll be using a fork of JeeLab's excellent RTC library [http://github.com/adafruit/RTClib RTClib] - a library for getting and setting time from a DS1307 (originally written by JeeLab, our version is slightly different so please only use ours to make sure its compatible!) - download the .zip by clicking on Download Source (top right) and rename the uncompressed folder RTClib Then install it in your Arduino directory in a folder called RTClib
+
N'importe quel microcontrôleur 5V supportant I2C peut facilement utiliser la RTC '''DS1307''' ou RTC '''PCF8523'''. Cette page montrera comment utiliser ces RTC avec Arduino (l'un des microcontrôleur très populaire).
   −
== Raccorder ==
+
Pour la librairie RTC, AdaFruit à utilisé un dérivé (fork) de l'excellente librairie RTC produit par JeeLab - [https://github.com/adafruit/RTClib téléchargement également disponible sur GitHub].
There are only 5 pins: 5V GND SCL SDA SQW.
     −
* '''5V''' is used to power to the RTC chip when you want to query it for the time. If there is no 5V signal, the chip goes to sleep using the coin cell for backup.
+
{{download-box|Téléchargez La bibliothèque RTC|https://github.com/adafruit/RTClib/archive/master.zip}}
* '''GND''' is common ground and is required
  −
* '''SCL''' is the i2c clock pin - its required to talk to the RTC
  −
* '''SDA''' is the i2c data pin - its required to talk to the RTC
  −
* '''SQW''' is the optional square-wave output you can get from the RTC if you have configured it to do so. Most people don't need or use this pin
     −
[[Fichier:ADF-RTC-DS1307-USE-01.jpg]]
+
[http://github.com/adafruit/RTClib RTCLib] est une librairie permettant de lire l'heure du '''DS1307''' ou '''PCF8523''' mais aussi de la modifier :-) .
 +
 
 +
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 [[Installation d'un librairie Arduino|l'installer dans le répertoire des librairie Arduino ]] (dans un répertoire nommé {{fname|repertoire_des_croquis_arduino/libraries/RTCLib/}} ).
 +
 
 +
Vérifiez que le répertoire RTClib contient les fichiers RTClib.cpp et RTClib.h
 +
 
 +
== 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
 +
 
 +
Sur une RTC DS1307:
 +
* '''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.
 +
 
 +
{{ADFImage|ADF-RTC-DS1307-USE-01.jpg}}
 +
 
 +
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)
 +
 
 +
{{ADFImage|ADF-RTC-DS1307-USE-02.jpg}}
 +
 
 +
== 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'''
 +
 
 +
{{ADFImage|ADF-RTC-DS1307-UTILISER-10.png}}
 +
 
 +
Puis compilez et téléchargez le sur votre Arduino avec breakout RTC branché OU votre shield Datalogger raccordé.
 +
 
 +
{{ambox|text=Vérifiez le nom du composant RTC Si vous avez un problème pour faire fonctionner l'exemple! Les puces RTC PCF8523 et DS1307 RTC ne sont pas identiques et ont des exemples séparés! }}
 +
 
 +
<syntaxhighlight lang="C">
 +
// fonctions Date et heure en utilisant
 +
// le RTC DS1307 RTC via bus I2C et librairie Wire
 +
 
 +
#include <Wire.h>
 +
#include "RTClib.h"
 +
 
 +
# Utiliser la classe RTC_DS1307 ou RTC_PCF8523 en
 +
# fonction du module RTC utilisé
 +
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);
 +
}
 +
</syntaxhighlight>
 +
 
 +
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:
 +
 
 +
{{ADFImage|ADF-RTC-DS1307-USE-03.jpg}}
 +
 
 +
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):
 +
 
 +
<nowiki>// La ligne suivante initialise la date du RTC avec la
 +
// date et heure de compilation du sketch
 +
RTC.adjust(DateTime(__DATE__, __TIME__));</nowiki>
 +
 
 +
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.
 +
 
 +
{{ADFImage|ADF-RTC-DS1307-USE-04.jpg}}
 +
 
 +
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
 +
 
 +
<nowiki>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();</nowiki>
 +
 
 +
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:
 +
 
 +
<nowiki>    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('/');</nowiki>
 +
 
 +
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.
 +
 
 +
<nowiki>    Serial.print(" depuis 1 jan. 2000 = ");
 +
    Serial.print(now.get());
 +
    Serial.print("secondes = ");
 +
    Serial.print(now.get() / 86400L);
 +
    Serial.println(" jours");</nowiki>
 +
 
 +
=== 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.
 +
 
 +
<nowiki>// 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" );
 +
}</nowiki>
    
{{ADF-RTC-DS1307-TRAILER}}
 
{{ADF-RTC-DS1307-TRAILER}}
29 837

modifications

Menu de navigation