ARDUINO – SD RTC SHIELD

pour toute les applications de sauvergarde et utilisation de données , il existe des shields comportant un lecteur de carte SD et une Horloge Temps Reel ( Real Time Clock). on retrouve ce type d’application sous la denomination commune de DataLogger . Nous développerons ici le principe sur la base du SD-RTC shiel Deek-Robot mais adafruit propose le même module .

avant de commencer et pour ceux parlant Anglais , ci dessous en téléchargement la notice complete PDF de la version Adafuit:

Le Bus SPI:

premier point important a savoir, la partie SD du shield utilise le BUS SPI , Un bus SPI est un bus série composé de quatre fils : deux fils de données (MOSI et MISO), un fil d’horloge (SCK) et un fil d’adressage (/CS =”Chip Select”) par périphérique utilisant le bus SPI.

Les trois premiers fils sont communs à tous les périphériques d’un même bus SPI. Le quatrième fil (/CS) est unique par périphérique et permet au maître de choisir avec quel périphérique il souhaite communiquer. il y aura autant de fil /CS différents que de périphériques utilisant le BUS SPI. les modules Deek-Robot et Adafruit utilisent les broches D11 (MOSI)- D12(MISO)- D13 (SCK) de l’ARDUINO UNO pour le BUS SPI et normalement ( a verifier) la broche D10 pour le /CS ( voir paramétrage en rouge dans le premier exemple de programme ino proposé) , ces 4 broches sont donc indisponibles pour connecter des capteurs ou actionneurs.

si vous voulez utiliser en plus un shield Ethernet utilisant le Bus SPI , il faudra donc veiller a ce qu’il utilise une autre boche que la broche D10 pour activer la communication SPI.

La carte SD:

deuxieme point crucial , il faudra bien entendu utiliser une carte SD mais en prenant en compte quelques précautions et limitations. Toutes les cartes SD ne sont pas compatibles avec les cartes Arduino. Cela est dû au fait que les cartes Arduino communiquent avec la carte SD via un bus SPI. La communication en mode SPI n’est pas la méthode classique de communication avec une carte SD. Ce mode un peu spécial est un héritage des toutes premières versions de cartes SD. ci dessous , quelques conseils qui aideront:

  • les cartes doivent etre compatible du protocole SPI
  • Les cartes SDXC ne sont PAS compatibles. De même que les cartes d’une capacité supérieure à 32Go.
  • Utiliser une carte SD max 32 Go formatée en FAT16 ou FAT32 .
  • utiliser de preference des cartes de teille maxi 2 a 8 Go
  • Les noms de fichiers devront être au standard MSDOS ( 8 caractères sans espace ni extension de plus de 3 caractères)
  • Utiliser de préférence des fichiers au format .CSV (Comma Separated Value ) , format texte  tabulaire qui permet la récupération directe sur Excel.
  • Les vieilles cartes SD de 128 ou 256 Mo récupérées sur d’anciens apareils font très bien l’affaire pour les projets arduino:

Exemples : 128 Mo permet de stocker 2 560 000 enregistrements de 50 caractères

Si un enregistrement toutes les 5 minutes => capacité pour 9 000 jours soit plus de 20 ans d’enregistrement de données …

La Fonction RTC :

pour utiliser la fonction Horloge Temps Réels (Real Time Clock) du SD shield , il faut impérativement mettre une pile ronde plate CR1220 dans le logement prévu a cet effet , ceci pour la sauvegarde jour/heure du RTC en cas de coupure de courant sur l’ARDUINO.

deuxieme point important a savoir, l’horloge Temps Réel utilise le bus I2C pour la communication avec l’ARDUINO UNO , ARDUINO utilise les broche A4 et A5 pour le bus I2C , ces 2 broches ne sont donc plus disponibles comme broches Analogiques .

Mise en Œuvre, exemples:

  • Plugger l’ensemble sur l’arduino UNO en prenant garde à l’alignement des broches.
exemple de shield SD sur Arduino UNO

a titre d’exemple d’utilisation , nous allons connecteur un capteur DHT11 ( voir rubrique dédiée) et enregistrer les données du capteur sur la carte SD .

pour ce test , j’ai utilisé une carte SD de 2 Go . première opération, vérifier que la carte SD est reconnue par l’ARDUINO. pour cela , nous allons ouvrir l’exemple “cardinfo” de la librairie SD:

avant de télé-verser le programme dans l’ARDUINO , il faut modifier la ligne qui permet de spécifier la broche /CS et remplacer par la bonne valeur ( 10 dans le cas des cartes ADAFRUIT et DEEK ROBOT ):

une fois televersé dans l’arduino, ouvrir le moniteur serie , et si tout se passes bien un message du genre ci dessous devrait s’afficher .

passons maintenant a un premier cas concret avec le DHT11

charger le programme ino ci dessous ( format ZIP car format ino interdit en telechargement par mesure de securité) et televersez le dans l’arduino avec le DHT11 branché comme ci dessuspuis ouvrir le moniteur serie.

#include <SPI.h>
#include <SD.h>
#include <dht_nonblocking.h>
const int chipSelect = 10;    // broche /CS utilisée par le shield
#define DHT_SENSOR_TYPE DHT_TYPE_11
//#define DHT_SENSOR_TYPE DHT_TYPE_21
//#define DHT_SENSOR_TYPE DHT_TYPE_22
static const int DHT_SENSOR_PIN = 2;
DHT_nonblocking dht_sensor( DHT_SENSOR_PIN, DHT_SENSOR_TYPE );

void setup() {
  Serial.begin(9600);
  while (!Serial) { ; // wait for serial port to connect. Needed for native USB port only
  }
  Serial.print("Initializing SD card...");  
  if (!SD.begin(chipSelect)) {    // see if the card is present and can be initialized:
    Serial.println("Card failed, or not present");    
    while (1);    // don't do anything more:
  }
  Serial.println("card initialized.");
}

static bool measure_environment( float *temperature, float *humidity ) {
static unsigned long measurement_timestamp = millis( );
if( millis( ) - measurement_timestamp > 3000ul )   {
        if( dht_sensor.measure( temperature, humidity ) == true )       {
           measurement_timestamp = millis( );
           return( true );
        }
    }
   return( false );
}

void loop() { 
   float temperature;
   float humidity;
   if( measure_environment( &temperature, &humidity ) == true )   {
      String dataString = String(temperature) + ";" + String(humidity) ;  // make a string for assembling the data to log: 
      File dataFile = SD.open("DHT11.csv", FILE_WRITE);  
      if (dataFile) {     // if the file is available, write to it:
          dataFile.println(dataString);
          dataFile.close();
          // print to the serial port too:
          Serial.println(dataString);
          Serial.print( "T = " );
          Serial.print( temperature, 1 );
          Serial.print( " deg. C, H = " );
          Serial.print( humidity, 1 );    
          Serial.println( "%" );
      }
      // if the file isn't open, pop up an error:
      else {
          Serial.println("error opening datalog.txt");
      }    

   }  
}

dans le moniteur série on a quelque chose comme ça:

debrancher l’ARDUINO de l’alimentation et mettre la carte SD dans un PC pour voir ce qui a été enregistré dans le fichier.

le deuxieme exemple de mise en pratique va utiliser l’Horodatage de façon a avoir date et heure de chaque donnée. pour cela , en préliminaire , il va faloir installer la bibliothequeRTC disponible ici:

https://github.com/adafruit/RTClib

une fois fait , charger le programme ci dessous dans l’IDE arduino et televersez le dans l’ARDUINO.

#include <SPI.h>
#include <SD.h>
#include <RTClib.h>   // horodatage
#include <Wire.h> // Pour la communication I2C horodateur
#include <dht_nonblocking.h>
const int chipSelect = 10;   // broche CS pour le bus SPI
#define DHT_SENSOR_TYPE DHT_TYPE_11
//#define DHT_SENSOR_TYPE DHT_TYPE_21
//#define DHT_SENSOR_TYPE DHT_TYPE_22
static const int DHT_SENSOR_PIN = 2;
DHT_nonblocking dht_sensor( DHT_SENSOR_PIN, DHT_SENSOR_TYPE );
RTC_DS1307 RTC;

void setup() {
  Serial.begin(9600);
  Wire.begin();
  RTC.begin();
  // following line sets the RTC to the date & time this sketch was compiled
  // RTC.adjust(DateTime(__DATE__, __TIME__));
  
  while (!Serial) { ; // wait for serial port to connect. Needed for native USB port only
  }
  Serial.print("Initializing SD card...");  
  if (!SD.begin(chipSelect)) {    // see if the card is present and can be initialized:
    Serial.println("Card failed, or not present");    
    while (1);    // don't do anything more:
  }
  Serial.println("card initialized.");
}

static bool measure_environment( float *temperature, float *humidity ) {
static unsigned long measurement_timestamp = millis( );
if( millis( ) - measurement_timestamp > 3000ul )   {
        if( dht_sensor.measure( temperature, humidity ) == true )       {
           measurement_timestamp = millis( );
           return( true );
        }
    }
   return( false );
}

void loop() { 
   float temperature;
   float humidity;
   if( measure_environment( &temperature, &humidity ) == true )   {
      File dataFile = SD.open("DHT11.csv", FILE_WRITE);  
      if (dataFile) {     // if the file is available, write to it:
          DateTime now = RTC.now();
          uint16_t year1 = now.year();
          uint16_t month1 = now.month();
          uint16_t day1 = now.day();
          uint16_t hour1 = now.hour();
          uint16_t minute1 = now.minute();
          uint16_t second1 = now.second();
          String dataReg = String(year1) + ";" + String( month1) + ";" + String(day1) +";" + String(hour1) + ";" + String(minute1) + ";" + String(temperature) + ";" + String(humidity) ; 
          dataFile.println(dataReg);
          dataFile.close();
          // print to the serial port too:
          Serial.println(dataReg);
      }
      // if the file isn't open, pop up an error:
      else {
          Serial.println("error opening DHT11.csv");
      }  
   }  
}

l’affichage dans le moniteur serie donne ceci:

et si ensuite on ouvre le fichier de la carte SD avec un PC sous notepad et excel on a ceci.

cet exemple terminera ce tuto sur le principe d’utilisation d’un DATALOGGER shield.