Gruino : Ajout d’une horloge RTC

Salut à  tous,

Aujourd’hui je vais vous expliquer comment apprendre maintenant à  votre carte Arduino à  connaitre l’heure et la date ! Ce qui peut s’avérer très pratique pour faire un minuteur ou une action à  des heures régulières.Pour cela nous allons utiliser un petit montage appelé horloge RTC pour Real Time Clock ou pour les non anglophones Horloge Temps Réel. Ces petits montages munis d’une pile sont autonome et fournisse l’heure de manière relativement précise.

Vous allez me dire oui mais pourquoi ne pas directement demander à  Arduino de   compter les secondes pour savoir se situer dans le temps ?

Tout simplement car en cas de coupure de courant Arduino sera perdu et recommencera à  Zero. Tandis qu’avec ce petit montage Arduino n’aura qu’a demandé l’heure comme à  son habitude au module et saura ainsi la date et l’heure.

Pour mon projet Gruino j’ai décidé d’utiliser une horloge basé sur un composant DS1307. La platine toute prête coute entre 3 et 7€ environ et est fourni ou non avec sa pile de sauvegarde. Il est tout petit (à  peu près la taille d’une pièce de 1€) et très simple à  utiliser.

Vola la bête :

IMG_4904 IMG_4907 IMG_4908Vous remarquerez les 4 fils qui « sorte » du module, j’ai du les souder moi même car sur le module que j’ai commandé il n’y avait pas de barrette pour enficher les fils sans soudure. Vous l’aurez compris il n’y a donc besoin que de 4 fils :

+5V
La masse
SDA
SCL

Pour le branchement c’est simple :

Le 5v et la masse pour alimenter le module

Le SCL et SDA respectivement sur les broches A5 et A4 de votre Arduino pour la communication avec l’horloge via le protocole I2C. I2C est un protocole série qui m’est encore inconnue, j’ai donc utilisé une librairie toute faite pour interroger l’horloge que nous verrons plus loin.

La programmation :

Pour ce qui est du code c’est très simple aussi, grâce à  une librairie encore fourni par le site Adafruit qui fonctionne très bien et qui est plutôt intuitive. Cette librairie appelée RTCLib est téléchargeable ici : https://github.com/adafruit/RTClib

Pour commencer on va inclure deux bibliothèque, la RTCLib et wire (incluse avec le logiciel Arduino) :

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

Ensuite on va ajouter les divers initialisation juste en dessous :

RTC_DS1307 rtc;

Dans la fonction setup() on va mettre les instruction suivante pour démarrer le module RTC :

#ifdef AVR
   Wire.begin();
#else
   Wire1.begin(); // Shield I2C pins connect to alt I2C bus on Arduino Due
#endif
   rtc.begin();

Puis, toujours dans la fonction setup() on va ajouter la condition suivante qui permet d’initialiser l’heure au premier démarrage du module :

   if (! rtc.isrunning()) {
       rtc.adjust(DateTime(__DATE__, __TIME__));
   }

Le souci avec la ligne rtc.adjust(DateTime(__DATE__, __TIME__)); c’est qu’elle prends les variable DATE et TIME du pc au moment de la compilation, donc pour que l’heure soit réglée au plus juste il vous faudra cliquer sur téléverser pour ne pas prendre de retard.

Si vous avez un souci d’heure il vous suffit de forcer cette fonction. Pour ma part quand ça m’est arrivé pendant les premiers tests j’ai juste déplacé la fonction dans le setup pour forcer le programme à  passer dessus. Je l’ai ensuite supprimé pour ne pas avoir de problèmes lors des auto reset de la carte quand on se connecte via la liaison série 🙂

Pour lire l’heure maintenant :

Il vous suffira d’appeler dans votre fonction le code suivant :

DateTime now = rtc.now();
 Serial.print(now.hour());
 Serial.print(':');
 Serial.print(now.minute());
 Serial.print(':');
 Serial.print(now.second());
 Serial.println();

Pour lire l’heure et la renvoyer au format hh:mm:ss via la liaison série. Bien sur si vous voulez récupérer les info par la liaison série n’oubliez pas d’initialiser celle ci comme nous l’avons vu ici par exemple.

Voici maintenant le code complet du projet mis à  jour avec l’ajout de l’interrogation de l’heure par la liaison série justement :

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

