JCV Support Electronique
Age : 75 Localisation : France (Nord) Prénom : Jean-Claude Date d'inscription : 28/04/2008
| Sujet: Data Logger à base d'Arduino, plus test avec capteur de pression. Jeu 22 Oct 2015 - 11:31 | |
| Bonjour, Essai d'un module horloge plus carte SD de chez Adafruit, avec ajout d'un module carte capteur de pression BMP180. Autre utilisation possible: avec les convertisseurs A/D ou les entrées digitales de l'Arduino, ou tout autres type de capteurs (GPS, ECG, Température, Compteur de pas, Éolienne, Luxmètre, etc ...). Composants:- Carte Arduino Uno. - Carte Datalogging Adafruit (Horloge DS1307 + pile + Lecteur SD-card) - Capteur de pression BMP180 - Carte SD en FAT32 (ici 512Mo), taille possible jusque 32Go Le montage de test:Fonctionalités:Les commandes possible sur la liaison série: t : affiche la date et l'heure courante. p : affiche la pression atmosphérique en hPa w : ajoute une ligne dans le fichier log (date plus pression et température. r : lecture et affichage du contenu du fichier log Note: une ligne est ajouté automatiquement dans le fichier log chaque fois que la pression atmosphérique à changée. La lecture de la pression atmosphérique se fait en Pa, puis est moyennée, puis arondie à sa valeur la plus proche en hPa. Exemple d'affichage sur la console: - Code:
-
Data Logger Card v0.5 Initializing RTC ... Ok. Initializing SD card ... Ok Initializing BMP180 ... Ok
Writing to test.txt ... done
Exemple d'extrait du fichier de log:Date, Heure, n° enregistrement, pression en hPa, température en °C - Code:
-
2015/10/09 14:15:29 38 1020 23.0 2015/10/09 16:58:04 39 1019 22.9
Le code du programme: - Code:
-
/* Programme de test écriture / lecture sur SD card * Auteur: Jean-Claude Vandenhekke * 04/10/2015 v0.1 : Création du test. * 05/10/2015 v0.2 : Ajout de l'horloge RTC (déjà mise à l'heure) * Log avec date et heure dans le fichier. * prog: 17280 / 32256 octets, ram: 1375 / 2048 octets * 05/10/2015 v0.3 : Avec dialogue par liaison série, plus sync. * prog: 17930 / 32256 octets, ram: 1379 / 2048 octets * 07/10/2015 v0.4 : Ajout capteur de Pression BMP180. * Log des variations de pression. * prog: 21546 / 32256 octets, ram: 1469 / 2048 octets * 08/10/2015 v0.5 : Filtrage des changement de pression. * prog: 21754 / 32256 octets, ram: 1473 / 2048 octets */ #include <Wire.h> #include <SPI.h> #include <RTClib.h> #include <SD.h> #include <Adafruit_BMP085.h>
#define VERSION "0.5"
// ----- RTC -----
RTC_DS1307 RTC; #define cntAddr (0)
void initRTC( void ) { Serial.print( "Initializing RTC ... "); if ( ! RTC.isrunning() ) { Serial.println( "Not running." ); //SyncRTC(); } else { Serial.println( "Ok." ); } }
uint8_t getCounterValue( void ) { // Valeur compteur contenue dans la NvRam de la RTC uint8_t tmp = RTC.readnvram( cntAddr ); RTC.writenvram( cntAddr, ++tmp ); return tmp; }
char* getCurrentDate( void ) { static char buf[24]; DateTime now = RTC.now(); // Convertir la date/time en chaine dans le buffer, !!! longueur du buffer // 2015/10/05 15:16:17 soit 19 caractères minimum + 0 final = 20 caractères. sprintf( buf, "%u/%.2u/%.2u %.2u:%.2u:%.2u", now.year(),now.month(),now.day(),now.hour(),now.minute(),now.second() ); return buf; }
// ----- BMP180 capteur de pression -----
Adafruit_BMP085 bmp; bool bmpOk = false; uint32_t previousPressure; // cur - 1 uint32_t currentPressure; // en hPa, lecture / 100
void initBMP180( void ) { Serial.print( "Initializing BMP180 ... "); if ( ! bmp.begin() ) { Serial.println( "no BMP." ); } else { Serial.println( "Ok" ); bmpOk = true; } previousPressure = 0; }
#define moyP (8) // > 1 (pair) static uint32_t avgPressure = 0;
uint32_t readCurrentPressure( void ) { // note: il faudrait introduire un système d’hystérésis pour éviter // les oscillations entre deux valeurs trop proches. uint32_t tmp = bmp.readPressure(); // en Pa if ( 0 == avgPressure ) avgPressure = (moyP * tmp ); // Calcul d'une valeur moyennée (filtrage) avgPressure += (tmp - avgPressure / moyP); return ( ( (avgPressure / moyP) + 50 ) / 100 ); // arrondi en hPa }
char* getCurentBMP( void ) { static char buf[16]; char tmp[8]; // pas de %f dans sprintf(), utiliser dtostrf() dtostrf( bmp.readTemperature(), 3, 1, tmp ); // Ok // Pb, %s ne fonctionne pas dans sprintf(). on utilise strcat() à la place //sprintf( buf, "%u %s", currentPressure, tmp ); sprintf( buf, "%u ", currentPressure ); strcat( buf, tmp ); return buf; }
void printBMP( void ) { if ( ! bmpOk ) return; Serial.print( "BMP: "); Serial.println( getCurentBMP() ); }
// ----- SD Card -----
// Adafruit SD shield and Modules : pin 10 on Arduino Uno const int chipSelect = 10; bool sdOk = false;
void writeLogFile( void ) { if ( ! sdOk ) return; // Open the file, note that only one file can be open at a time. File theFile = SD.open( "test.txt", FILE_WRITE ); if ( theFile ) { Serial.print( "Writing to test.txt ... " ); theFile.print( getCurrentDate() ); theFile.print( " " ); theFile.print( getCounterValue(), DEC ); if ( bmpOk ) { theFile.print( " " ); theFile.print( getCurentBMP() ); } theFile.println(); theFile.close(); Serial.println( "done" ); } else { // if the file didn't open write an error. Serial.println( "Error: can't open file test.txt" ); } }
void readLogFile( void ) { if ( ! sdOk ) return; // Open the file, note that only one file can be open at a time. File theFile = SD.open( "test.txt" ); if ( theFile ) { Serial.println( "Reading from test.txt : " ); while ( theFile.available() ) { Serial.write( theFile.read() ); } theFile.close(); } else { // if the file didn't open write an error. Serial.println( "Error: can't open file test.txt" ); } }
void initSDCard( void ) { Serial.print( "Initializing SD card ... "); pinMode( chipSelect, OUTPUT ); // chipSelect de la carte SD // Test card is working, quarter speed avec ma vielle carte 512Mo if ( ! SD.begin( chipSelect ) ) { Serial.println( "Initialization failed, Things to check:" ); Serial.println( " is a card is inserted." ); Serial.println( " is your wiring correct." ); } else { Serial.println( "Ok" ); sdOk = true; } }
// ----- Setup et Loop -----
#define INTERVAL (15000) // 15 Sec unsigned long previousMillis;
void setup() { Serial.begin(115200); Wire.begin(); Serial.print("Test Data Logger Card v"); Serial.println(VERSION); Serial.println();
initRTC(); initSDCard(); initBMP180();
Serial.println(); previousMillis = 0; }
void loop() { if ( Serial.available() > 0 ) { char inChar = Serial.read(); switch ( inChar ) { case 'r' : // read log file readLogFile(); break; case 'w' : // write log file (add a line) writeLogFile(); break; case 't' : // affiche date heure Serial.println( getCurrentDate() ); break; case 'p' : // pression et température printBMP(); break; case '\n' : Serial.println(); break; } }
unsigned long currentMillis = millis(); if ( 0 == previousMillis ) currentMillis = INTERVAL;
// How to reset millis() to avoid rollover (~49 days), this code is Ok : if ((unsigned long)(currentMillis - previousMillis) >= INTERVAL) { previousMillis = currentMillis; // save the last time // On va faire un log des variations de pression currentPressure = readCurrentPressure(); // en hPa if ( (currentPressure != previousPressure) ) { // uniquement si la pression a changé previousPressure = currentPressure; writeLogFile(); } } delay( 100 ); } Le code du programme utilisé pour la mise à l'heure de l'horloge: - Code:
-
/* Programme de test horloge DS1307 * Auteur: Jean-Claude Vandenhekke * 04/10/2015 v0.1 : Création du test. * Pour mise à l'heure de l'horloge * Heure de compilation */ #include <Wire.h> #include <RTClib.h>
#define VERSION "0.1"
// ----- RTC -----
RTC_DS1307 RTC; #define cntAddr (0)
void initRTC( void ) { Serial.print( "Initializing RTC ... "); if ( ! RTC.isrunning() ) { Serial.println( "Not running." ); RTC.adjust( DateTime( __DATE__,__TIME__ ) ); } else { Serial.println( "Ok." ); } }
char* getCurrentDate( void ) { static char buf[24]; DateTime now = RTC.now(); // Convertir la date/time en chaine dans le buffer, !!! longueur du buffer // 2015/10/05 15:16:17 soit 19 caractères minimum + 0 final = 20 caractères. sprintf( buf, "%u/%.2u/%.2u %.2u:%.2u:%.2u", now.year(),now.month(),now.day(),now.hour(),now.minute(),now.second() ); return buf; }
// ----- Setup et Loop -----
void setup() { Serial.begin(115200); Wire.begin(); Serial.print("Test Data Logger Card v"); Serial.println(VERSION); Serial.println();
initRTC();
Serial.println( getCurrentDate() ); }
void loop() { delay( 3000 ); } Pour la mise à l'heure avec ce code, il faut compiler et télécharger/exécuter tout de suite, ce code met l'horloge à l'heure de compilation, c'est une peu simpliste mais ça fonctionne. Il serait possible de faire un dialogue qui demande l'heure au PC, sur lequel il faut alors faire tourner un script. A+ JCV
Dernière édition par JCV le Sam 24 Oct 2015 - 14:16, édité 1 fois | |
|
Asl Support Electronique Membre d'Honneur
Age : 73 Localisation : Près de Saumur Prénom : Alain Date d'inscription : 15/08/2006
| Sujet: Re: Data Logger à base d'Arduino, plus test avec capteur de pression. Ven 23 Oct 2015 - 11:06 | |
| Bonjour Jean-Claude, Beau module qui peut en effet s'intégrer dans un projet plus complet. Merci. Je ne parle pas pour moi car je reste toujours au langage assembleur, mais une précision pour les autres qui souhaiteraient éventuellement utiliser ce module : les fichiers #include sont-ils intégrés (donc fournis) dans le compilateur ? - Citation :
- 2015/10/09 14:15:29 38 1020 23.0
2015/10/09 16:58:04 39 1019 22.9 Dis-donc, si tu as placé ta sonde de température à l'extérieur, tu es un sacré veinard... @++ | |
|
JCV Support Electronique
Age : 75 Localisation : France (Nord) Prénom : Jean-Claude Date d'inscription : 28/04/2008
| Sujet: Re: Data Logger à base d'Arduino, plus test avec capteur de pression. Ven 23 Oct 2015 - 13:16 | |
| Bonjour Alain,
Effectivement je n'ai pas indiqué les fichiers librairies (includes), Wire, Spi, Sd sont intégré à l'éditeur/compilateur.
La librairie RTCLib se trouve facilement à partir du site qui vend la carte. Et pour le BMP180, c'est le même que pour le BMP085, on le trouve à partir du site Adafruit avec la doc du module.
En général c'est sur "Gitub" et il suffit de charger le zip de la dernière version.
La température est celle de la pièce où je fait mes essais, un peu élevée car pas très loin du PC.
A+ JCV | |
|
JCV Support Electronique
Age : 75 Localisation : France (Nord) Prénom : Jean-Claude Date d'inscription : 28/04/2008
| Sujet: Re: Data Logger à base d'Arduino, plus test avec capteur de pression. Ven 23 Oct 2015 - 13:35 | |
| Les librairies que j'ai utilisé, fichiers ici :
https://github.com/adafruit/RTClib
https://github.com/adafruit/Adafruit-BMP085-Library
Il y en a d'autres mais j'ai pris les plus petites pour ne pas dépasser la taille de la mémoire de l'Arduino Uno.
A+ JCV | |
|
Contenu sponsorisé
| Sujet: Re: Data Logger à base d'Arduino, plus test avec capteur de pression. | |
| |
|