J'avais alors fait remarquer qu'un shield tout fait était vendu par Adafruit, mais au prix de 14 USD, ça me semblait un luxe inutile.
Les temps ont bien changé. De nos jours, vous pouvez facilement trouver sur eBay des clones du Data Logging Shield conçu par Adafruit pour aussi peu que 3 USD (frais de port inclus).
Résultat: de nos jours, même pour un radin comme moi, il n'y a aucune raison de se priver d'un data logging shield prêt à l'utilisation.
Le shield comporte un lecteur de carte SD, une horloge temps réel et un convertisseur de niveau logique, en plus de deux LEDs que vous pouvez, au besoin, lier à la pin Arduino de votre choix. Il ne reste donc plus qu'à brancher les capteurs.
L'horloge
Pour que l'horloge temps réel DS1307 fonctionne correctement, il faut insérer une pile CR1220 (qui n'était pas fournie avec le shield que j'ai acheté). Cette horloge utilise le protocole i2c.
Pour utiliser l'horloge, vous devez installer la bibliothèque RTClib de Jeetlabs qui n'est généralement pas incluse avec l'IDE Arduino. Le sketch d'exemple "ds1307" fourni avec la bibliothèque vous permettra de vérifier que votre horloge fonctionne correctement (si elle n'affiche pas l'heure et la date correcte, exécutez l'exemple "ds1307" après avoir décommenté la ligne "RTC.adjust(DateTime(__DATE__, __TIME__));"
Le lecteur de cartes SD
Le lecteur de carte SD utilise quant à lui le protocole SPI. La bibliothèque SD est déjà installée par défaut avec l'IDE Arduino. Pour vous assurer que le lecteur fonctionne correctement, vous pouvez exécuter le sketch "CardInfo" fourni avec la bibliothèque SD...
...mais attention: dans ce sketch, vous devez modifier la constante "chipSelect" et lui assigner la valeur "10".
Les LEDs indicatrices
Le shield comporte également deux LEDs (L1 et L2) qui peuvent être connectées à n'importe quelle sortie de l'Arduino. Grâce à deux petits bouts de fil conducteur, j'ai relié la LED "L1" à la sortie 5 de l'Arduino, et la LED "L2" à la sortie 4 (un fer à souder est requis ici).
Ces LEDs peuvent être utilisées pour vous permettre de savoir si votre data logger fonctionne correctement lorsqu'il n'est pas connecté à un ordinateur (une LED peut s'allumer ou clignoter pendant que les mesures sont prises, une autre peut indiquer la fin de la prise de mesure, etc.).
Un exemple de sketch
Pour cet exemple de sketch, j'ai supposé la présence de deux capteurs analogiques branchés respectivement aux entrées A0 et A1 du shield. Il ne vous restera qu'à adapter le code pour qu'il gère les capteurs qui vous conviennent, peu importe qu'ils soient analogiques ou numériques.
Des mesures sont prises toutes les 10 secondes: il est facile de modifier cette fréquence, stockée dans la constante "DELAI_MESURES".
Chaque fois qu'une mesure est prise, elle est affichée dans le moniteur série, si ce dernier est actif (ce qui sera surtout utile pour vérifier le fonctionnement correct du dispositif). De plus (et surtout), elle est enregistrée dans un fichier "csv" ("comma separated values") qui pourra facilement être ouvert et traité avec un tableur comme, par exemple, Excel. Notez que j'utilise la convention qui permettra aux fichiers d'être correctement interprétée par la version française d'Excel: les données sont séparées par des points virgules plutôt que par des virgules.
La LED "L1" clignote pour indiquer que le data logger est en fonctionnement (si vous oubliez d'insérer une carte SD lors du démarrage du sketch, la LED ne s'allumera pas).
La LED "L2" s'allume temporairement chaque fois que le data logger effectue des mesures et les enregistre sur la carte SD.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/************************************************************ | |
Saisie de données (data logging) avec un Arduino | |
Matériel: Arduino Uno et Data Logging Shield (modèle mis au point par Adafruit) | |
Lecteur de carte SD (10-11-12-13) avec adapteur 5/3,3 V | |
Capteurs analogiques branchés à A0 et A1 | |
LEDs du Data Logging Shield branchées à D4 et D5 | |
http://electroniqueamateur.blogspot.ca/2016/10/utilisation-du-data-logging-shield.html | |
*************************************************************/ | |
// Les bibiothèques | |
#include <SD.h> // pour le lecteur de carte SD | |
#include <Wire.h> // pour l'horloge temps réel et capteurs i2C | |
#include <RTClib.h> // pour l'horloge temps réel | |
// Nombre de secondes entres chaque prise de mesure | |
#define DELAI_MESURES 10 | |
const int capteur1Pin = A0; // un premier capteur branché à A0 | |
const int capteur2Pin = A1; // un premier capteur branché à A1 | |
const int chipSelect = 10; // chipSelect de la carte SD à la pin 10 | |
const int LED1Pin = 5; // une LED branchée à D5 (clignote pendant que le DataLogger est en fonction) | |
const int LED2Pin = 4; // une LED branchée à D4 (s'allume temporairement pendant la prise de mesures) | |
RTC_DS1307 RTC; // objet Real Time Clock | |
DateTime now; | |
long tempsInitial = 0; // nombre de secondes entre le 1 jan 2000 et le début du script | |
long derniereMesure = 0; // moment de la plus récente prise de mesure | |
long dernierBlink = 0; // dernère fois qu'on a changé l'état de la LED clignotante | |
int etatLED = 0; | |
File logfile; //fichier | |
void error(char *str) | |
{ | |
Serial.print("Erreur: "); | |
Serial.println(str); | |
while (1); | |
} | |
void setup(void) | |
{ | |
// initialisation du moniteur série | |
Serial.begin(9600); | |
Serial.println(); | |
// initialisation de la carte SD | |
pinMode(10, OUTPUT); | |
// initialisation de la carte SD | |
if (!SD.begin(chipSelect)) { | |
error("echec de l'initialisation de la carte SD"); | |
} | |
Serial.println("Initialisation de la carte SD reussie."); | |
// Création d'un fichier | |
char filename[] = "Rappor00.csv"; | |
for (uint8_t i = 0; i < 100; i++) { | |
filename[6] = i / 10 + '0'; | |
filename[7] = i % 10 + '0'; | |
if (! SD.exists(filename)) { | |
logfile = SD.open(filename, FILE_WRITE); | |
break; | |
} | |
} | |
if (! logfile) { | |
error("echec de la creation du fichier"); | |
} | |
Serial.print("Nom du fichier: "); | |
Serial.println(filename); | |
// initialisation de l'horloge temps réel (RTC) | |
Wire.begin(); | |
RTC.begin(); | |
now = RTC.now(); | |
tempsInitial = now.get(); | |
derniereMesure = now.get() - DELAI_MESURES; | |
logfile.println("secondes;date;heure;mesure 1;mesure 2"); | |
Serial.println("secondes;date;heure;mesure 1;mesure 2"); | |
} | |
void loop(void) | |
{ | |
// on mesure les données pertinentes | |
now = RTC.now(); // quelle heure est-il? | |
long maintenant = now.get(); | |
//clignotement de la LED de fonctionnement normal | |
if ((maintenant - dernierBlink) >= 1) { // c'est le temps de changer l'état de la LED clignotante | |
etatLED = !etatLED; | |
digitalWrite(LED1Pin, etatLED); | |
dernierBlink = maintenant; | |
} | |
if ((now.get() - derniereMesure) < DELAI_MESURES) return; // on ne va pas plus loin si aucune mesure n'est nécessaire | |
derniereMesure = now.get(); | |
// on allume la LED indicatrice de mesure | |
digitalWrite(LED2Pin, HIGH); | |
int mesure1 = analogRead(capteur1Pin); | |
int mesure2 = analogRead(capteur2Pin); | |
// Écriture du fichier | |
logfile.print(now.get() - tempsInitial); // nombre de secondes depuis le début des mesures | |
logfile.print("; "); | |
if (now.day() < 10) logfile.print("0"); // date | |
logfile.print(now.day(), DEC); | |
logfile.print("-"); | |
if (now.month() < 10) logfile.print("0"); | |
logfile.print(now.month(), DEC); | |
logfile.print("-"); | |
logfile.print(now.year(), DEC); | |
logfile.print("; "); | |
if (now.hour() < 10) logfile.print("0"); // heure | |
logfile.print(now.hour(), DEC); | |
logfile.print(":"); | |
if (now.minute() < 10) logfile.print("0"); | |
logfile.print(now.minute(), DEC); | |
logfile.print(":"); | |
if (now.second() < 10) logfile.print("0"); | |
logfile.print(now.second(), DEC); | |
logfile.print("; "); | |
logfile.print(mesure1); // luminosite | |
logfile.print("; "); | |
logfile.print(mesure2); | |
logfile.println(); | |
// Écriture du moniteur série (utile pour le débogage, pas tellement pendant | |
// l'utilisation réelle. | |
Serial.print(now.get() - tempsInitial); // nombre de secondes depuis le début du sketch | |
Serial.print("; "); | |
if (now.day() < 10) Serial.print("0"); | |
Serial.print(now.day(), DEC); | |
Serial.print("-"); | |
if (now.month() < 10) Serial.print("0"); | |
Serial.print(now.month(), DEC); | |
Serial.print("-"); | |
Serial.print(now.year(), DEC); | |
Serial.print("; "); | |
if (now.hour() < 10) Serial.print("0"); | |
Serial.print(now.hour(), DEC); | |
Serial.print(":"); | |
if (now.minute() < 10) Serial.print("0"); | |
Serial.print(now.minute(), DEC); | |
Serial.print(":"); | |
if (now.second() < 10) Serial.print("0"); | |
Serial.print(now.second(), DEC); | |
Serial.print("; "); | |
Serial.print(mesure1); | |
Serial.print("; "); | |
Serial.print(mesure2); | |
Serial.println(); | |
logfile.flush(); | |
// on éteint la LED de mesure | |
digitalWrite(LED2Pin, LOW); | |
} | |
Voici ce qu'affiche le moniteur série pendant la prise de mesures:
Et voici le fichier "RAPPOR00.CSV" qui a été enregistré sur la carte SD, après ouverture dans Excel:
Les données peuvent ensuite être présentées sous forme de graphiques.
Yves Pelletier (Twitter, Facebook)