#define DHTPIN 2             // pin connecté au DHT
#define DHTTYPE DHT22   // DHT 22 (AM2302)
#define LED_PIN 13         // pin connecté à  la led de test

DHT dht(DHTPIN, DHTTYPE);
RTC_DS1307 rtc;

float Temperature();
float Humidite();
void lire();
int LightLevel(int port);
int isLightOn(int port);

int plage_lampes[7][4];

void setup()
{
   pinMode(LED_PIN, OUTPUT);
   digitalWrite(LED_PIN, LOW);
   digitalWrite(RELAY_1_PIN,LOW);
   digitalWrite(RELAY_2_PIN,LOW);

#ifdef AVR
   Wire.begin();
#else
   Wire1.begin(); // Shield I2C pins connect to alt I2C bus on Arduino Due
#endif
   rtc.begin();

   Serial.begin(9600);
   dht.begin();

   if (! rtc.isrunning()) {
       Serial.println("RTC is NOT running!");
       rtc.adjust(DateTime(__DATE__, __TIME__));
   }

}

void loop()
{
  lire();
}

void lire()
{
   if(Serial.available() > 0)
   {
       switch(Serial.read())
       {
           case 'e':
               digitalWrite(LED_PIN, LOW);
               break;

           case 'm':
               digitalWrite(LED_PIN, HIGH);
               break;
           case 't':
               float t;
               t = Temperature();
               if(t != -99)
               {
                     Serial.println(t); 
               }
               else
               {
                   Serial.println("erreur de lecture du DHT");
               }
               break;
           case 'h':
               float h;
               h = Humidite();
               if(t != -99)
               {
                     Serial.println(h); 
               }
               else
               {
                   Serial.println("erreur de lecture du DHT");
               }
               break;
           case 'l':
               int l;
               l = LightLevel(0);
               Serial.println(l);
               break;
           case 'r':
               DateTime now = rtc.now();
               Serial.print(now.hour());
               Serial.print(':');
               Serial.print(now.minute());
               Serial.print(':');
               Serial.print(now.second());
               Serial.println();
               break;

       }
   }
}

/*****************************************************************
Détermine si la lumière est allumée ou éteinte. 
La réponse est binaire, cela peut permettre une réponse rapide 
en cas de manque de place dans le flux de données.
*****************************************************************/
int isLightOn(int port)
{
   int valeurLumiere=0;
   valeurLumiere = analogRead(port);
   if(valeurLumiere>500)
   {
         return 1; 
   }
   else
   {
         return 0; 
   }
}

/*****************************************************************
renvoie une quantité de lumière mesurée par la diode. 
Les valeurs vont de 0 à  1023 en fonction de la quantité de lumière
reçu.
*****************************************************************/
int LightLevel(int port)
{
   int valeurLumiere=0;
   valeurLumiere = analogRead(port);
   return valeurLumiere;
}

void DHTt()
{
   float h = dht.readHumidity();
   float t = dht.readTemperature();

   if (isnan(t) || isnan(h)) {
       Serial.println("Failed to read from DHT");
   } else {
       Serial.print("Humidity: ");
       Serial.print(h);
       Serial.print(" %t");
       Serial.print("Temperature: ");
       Serial.print(t);
       Serial.println(" *C"); 
   }
}

float Temperature()
{
   float t = dht.readTemperature();

   if (isnan(t)) 
   {
       return -99;
   } 
   else 
   {
       //Serial.print(t);
       return t;
   }
}

float Humidite()
{
   float h = dht.readHumidity();

   if (isnan(h)) 
   {
       return -99;
   } 
   else {
       return h;
   }

Voila, en espérant avoir été claire et avoir pu vous aider à  appréhender ces petites horloges fort pratique. A venir très bientôt un tuto pour piloter un Relai et faire un programmateur pour les lampes avec celui-ci couplé à  l’horloge DS1307 que nous venons de voir !

2 Commentaires

  1. Setreme

    Toutes mes félicitations pour ce tutoriel. J’ai hâte de poursuivre

    Répondre
    1. loizo (Auteur de l'article)

      Merci 🙂
      J’ai préparé un article sur la commande de carte relai par arduino qui est simple mais efficace 🙂 Il faut que je trouve un peu de temps pour l’illustrer et je le met en ligne ^^

      Répondre

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *