Bureau d'études de Recherche et de Développement


 
AccueilAccueil  PortailPortail  FAQFAQ  S'enregistrerS'enregistrer  Connexion  

Partagez | 
 

 Data Logger à base d'Arduino, plus test avec capteur de pression.

Voir le sujet précédent Voir le sujet suivant Aller en bas 
AuteurMessage
JCV
Support Electronique
avatar

Age : 69
Localisation : France (Nord)
Prénom : Jean-Claude
Date d'inscription : 28/04/2008

MessageSujet: 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
Revenir en haut Aller en bas
Asl
Support Electronique
Membre d'Honneur
Support ElectroniqueMembre d'Honneur
avatar

Age : 66
Localisation : Près de Saumur
Prénom : Alain
Date d'inscription : 15/08/2006

MessageSujet: 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... sunny Laughing Razz

@++

****************************
Tout le monde savait que c'était impossible.
Il est venu un imbécile qui ne le savait pas... et qui l'a fait.
(X-Wing)
Revenir en haut Aller en bas
JCV
Support Electronique
avatar

Age : 69
Localisation : France (Nord)
Prénom : Jean-Claude
Date d'inscription : 28/04/2008

MessageSujet: 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
Revenir en haut Aller en bas
JCV
Support Electronique
avatar

Age : 69
Localisation : France (Nord)
Prénom : Jean-Claude
Date d'inscription : 28/04/2008

MessageSujet: 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
Revenir en haut Aller en bas
Contenu sponsorisé




MessageSujet: Re: Data Logger à base d'Arduino, plus test avec capteur de pression.   

Revenir en haut Aller en bas
 
Data Logger à base d'Arduino, plus test avec capteur de pression.
Voir le sujet précédent Voir le sujet suivant Revenir en haut 
Page 1 sur 1

Permission de ce forum:Vous ne pouvez pas répondre aux sujets dans ce forum
Bureau d'études de Recherche et de Développement :: Bureau d'Etudes :: Essais et expériences diverses-
Sauter vers:  
Site à visiter...

Econologie.com : rechauffement climatique et economies d'energie

NOS REALISATIONS, TESTEES ET...
REPRODUCTIBLES PAR TOUS !

Alimentation à découpage
2v - 25v / 20A

Carte interface série optocouplée
pour système de développement
sur PICS

Carte PWM avec
mosfet de puissance intégré