Enregistrement de données sur carte SD - Projet mini station météo

Bonjour à tous,

Je construit une mini station météo avec le matériel suivant :

  • carte UNO rev3
  • capteur DHT11
  • capteur BMP085
  • Module SDCard Micro SDCard Adapter
  • Module RTC DS3231

Jusqu'ici je n'ai rencontré aucun problème de lecture et d'enregistrement de données sur la carte SD, sauf depuis que j'ai ajouté le capteur BMP085. J'affiche correctement les valeurs lues sur le moniteur série, mais aucune valeur n'est enregistrée sur ma carte SD (cela fonctionnait avant l'ajout du BMP085).
Je mets le sketch, le schéma de montage, une copie du moniteur série et du fichier DATA0001.LOG en PJ.

Quelqu'un aurait une idée d'où vient le problème pour la sauvegarde sur carte SD ?

Code du programme :

//-------------------------------------------------------------------------------------------------------------------------------------------------------
//                                                        DESCRIPTION DU PROGRAMME
//-------------------------------------------------------------------------------------------------------------------------------------------------------
/* Début de commentaire
 Programme enregistrant les données des capteurs DHT11 et BMP085 sur carte SD + horodatage par DS3231.
 Fin de commentaire */
//-------------------------------------------------------------------------------------------------------------------------------------------------------
//                                                       DEFINITION DES BIBLIOTHEQUES
//-------------------------------------------------------------------------------------------------------------------------------------------------------

//Librairie DS3231
#include <Wire.h>
#include "RTClib.h"

//Librairie du capteur DHT11
#include <dht11.h>
#define DHT11PIN 9  //Branché sur pin 9 digital

//Librairies du module SDCard
#include <SPI.h>
#include <SD.h>

//Librairies BMP085
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP085_U.h>

//-------------------------------------------------------------------------------------------------------------------------------------------------------
//                                                       DEFINITION DES VARIABLES/INSTANCES DES CAPTEURS
//-------------------------------------------------------------------------------------------------------------------------------------------------------

//Instance DS3231
RTC_DS3231 rtc;
//Instance du capteur DHT11
dht11 DHT11;
//Instance module SDCard
File dataFile;
//Instance BMP085
Adafruit_BMP085_Unified bmp = Adafruit_BMP085_Unified(12345);

//Tableau stockant les jours de la semaine
char daysOfTheWeek[7][12] = {"Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"};

//Variables
long tempo = 5000;
const int CS_PIN = 10;

//-------------------------------------------------------------------------------------------------------------------------------------------------------
//                                                      INITIALISATION DU PROGRAMME
//-------------------------------------------------------------------------------------------------------------------------------------------------------

void setup ()
{
 Serial.begin(9600);

 delay(100); // Attente de l'ouverture de la console

 // Initialisation DS3231
 if (! rtc.begin())
   {
   Serial.println("Couldn't find RTC");
   while (1);
   };

 if (rtc.lostPower())
   {
   Serial.println("RTC lost power, lets set the time!");
   // following line sets the RTC to the date & time this sketch was compiled
   rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
   };

 // Initialisation SDCard
 if (!SD.begin(CS_PIN))
   {
   Serial.println("Initialization SDCard failed!");
   while (1);
   }
 Serial.println("Initialization SDCard done.");

 // Ouverture du fichier DATA0001.LOG :
 dataFile = SD.open("DATA0001.LOG", FILE_WRITE);

 // Si le fichier est ouvert, écrire dedans :
 if (dataFile)
   {
     // Concaténation chaîne pour date et heure :
     String dataString = "";
     DateTime now = rtc.now();
     dataString += "Programme [DS3231_SDCard_DHT11_BMP085_V01], ";
     dataString += daysOfTheWeek[now.dayOfTheWeek()];
     dataString += " le ";
     dataString += now.day();
     dataString += "/";
     dataString += now.month();
     dataString += "/";
     dataString += now.year();
     dataString += " - ";
     dataString += now.hour();
     dataString += ":";
     dataString += now.minute();
     dataString += ":";
     dataString += now.second();
     dataString += ".";
     dataFile.println(dataString);
     dataString = "";
     dataString += "Date\tHeure\tHumidité (%)\tTempérature (°C)\tPression (hPa)\tTempérature BMP085 (°C)";
     dataFile.println(dataString);
     dataFile.close();    
   }
 // Sinon, afficher une erreur :
 else
   {
   Serial.println("error opening DATA0001.LOG");
   };
 delay(100);

 // Initialisation du capteur DHT11
 Serial.print("Vérification du capteur DHT11 : ");
 int chk = DHT11.read(DHT11PIN);
 switch (chk)
   {
   case DHTLIB_OK:
     Serial.println("OK.");
     break;
   case DHTLIB_ERROR_CHECKSUM:
     Serial.println("Erreur de Checksum.");
     break;
   case DHTLIB_ERROR_TIMEOUT:
     Serial.println("Erreur de Time out.");
     break;
   default:
     Serial.println("Erreur inconnue.");
     break;
   }

 // Initialisation BMP085
 Serial.print("Pressure Sensor Test : ");

 // Vérification de la connexion du capteur
 if(!bmp.begin())
 {
   Serial.print("Ooops, no BMP085 detected ... Check your wiring or I2C ADDR!");
   while(1);
 }
 else
 {
   Serial.println("BMP085 ready.");
 }
}

//-------------------------------------------------------------------------------------------------------------------------------------------------------
//                                                           BOUCLE PRINCIPALE
//-------------------------------------------------------------------------------------------------------------------------------------------------------

void loop ()
{
 writeSD();
}

//-------------------------------------------------------------------------------------------------------------------------------------------------------
//                                                    FONCTIONS DE LA BOUCLE PRINCIPALE
//-------------------------------------------------------------------------------------------------------------------------------------------------------

void writeSD()
{  
 // Lecture des données sur DHT11
 float humi = DHT11.humidity;
 float temp = DHT11.temperature;

 // Lecture données BMP85
 sensors_event_t event;
 bmp.getEvent(&event);
 float tempBMP085;
 bmp.getTemperature(&tempBMP085);
 float pressure = event.pressure;

 //Concaténation des données dans la chaîne dataString
 String dataString = "";
 DateTime now = rtc.now();
 dataString += now.day();
 dataString += "/";
 dataString += now.month();
 dataString += "/";
 dataString += now.year();
 dataString += "\t";
 dataString += now.hour();
 dataString += ":";
 dataString += now.minute();
 dataString += ":";
 dataString += now.second();
 dataString += "\t";
 dataString += humi;
 dataString += "\t";
 dataString += temp;
 dataString += "\t";
 dataString += pressure;
 dataString += "\t";  
 dataString += tempBMP085;

 // Ecriture de dataString sur la carte SD.
 File dataFile = SD.open("DATA0001.LOG", FILE_WRITE);
 dataFile.println(dataString);
 dataFile.close();
 // Affichage sur console de dataString :
 Serial.println(dataString);

 delay(tempo);
}

Merci à vous !
Waykot.

[Edit] : le module DS3231 et le capteur BMP085 communiquent tous les deux via la librairie Wire (DS3231 branché sur pins SDA+ SCL et BMP085 sur les pins analogiques A4 + A5). Est-ce qu'il ne pourrait pas y avoir conflit, d'où les données non sauvegardées sur SD ? Mais dans ce cas, pourquoi je vois bien les données sur la console ?

[Edit 2] : ça a l'air de venir de la déclaration des variables du capteur BMP085, j'ai commenté cette section :

// Lecture données BMP85
//  sensors_event_t event;
//  bmp.getEvent(&event);
//  float tempBMP085;
//  bmp.getTemperature(&tempBMP085);
//  float pressure = event.pressure;

Du coup, je retrouve le fonctionnement normal d'avant.
Si vous avez des suggestions d'amélioration du code ci-dessus pour qu'il fonctionne, je suis preneur !

Test_DS3231_SDCard_DHT11_BMP085_V01.ino (6.8 KB)

Postez le code directement dans le forum - peux pas le lire simplement depuis mon mobile

Voici vos images pour éviter de clicker (mais pour le fichier ou la console le mieux c’est de poster le texte plutôt qu’une image...)

Schéma de montage

Moniteur série

Fichier

Je ne sais pas si le problème vient de conflits de communication, mais peux-tu tester :

 // Ecriture de dataString sur la carte SD.
  File dataFile = SD.open("DATA0001.LOG", FILE_WRITE);
  if (dataFile)
  {
    dataFile.println(dataString);
    dataFile.close();
  }
  else
  {
    Serial.println("Couldn't open datafile");
  }

Tu peux même ajouter un
Serial.println(dataFile); pour voir le code d'erreur renvoyé.

lesept:
Je ne sais pas si le problème vient de conflits de communication, mais peux-tu tester :

 // Ecriture de dataString sur la carte SD.

File dataFile = SD.open("DATA0001.LOG", FILE_WRITE);
 if (dataFile)
 {
   dataFile.println(dataString);
   dataFile.close();
 }
 else
 {
   Serial.println("Couldn't open datafile");
 }

Effectivement, le fichier dataFile ne s'ouvre pas :

Vérification du capteur DHT11 : OK.
Pressure Sensor Test : BMP085 ready.
Initialization SDCard done.
error opening DATA0001.LOG
Couldn't open datafile
16/6/2018 10:24:43 \a⸮

La première erreur apparaît dès le SETUP, la seconde dans la fonction writeSD().

Je viens de tester avec une librairie plus simple (Adafruit_BMP085.h), ça fonctionne parfaitement, je perds juste en précision pour la mesure de la pression.

Code V02 :

//-------------------------------------------------------------------------------------------------------------------------------------------------------
//                                                        DESCRIPTION DU PROGRAMME
//-------------------------------------------------------------------------------------------------------------------------------------------------------
/* Début de commentaire
 Programme enregistrant les données des capteurs DHT11 et BMP085 sur carte SD + horodatage par DS3231.
 Fin de commentaire */
//-------------------------------------------------------------------------------------------------------------------------------------------------------
//                                                       DEFINITION DES BIBLIOTHEQUES
//-------------------------------------------------------------------------------------------------------------------------------------------------------

//Librairie DS3231
#include <Wire.h>
#include "RTClib.h"

//Librairie du capteur DHT11
#include <dht11.h>
#define DHT11PIN 9  //Branché sur pin 9 digital

//Librairies du module SDCard
#include <SPI.h>
#include <SD.h>

//Librairies BMP085
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP085.h>

//-------------------------------------------------------------------------------------------------------------------------------------------------------
//                                                       DEFINITION DES VARIABLES/INSTANCES DES CAPTEURS
//-------------------------------------------------------------------------------------------------------------------------------------------------------

//Instance DS3231
RTC_DS3231 rtc;
//Instance du capteur DHT11
dht11 DHT11;
//Instance module SDCard
File dataFile;
//Instance BMP085
Adafruit_BMP085 bmp;

//Tableau stockant les jours de la semaine
char daysOfTheWeek[7][12] = {"Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"};

//Variables
long tempo = 5000;
const int CS_PIN = 10;

//-------------------------------------------------------------------------------------------------------------------------------------------------------
//                                                      INITIALISATION DU PROGRAMME
//-------------------------------------------------------------------------------------------------------------------------------------------------------

void setup ()
{
 Serial.begin(9600);

 delay(100); // Attente de l'ouverture de la console

 // Initialisation DS3231
 if (! rtc.begin())
   {
   Serial.println("Couldn't find RTC");
   while (1);
   };

 if (rtc.lostPower())
   {
   Serial.println("RTC lost power, lets set the time!");
   // following line sets the RTC to the date & time this sketch was compiled
   rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
   };

 // Initialisation du capteur DHT11
 Serial.print("Vérification du capteur DHT11 : ");
 int chk = DHT11.read(DHT11PIN);
 switch (chk)
   {
   case DHTLIB_OK:
     Serial.println("OK.");
     break;
   case DHTLIB_ERROR_CHECKSUM:
     Serial.println("Erreur de Checksum.");
     break;
   case DHTLIB_ERROR_TIMEOUT:
     Serial.println("Erreur de Time out.");
     break;
   default:
     Serial.println("Erreur inconnue.");
     break;
   }

 // Initialisation BMP085
 Serial.print("Pressure Sensor Test : ");

 // Vérification de la connexion du capteur
 if(!bmp.begin())
 {
   Serial.print("Ooops, no BMP085 detected ... Check your wiring or I2C ADDR!");
   while(1);
 }
 else
 {
   Serial.println("BMP085 ready.");
 }
 
 // Initialisation SDCard
 if (!SD.begin(CS_PIN))
   {
   Serial.println("Initialization SDCard failed!");
   while (1);
   }
 Serial.println("Initialization SDCard done.");

 // Ouverture du fichier DATA0001.LOG :
 dataFile = SD.open("DATA0001.LOG", FILE_WRITE);

 // Si le fichier est ouvert, écrire dedans :
 if (dataFile)
   {
     // Concaténation chaîne pour date et heure :
     String dataString = "";
     DateTime now = rtc.now();
     dataString += "Programme [DS3231_SDCard_DHT11_BMP085_V01], ";
     dataString += daysOfTheWeek[now.dayOfTheWeek()];
     dataString += " le ";
     dataString += now.day();
     dataString += "/";
     dataString += now.month();
     dataString += "/";
     dataString += now.year();
     dataString += " - ";
     dataString += now.hour();
     dataString += ":";
     dataString += now.minute();
     dataString += ":";
     dataString += now.second();
     dataString += ".";
     dataFile.println(dataString);
     Serial.println(dataString);
     dataString = "Date\tHeure\tHumidité (%)\tTempérature (°C)\tPression (hPa)\tTempérature BMP085 (°C)\tAltitude (m)";
     dataFile.println(dataString);
     Serial.println(dataString);
     dataFile.close();    
   }
 // Sinon, afficher une erreur :
 else
   {
   Serial.println("error opening DATA0001.LOG");
   };
 delay(100);
}

//-------------------------------------------------------------------------------------------------------------------------------------------------------
//                                                           BOUCLE PRINCIPALE
//-------------------------------------------------------------------------------------------------------------------------------------------------------

void loop ()
{
 writeSD();
}

//-------------------------------------------------------------------------------------------------------------------------------------------------------
//                                                    FONCTIONS DE LA BOUCLE PRINCIPALE
//-------------------------------------------------------------------------------------------------------------------------------------------------------

void writeSD()
{  
 // Lecture des données sur DHT11
 float humi = DHT11.humidity;
 float temp = DHT11.temperature;

 // Lecture données BMP85
 float tempBMP085 = bmp.readTemperature();
 float pressure = bmp.readPressure()/100;
 int altitude = bmp.readAltitude();

 //Concaténation des données dans la chaîne dataString
 String dataString = "";
 DateTime now = rtc.now();
 dataString += now.day();
 dataString += "/";
 dataString += now.month();
 dataString += "/";
 dataString += now.year();
 dataString += "\t";
 dataString += now.hour();
 dataString += ":";
 dataString += now.minute();
 dataString += ":";
 dataString += now.second();
 dataString += "\t";
 dataString += humi;
 dataString += "\t";
 dataString += temp;
 dataString += "\t";
 dataString += pressure;
 dataString += "\t";  
 dataString += tempBMP085;
 dataString += "\t";
 dataString += altitude;

 // Ecriture de dataString sur la carte SD.
 File dataFile = SD.open("DATA0001.LOG", FILE_WRITE);
 dataFile.println(dataString);
 dataFile.close();
 // Affichage sur console de dataString :
 Serial.println(dataString);

 delay(tempo);
}

Console :
Vérification du capteur DHT11 : OK.
Pressure Sensor Test : BMP085 ready.
Initialization SDCard done.
Programme [DS3231_SDCard_DHT11_BMP085_V02], Samedi le 16/6/2018 - 10:30:22.
Date Heure Humidité (%) Température (°C) Pression (hPa) Température BMP085 (°C) Altitude (m)
16/6/2018 10:30:22 63.00 22.00 1010.00 23.20 18
16/6/2018 10:30:27 63.00 22.00 1010.00 23.20 18
16/6/2018 10:30:32 63.00 22.00 1010.00 23.20 18

Fichier DATA0001.LOG :
Programme [DS3231_SDCard_DHT11_BMP085_V02], Samedi le 16/6/2018 - 10:30:22.
Date Heure Humidité (%) Température (°C) Pression (hPa) Température BMP085 (°C) Altitude (m)
16/6/2018 10:30:22 63.00 22.00 1010.00 23.20 18
16/6/2018 10:30:27 63.00 22.00 1010.00 23.20 18
16/6/2018 10:30:32 63.00 22.00 1010.00 23.20 18

J'imagine que je dois mal déclarer/utiliser les variables de la librairie Adafruit_BMP085_U.h

Déjà tu utilises mal le forum, c'est galère de lire les programmes quand il ne sont pas entre balises "CODE" : peux-tu éditer et modifier tes messages pour mettre les balises autour de tes programmes (la touche </>) ? Merci

Ensuite, le seul point que je vois qui diffère avec l'exemple de la bibli c'est que tu acquières la pression sans attendre l’événement :

/* Display the results (barometric pressure is measure in hPa) */
  if (event.pressure)
  {
    /* Display atmospheric pressure in hPa */
    Serial.print("Pressure:    ");
    Serial.print(event.pressure);
    Serial.println(" hPa");

            ...
  }

Après, quel lien ça pourrait avoir avec un fichier qui ne s'ouvre pas ? Peut-être une gestion d'interruption incorrecte, je ne sais pas. Essaye de rester plus proche de l'exemple pour voir si ça a un impact.

Je ne comprends pas d'où vient le problème.
J'ai testé le capteur BMP085 (librairie Adafruit_BMP085_Unified) seul avec le module SDCard, tout fonctionne sans problème.

J'ai donc retenté avec mon code initial, en reprenant la syntaxe fournie (celle que tu décris), mais ça continue à planter ...

//-------------------------------------------------------------------------------------------------------------------------------------------------------
//                                                        DESCRIPTION DU PROGRAMME
//-------------------------------------------------------------------------------------------------------------------------------------------------------
/* Début de commentaire
  Programme enregistrant les données des capteurs DHT11 et BMP085 sur carte SD + horodatage par DS3231.
  Fin de commentaire */
//-------------------------------------------------------------------------------------------------------------------------------------------------------
//                                                       DEFINITION DES BIBLIOTHEQUES
//-------------------------------------------------------------------------------------------------------------------------------------------------------

//Librairie DS3231
#include <Wire.h>
#include "RTClib.h"

//Librairie du capteur DHT11
#include <dht11.h>
#define DHT11PIN 9  //Branché sur pin 9 digital

//Librairies du module SDCard
#include <SPI.h>
#include <SD.h>

//Librairies BMP085
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP085_U.h>

//-------------------------------------------------------------------------------------------------------------------------------------------------------
//                                                       DEFINITION DES VARIABLES/INSTANCES DES CAPTEURS
//-------------------------------------------------------------------------------------------------------------------------------------------------------

//Instance DS3231
RTC_DS3231 rtc;
//Instance du capteur DHT11
dht11 DHT11;
//Instance module SDCard
File dataFile;
//Instance BMP085
Adafruit_BMP085_Unified bmp = Adafruit_BMP085_Unified(12345);

//Tableau stockant les jours de la semaine
char daysOfTheWeek[7][12] = {"Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"};

//Variables
long tempo = 5000;
const int CS_PIN = 10;

//-------------------------------------------------------------------------------------------------------------------------------------------------------
//                                                      INITIALISATION DU PROGRAMME
//-------------------------------------------------------------------------------------------------------------------------------------------------------

void setup ()
{
  Serial.begin(9600);

  delay(100); // Attente de l'ouverture de la console
  Serial.println("Programme [DS3231_SDCard_DHT11_BMP085_V03]");

  // Initialisation DS3231
  if (! rtc.begin())
    {
    Serial.println("Couldn't find RTC");
    while (1);
    }
  else
    {
    Serial.println("Vérification module DS3231 : OK.");
    }

  if (rtc.lostPower())
    {
    Serial.println("RTC lost power, lets set the time!");
    // following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    };

  // Initialisation du capteur DHT11
  Serial.print("Vérification du capteur DHT11 : ");
  int chk = DHT11.read(DHT11PIN);
  switch (chk)
    {
    case DHTLIB_OK:
      Serial.println("OK.");
      break;
    case DHTLIB_ERROR_CHECKSUM:
      Serial.println("Erreur de Checksum.");
      break;
    case DHTLIB_ERROR_TIMEOUT:
      Serial.println("Erreur de Time out.");
      break;
    default:
      Serial.println("Erreur inconnue.");
      break;
    }

  // Initialisation BMP085
  Serial.print("Vérification du capteur BMP085 : ");

  // Vérification de la connexion du capteur
  if (!bmp.begin())
    {
    Serial.print("Pas de capteur détecté ... Vérifier le câblage ou l'adresse I2C !");
    while (1);
    }
  else
    {
    Serial.println("Ok.");
    }

  // Initialisation SDCard
  if (!SD.begin(CS_PIN))
    {
    Serial.println("Initialization SDCard failed !");
    while (1);
    }
  else
    {
    Serial.println("Initialization SDCard done.");
    // Ouverture du fichier DATA0001.LOG :
    dataFile = SD.open("DATA0001.LOG", FILE_WRITE);
    // Si le fichier est ouvert, écrire dedans :
    if (dataFile)
      {
      Serial.println("Fichier DATA0001.LOG ouvert.");
      // Concaténation chaîne pour date et heure :
      String dataString = "";
      DateTime now = rtc.now();
      dataString += "Programme [DS3231_SDCard_DHT11_BMP085_V03], ";
      dataString += daysOfTheWeek[now.dayOfTheWeek()];
      dataString += " le ";
      dataString += now.day();
      dataString += "/";
      dataString += now.month();
      dataString += "/";
      dataString += now.year();
      dataString += " - ";
      dataString += now.hour();
      dataString += ":";
      dataString += now.minute();
      dataString += ":";
      dataString += now.second();
      dataString += ".";
      dataFile.println(dataString);
      Serial.println(dataString);
      dataString = "Date\tHeure\tHumidité (%)\tPression (hPa)\tTempérature BMP085 (°C)";
      dataFile.println(dataString);
      Serial.println(dataString);
      dataFile.close();
      }
    // Sinon, afficher une erreur :
    else
      {
      Serial.println("Erreur d'ouverture DATA0001.LOG");
      }
    }
  delay(100);
}

//-------------------------------------------------------------------------------------------------------------------------------------------------------
//                                                           BOUCLE PRINCIPALE
//-------------------------------------------------------------------------------------------------------------------------------------------------------

void loop ()
{
  writeSD();
}

//-------------------------------------------------------------------------------------------------------------------------------------------------------
//                                                    FONCTIONS DE LA BOUCLE PRINCIPALE
//-------------------------------------------------------------------------------------------------------------------------------------------------------

void writeSD()
{
  // Lecture des données sur DHT11
  float humi = DHT11.humidity;

  // Lecture données BMP85
  /* Get a new sensor event */
  sensors_event_t event;
  bmp.getEvent(&event);
  float temperature;

  //Concaténation des données dans la chaîne dataString
  String dataString = "";
  DateTime now = rtc.now();
  dataString += now.day();
  dataString += "/";
  dataString += now.month();
  dataString += "/";
  dataString += now.year();
  dataString += "\t";
  dataString += now.hour();
  dataString += ":";
  dataString += now.minute();
  dataString += ":";
  dataString += now.second();
  dataString += "\t";
  dataString += humi;
  dataString += "\t";
  if (event.pressure)
    {
      Serial.println("Reading sensor");
      //Concaténation des données dans la chaîne dataString
      dataString += event.pressure;
      dataString += "\t";
      bmp.getTemperature(&temperature);
      dataString += temperature;
    }
  else
    {
      Serial.println("Sensor error");
    }

  // Ecriture de dataString sur la carte SD.
  File dataFile = SD.open("DATA0001.LOG", FILE_WRITE);
  dataFile.println(dataString);
  dataFile.close();
  // Affichage sur console de dataString :
  Serial.println(dataString);

  delay(tempo);
}

As-tu essayé d'ajouter

   Serial.println(event.pressure);

avant de l'ajouter à ta string ?

EDIT : quand tu dis que ça plante, c'est qu'il n'arrive pas à ouvrir le fichier ? Dans ce cas, le problème apparaît avant la lecture du capteur ?

Si oui, essaye de simplifier ton code au maximum : trouve une version qui fonctionne et ajoute tes lignes une par une jusqu'à trouver celle qui fait planter.

Après plusieurs essais, je pense avoir trouvé d'où vient le problème.
J'ai pu vérifier que le capteur BMP085 fonctionne correctement, en affichant sur la console la valeur du capteur via :

Serial.println(event.pressure);

Mes variables utilisent environ 86% de mémoire dynamique. Les variables et le code du module DS3231 consomment pas mal a priori.
En commentant et testant, je suis redescendu à 80% et ça fonctionne correctement.

Le croquis utilise 20432 octets (63%) de l'espace de stockage de programmes.
Les variables globales utilisent 1644 octets (80%) de mémoire dynamique

J'ai donc enlevé une partie du code du module dans le SETUP, ça donne ça et c'est fonctionnel.

//-------------------------------------------------------------------------------------------------------------------------------------------------------
//                                                        DESCRIPTION DU PROGRAMME
//-------------------------------------------------------------------------------------------------------------------------------------------------------
/* Début de commentaire
  Programme enregistrant les données des capteurs DHT11 et BMP085 sur carte SD + horodatage par DS3231.
  Fin de commentaire */
//-------------------------------------------------------------------------------------------------------------------------------------------------------
//                                                       DEFINITION DES BIBLIOTHEQUES
//-------------------------------------------------------------------------------------------------------------------------------------------------------

//Librairie DS3231
#include <Wire.h>
#include "RTClib.h"

//Librairie du capteur DHT11
#include <dht11.h>
#define DHT11PIN 9  //Branché sur pin 9 digital

//Librairies du module SDCard
#include <SPI.h>
#include <SD.h>

//Librairies BMP085
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP085_U.h>

//-------------------------------------------------------------------------------------------------------------------------------------------------------
//                                                       DEFINITION DES VARIABLES/INSTANCES DES CAPTEURS
//-------------------------------------------------------------------------------------------------------------------------------------------------------

//Instance DS3231
RTC_DS3231 rtc;
//Instance du capteur DHT11
dht11 DHT11;
//Instance module SDCard
File dataFile;
//Instance BMP085
Adafruit_BMP085_Unified bmp = Adafruit_BMP085_Unified(12345);

//Variables
long tempo = 60000;
const int CS_PIN = 10;

//-------------------------------------------------------------------------------------------------------------------------------------------------------
//                                                      INITIALISATION DU PROGRAMME
//-------------------------------------------------------------------------------------------------------------------------------------------------------

void setup ()
{
  Serial.begin(9600);

  delay(100); // Attente de l'ouverture de la console
  Serial.println("Programme [DS3231_SDCard_DHT11_BMP085_V03]");

  // Initialisation DS3231
  if (! rtc.begin())
    {
    Serial.println("Couldn't find RTC");
    while (1);
    }
  else
    {
    Serial.println("Vérification module DS3231 : OK.");
    }

  if (rtc.lostPower())
    {
    // following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    };

  // Initialisation du capteur DHT11
  Serial.print("Vérification du capteur DHT11 : ");
  int chk = DHT11.read(DHT11PIN);
  switch (chk)
    {
    case DHTLIB_OK:
      Serial.println("OK.");
      break;
    default:
      Serial.println("Erreur inconnue.");
      break;
    }

  // Initialisation BMP085
  Serial.print("SETUP : Vérification du capteur BMP085 : ");

  // Vérification de la connexion du capteur
  if (!bmp.begin())
    {
    Serial.print("Pas de capteur BMP085 détecté ... Vérifier le câblage ou l'adresse I2C !");
    while (1);
    }
  else
    {
    Serial.println("Ok.");
    }

  // Initialisation SDCard
  if (!SD.begin(CS_PIN))
    {
    Serial.println("Initialization SDCard failed !");
    while (1);
    }
  else
    {
    // Ouverture du fichier DATA0001.LOG :
    dataFile = SD.open("DATA0001.LOG", FILE_WRITE);
    // Si le fichier est ouvert, écrire dedans :
    if (dataFile)
      {
      // Concaténation chaîne pour date et heure :
      String dataString = "";
      dataString = "Date\tHeure\tDHTHumidité (%)\tDHTTempérature (°C)\tPression (hPa)\tTempérature BMP085 (°C)";
      dataFile.println(dataString);
      dataFile.close();
      }
    // Sinon, afficher une erreur :
    else
      {
      Serial.println("SETUP : Erreur d'ouverture DATA0001.LOG");
      }
    }
  delay(100);
}

//-------------------------------------------------------------------------------------------------------------------------------------------------------
//                                                           BOUCLE PRINCIPALE
//-------------------------------------------------------------------------------------------------------------------------------------------------------

void loop ()
{
  writeSD();
}

//-------------------------------------------------------------------------------------------------------------------------------------------------------
//                                                    FONCTIONS DE LA BOUCLE PRINCIPALE
//-------------------------------------------------------------------------------------------------------------------------------------------------------

void writeSD()
{
  //Concaténation des données dans la chaîne dataString
  String dataString = "";
  //Ouverture fichier DATA0001.LOG
  File dataFile = SD.open("DATA0001.LOG", FILE_WRITE);
  if (dataFile)
    {
    // Lecture des données sur DHT11
    float dhtHumi = DHT11.humidity;
    float dhtTemp = DHT11.temperature;

    // Lecture données BMP85
    /* Get a new sensor event */
    sensors_event_t event;
    bmp.getEvent(&event);
    float temperature;
    
    DateTime now = rtc.now();
    dataString += now.day();
    dataString += "/";
    dataString += now.month();
    dataString += "/";
    dataString += now.year();
    dataString += "\t";
    dataString += now.hour();
    dataString += ":";
    dataString += now.minute();
    dataString += ":";
    dataString += now.second();
    dataString += "\t";
    dataString += dhtHumi;
    dataString += "\t";
    dataString += dhtTemp;
    dataString += "\t";
    if (event.pressure)
      {
      //Concaténation des données dans la chaîne dataString
      dataString += event.pressure;
      dataString += "\t";
      bmp.getTemperature(&temperature);
      dataString += temperature;
      }
    else
      {
      Serial.println("LOOP : BMP085 error");
      }
    }
  else
    {
    Serial.println("LOOP : Erreur d'ouverture DATA0001.LOG");
    }

  // Ecriture de dataString sur la carte SD.
  dataFile.println(dataString);
  dataFile.close();
  // Affichage sur console de dataString :
  Serial.println(dataString);

  delay(tempo);
}

Les renvois vers la console sont assez gourmands aussi, donc à terme, je les enlèverais du programme pour gagner encore un peu de mémoire.

Merci à Lesept et à J-M-L pour votre aide et vos conseils :wink:

Vous pouvez gagner un peu de mémoire en changeantchar daysOfTheWeek[7][12] = {"Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"}; enconst char * daysOfTheWeek[] = {"Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"};chaque pointeur réservera juste le bon nombre de caractères et pas 12 à chaque fois (par exemple «lundi» c’est 6 octets pas besoin de 12)

Partout où vous imprimez un texte - Changez tous vosSerial.println("Programme [DS3231_SDCard_DHT11_BMP085_V03]");enSerial.println(F("Programme [DS3231_SDCard_DHT11_BMP085_V03]"));L’usage de la macro F() permet de mettre la chaîne en mémoire flash

Utilisez la librairie SDFat au lieu de SD

N’utilisez pas la classe String! (lisez cet article en anglais pour savoir pourquoi) - Surtout pour faire ça...

      String dataString = "";
      dataString = "Date\tHeure\tDHTHumidité (%)\tDHTTempérature (°C)\tPression (hPa)\tTempérature BMP085 (°C)";
      dataFile.println(dataString);
      dataFile.close();

alors que vous pouvez juste faire

dataFile.println(F("Date\tHeure\tDHTHumidité (%)\tDHTTempérature (°C)\tPression (hPa)\tTempérature BMP085 (°C)"));
dataFile.close();

vu que le texte est statique...

Et pour la fonction qui écrit les valeurs au lieu de fabriquer un grand buffer (avec la classe String qui va vous morceler la mémoire) écrivez juste le contenu par bouts (plusieurs print), la librairie se charge de faire le cache mémoire pour optimiser l’ecriture Sur la carte pour vous

Si vous faites tout cela vos soucis mémoire vont disparaître

Wow ! Merci J-M-L pour toutes ces astuces.
Le gain de mémoire est impressionnant :

Le croquis utilise 19522 octets (60%) de l'espace de stockage de programmes.
Les variables globales utilisent 1316 octets (64%) de mémoire dynamique.

Voici le code mis à jour :

//-------------------------------------------------------------------------------------------------------------------------------------------------------
//                                                        DESCRIPTION DU PROGRAMME
//-------------------------------------------------------------------------------------------------------------------------------------------------------
/* Début de commentaire
  Programme enregistrant les données des capteurs DHT11 et BMP085 sur carte SD + horodatage par DS3231.
  Fin de commentaire */
//-------------------------------------------------------------------------------------------------------------------------------------------------------
//                                                       DEFINITION DES BIBLIOTHEQUES
//-------------------------------------------------------------------------------------------------------------------------------------------------------

//Librairie DS3231
#include <Wire.h>
#include "RTClib.h"

//Librairie du capteur DHT11
#include <dht11.h>
#define DHT11PIN 9  //Branché sur pin 9 digital

//Librairies du module SDCard
#include <SPI.h>
#include <SD.h>

//Librairies BMP085
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP085_U.h>

//-------------------------------------------------------------------------------------------------------------------------------------------------------
//                                                       DEFINITION DES VARIABLES/INSTANCES DES CAPTEURS
//-------------------------------------------------------------------------------------------------------------------------------------------------------

//Instance DS3231
RTC_DS3231 rtc;
//Instance du capteur DHT11
dht11 DHT11;
//Instance module SDCard
File dataFile;
//Instance BMP085
Adafruit_BMP085_Unified bmp = Adafruit_BMP085_Unified(12345);

//Variables
long tempo = 5000;
const int CS_PIN = 10;
//Tableau stockant les jours de la semaine
const char * daysOfTheWeek[] = {"Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"};

//-------------------------------------------------------------------------------------------------------------------------------------------------------
//                                                      INITIALISATION DU PROGRAMME
//-------------------------------------------------------------------------------------------------------------------------------------------------------

void setup ()
{
  Serial.begin(9600);

  delay(100); // Attente de l'ouverture de la console
  Serial.println(F("Programme [DS3231_SDCard_DHT11_BMP085_V03]"));

  // Initialisation DS3231
  if (! rtc.begin())
    {
    Serial.println(F("Couldn't find RTC"));
    while (1);
    }
  else
    {
    Serial.println(F("Vérification module DS3231 : OK."));
    }

  if (rtc.lostPower())
    {
    // following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    };

  // Initialisation du capteur DHT11
  Serial.print(F("Vérification du capteur DHT11 : "));
  int chk = DHT11.read(DHT11PIN);
  switch (chk)
    {
    case DHTLIB_OK:
      Serial.println(F("OK."));
      break;
    default:
      Serial.println(F("Erreur inconnue."));
      break;
    }

  // Initialisation BMP085
  Serial.print(F("Vérification du capteur BMP085 : "));

  // Vérification de la connexion du capteur
  if (!bmp.begin())
    {
    Serial.print(F("Pas de capteur BMP085 détecté ... Vérifier le câblage ou l'adresse I2C !"));
    while (1);
    }
  else
    {
    Serial.println(F("Ok."));
    }

  // Initialisation SDCard
  if (!SD.begin(CS_PIN))
    {
    Serial.println(F("Initialization SDCard failed !"));
    while (1);
    }
  else
    {
    // Ouverture du fichier DATA0001.LOG :
    dataFile = SD.open("DATA0001.LOG", FILE_WRITE);
    // Si le fichier est ouvert, écrire dedans :
    if (dataFile)
      {
        Serial.println(F("SETUP : Fichier DATA0001.LOG ouvert."));
        dataFile.println("Programme [DS3231_SDCard_DHT11_BMP085_V03]");
        DateTime now = rtc.now();
        dataFile.print(daysOfTheWeek[now.dayOfTheWeek()]);
        dataFile.print(", le ");
        dataFile.print(now.day());
        dataFile.print("/");
        dataFile.print(now.month());
        dataFile.print("/");
        dataFile.print(now.year());
        dataFile.print(" à ");
        dataFile.print(now.hour());
        dataFile.print(":");
        dataFile.print(now.minute());
        dataFile.print(":");
        dataFile.println(now.second()); 
        dataFile.println(F("Date\tHeure\tDHTHumidité (%)\tDHTTempérature (°C)\tPression (hPa)\tTempérature BMP085 (°C)"));
        //Fermeture du fichier DATA0001.LOG
        dataFile.close();
        Serial.println(F("SETUP : Fichier DATA0001.LOG fermé."));
      }
    // Sinon, afficher une erreur :
    else
      {
      Serial.println(F("SETUP : Erreur d'ouverture DATA0001.LOG"));
      }
    }
  delay(100);
}

//-------------------------------------------------------------------------------------------------------------------------------------------------------
//                                                           BOUCLE PRINCIPALE
//-------------------------------------------------------------------------------------------------------------------------------------------------------

void loop ()
{
  writeSD();
}

//-------------------------------------------------------------------------------------------------------------------------------------------------------
//                                                    FONCTIONS DE LA BOUCLE PRINCIPALE
//-------------------------------------------------------------------------------------------------------------------------------------------------------

void writeSD()
{
  //Ouverture fichier DATA0001.LOG
  File dataFile = SD.open("DATA0001.LOG", FILE_WRITE);
  if (dataFile)
    {
      Serial.println(F("LOOP : Fichier DATA0001.LOG ouvert."));
      // Lecture des données sur DHT11
      int dhtHumi = DHT11.humidity;
      int dhtTemp = DHT11.temperature;
  
      // Lecture données BMP85
      /* Get a new sensor event */
      sensors_event_t event;
      bmp.getEvent(&event);
      float temperature;
      
      DateTime now = rtc.now();
      dataFile.print(now.day());
      dataFile.print("/");
      dataFile.print(now.month());
      dataFile.print("/");
      dataFile.print(now.year());
      dataFile.print("\t");
      dataFile.print(now.hour());
      dataFile.print(":");
      dataFile.print(now.minute());
      dataFile.print(":");
      dataFile.print(now.second());
      dataFile.print("\t");
      dataFile.print(dhtHumi);
      dataFile.print("\t");
      dataFile.print(dhtTemp);
      dataFile.print("\t");
      
    if (event.pressure)
      {
        dataFile.print(int(event.pressure));
        dataFile.print("\t");
        bmp.getTemperature(&temperature);
        dataFile.println(temperature);
      }
    else
      {
        Serial.println(F("LOOP : BMP085 error"));
      }
    dataFile.close();
    Serial.println(F("LOOP : Fichier DATA0001.LOG fermé."));
    }
  else
    {
      Serial.println(F("LOOP : Erreur d'ouverture DATA0001.LOG"));
    }
  
  delay(tempo);
}

Pour l'instant, je continue avec la librairie SD.h, je vais me pencher sur SDFat.h mais elle m'a l'air un peu plus complexe, donc je vais faire des tests avant.

Pour l’usage que vous en faites je pense (à tester) que même si SDFat est plus riche ça va fonctionner pareil, quasiment tel que votre code est. (SDFat est la version à jour de la librairie SD qui est fournie en standard. même auteur)

Quand vous faites les écritures dans le fichier de texte statiquedataFile.println("Programme [DS3231_SDCard_DHT11_BMP085_V03]");vous pouvez aussi utiliser je pense la macro F(), de mémoire c’est supporté aussi.dataFile.println(F("Programme [DS3231_SDCard_DHT11_BMP085_V03]"));

Sinon vous avez deux fois le code qui imprime une ligne de donnée dans le fichier, c’est une fois de trop :slight_smile: ==> faites une fonction comme ça vous n’aurez pas 2 fois les chaînes de caractère en mémoire flash

J-M-L:
vous pouvez aussi utiliser je pense la macro F(), de mémoire c’est supporté aussi.

dataFile.println(F("Programme [DS3231_SDCard_DHT11_BMP085_V03]"));

Sinon vous avez deux fois le code qui imprime une ligne de donnée dans le fichier, c’est une fois de trop :slight_smile: ==> faites une fonction comme ça vous n’aurez pas 2 fois les chaînes de caractère en mémoire flash

Je confirme pour la macro F(), ça fonctionne très bien. Merci :wink:
J'ai testé en créant une fonction horodatage() applicable au SETUP et à ma fonction writeSD().
Ca fonctionne pour le SETUP, mais pas pour writeSD().
J'ai essayé en créant une deuxième fonction horodatageBis() spécifique à la fonction writeSD(), sans plus de résultats.

Voilà le code mis à jour, avec fonction horodatage() dans le SETUP :

//-------------------------------------------------------------------------------------------------------------------------------------------------------
//                                                        DESCRIPTION DU PROGRAMME
//-------------------------------------------------------------------------------------------------------------------------------------------------------
/* Début de commentaire
  Programme enregistrant les données des capteurs DHT11 et BMP085 sur carte SD + horodatage par DS3231.
  Fin de commentaire */
//-------------------------------------------------------------------------------------------------------------------------------------------------------
//                                                       DEFINITION DES BIBLIOTHEQUES
//-------------------------------------------------------------------------------------------------------------------------------------------------------

//Librairie DS3231
#include <Wire.h>
#include "RTClib.h"

//Librairie du capteur DHT11
#include <dht11.h>
#define DHT11PIN 9  //Branché sur pin 9 digital

//Librairies du module SDCard
#include <SPI.h>
#include <SD.h>

//Librairies BMP085
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP085_U.h>

//-------------------------------------------------------------------------------------------------------------------------------------------------------
//                                                       DEFINITION DES VARIABLES/INSTANCES DES CAPTEURS
//-------------------------------------------------------------------------------------------------------------------------------------------------------

//Instance DS3231
RTC_DS3231 rtc;
//Instance du capteur DHT11
dht11 DHT11;
//Instance module SDCard
File dataFile;
//Instance BMP085
Adafruit_BMP085_Unified bmp = Adafruit_BMP085_Unified(12345);

//Variables
long tempo = 5000;
const int CS_PIN = 10;
//Tableau stockant les jours de la semaine
const char * daysOfTheWeek[] = {"Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"};

//-------------------------------------------------------------------------------------------------------------------------------------------------------
//                                                      INITIALISATION DU PROGRAMME
//-------------------------------------------------------------------------------------------------------------------------------------------------------

void setup ()
{
  Serial.begin(9600);

  delay(100); // Attente de l'ouverture de la console
  Serial.println(F("Programme [DS3231_SDCard_DHT11_BMP085_V03]"));

  // Initialisation DS3231
  if (! rtc.begin())
    {
    Serial.println(F("Couldn't find RTC"));
    while (1);
    }
  else
    {
    Serial.println(F("Vérification module DS3231 : OK."));
    }

  if (rtc.lostPower())
    {
    // following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    };

  // Initialisation du capteur DHT11
  Serial.print(F("Vérification du capteur DHT11 : "));
  int chk = DHT11.read(DHT11PIN);
  switch (chk)
    {
    case DHTLIB_OK:
      Serial.println(F("OK."));
      break;
    default:
      Serial.println(F("Erreur inconnue."));
      break;
    }

  // Initialisation BMP085
  Serial.print(F("Vérification du capteur BMP085 : "));

  // Vérification de la connexion du capteur
  if (!bmp.begin())
    {
    Serial.print(F("Pas de capteur BMP085 détecté ... Vérifier le câblage ou l'adresse I2C !"));
    while (1);
    }
  else
    {
    Serial.println(F("Ok."));
    }

  // Initialisation SDCard
  if (!SD.begin(CS_PIN))
    {
    Serial.println(F("Initialization SDCard failed !"));
    while (1);
    }
  else
    {
    // Ouverture du fichier DATA0001.LOG :
    dataFile = SD.open("DATA0001.LOG", FILE_WRITE);
    // Si le fichier est ouvert, écrire dedans :
    if (dataFile)
      {
        dataFile.println(F("Programme [DS3231_SDCard_DHT11_BMP085_V03]"));
        dataFile.print(F("Enregistrement : "));
        horodatage();
        dataFile.print(F("Pas de mesures : "));
        dataFile.print(tempo/1000);
        dataFile.println(F(" seconde(s)."));
        dataFile.println(F("Date\tHeure\tDHTHumidité (%)\tDHTTempérature (°C)\tPression (hPa)\tTempérature BMP085 (°C)"));
        //Fermeture du fichier DATA0001.LOG
        dataFile.close();
        Serial.println(F("SETUP : fichier DATA0001.LOG ouvert, début enregistrement."));
      }
    // Sinon, afficher une erreur :
    else
      {
        Serial.print(F("SETUP : Erreur d'ouverture DATA0001.LOG."));
        Serial.println(F("Enregistrement annulé."));
      }
    }
  delay(100);
}

//-------------------------------------------------------------------------------------------------------------------------------------------------------
//                                                           BOUCLE PRINCIPALE
//-------------------------------------------------------------------------------------------------------------------------------------------------------

void loop ()
{
  writeSD();
}

//-------------------------------------------------------------------------------------------------------------------------------------------------------
//                                                    FONCTIONS SUPPLEMENTAIRES
//-------------------------------------------------------------------------------------------------------------------------------------------------------

void horodatage()
{
  DateTime now = rtc.now();
  dataFile.print(daysOfTheWeek[now.dayOfTheWeek()]);
  dataFile.print(F(" "));
  dataFile.print(now.day());
  dataFile.print(F("/"));
  dataFile.print(now.month());
  dataFile.print(F("/"));
  dataFile.print(now.year());
  dataFile.print(F(" à "));
  dataFile.print(now.hour());
  dataFile.print(F(":"));
  dataFile.print(now.minute());
  dataFile.print(F(":"));
  dataFile.println(now.second());
}

void writeSD()
{
  //Ouverture fichier DATA0001.LOG
  File dataFile = SD.open("DATA0001.LOG", FILE_WRITE);
  if (dataFile)
    {
      // Lecture des données sur DHT11
      int dhtHumi = DHT11.humidity;
      int dhtTemp = DHT11.temperature;
  
      // Lecture données BMP85
      /* Get a new sensor event */
      sensors_event_t event;
      bmp.getEvent(&event);
      float temperature;
      DateTime now = rtc.now();
      dataFile.print(now.day());
      dataFile.print(F("/"));
      dataFile.print(now.month());
      dataFile.print(F("/"));
      dataFile.print(now.year());
      dataFile.print(F("\t"));
      dataFile.print(now.hour());
      dataFile.print(F(":"));
      dataFile.print(now.minute());
      dataFile.print(F(":"));
      dataFile.print(now.second());
      dataFile.print(F("\t"));
      dataFile.print(dhtHumi);
      dataFile.print(F("\t"));
      dataFile.print(dhtTemp);
      dataFile.print(F("\t"));
      
    if (event.pressure)
      {
        dataFile.print(int(event.pressure));
        dataFile.print(F("\t"));
        bmp.getTemperature(&temperature);
        dataFile.println(temperature);
      }
    else
      {
        Serial.println(F("LOOP : BMP085 error"));
      }
    dataFile.close();
    Serial.println(F("LOOP : Données enregistrées sur DATA0001.LOG."));
    }
  else
    {
      Serial.println(F("LOOP : Erreur d'ouverture DATA0001.LOG"));
    }
  
  delay(tempo);
}

Vous devez vous assurer que le fichier est ouvert en écriture pour votre fonction d’horodatage

Yep :slight_smile: merci du rappel.

Ca fonctionne du tonnerre !
J'ai déplacé dans le LOOP la vérification de l'ouverture du fichier.

Code V04 :

//---------------------------------------
//     DESCRIPTION DU PROGRAMME
//---------------------------------------
/* Programme enregistrant les données des capteurs DHT11 et BMP085 sur carte SD + horodatage par DS3231. */
//---------------------------------------
//     DEFINITION DES BIBLIOTHEQUES
//---------------------------------------

//Librairie DS3231
#include <Wire.h>
#include "RTClib.h"

//Librairie du capteur DHT11
#include <dht11.h>
#define DHT11PIN 9  //Branché sur pin 9 digital

//Librairies du module SDCard
#include <SPI.h>
#include <SD.h>

//Librairies BMP085
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP085_U.h>

//----------------------------------------------------------
//     DEFINITION DES VARIABLES/INSTANCES DES CAPTEURS
//----------------------------------------------------------

//Instance DS3231
RTC_DS3231 rtc;
//Instance du capteur DHT11
dht11 DHT11;
//Instance module SDCard
File dataFile;
//Instance BMP085
Adafruit_BMP085_Unified bmp = Adafruit_BMP085_Unified(12345);

//Variables
// CS_PIN module SDCard.
const int CS_PIN = 10;

//Stockage du nom du programme dans un tableau.
const char * nomProg [] = {"Programme [DS3231_SDCard_DHT11_BMP085_V04]"};

// Tableau stockant les différentes valeurs de pas (en secondes).
const char * pas [] = {1, 2, 5, 10, 20, 30, 40, 50, 60, 120, 180, 240, 300, 600, 1200, 1800, 3600, 7200};

// Sélection du pas par son index dans le tableau.
int pasMesures = pas[5];

// Création de la temporisation à partir du pas de mesures défini.
const int multiplier = 1000;
long tempo = pasMesures * multiplier;

//Tableau stockant les jours de la semaine
const char * daysOfTheWeek[] = {"Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"};

//--------------------------------------
//     INITIALISATION PROGRAMME
//--------------------------------------

void setup ()
{
  Serial.begin(9600);

  delay(100); // Attente de l'ouverture de la console
  Serial.println(nomProg[0]);
  
  // Initialisation DS3231
  if (! rtc.begin())
    {
    Serial.println(F("Couldn't find RTC"));
    while (1);
    }
  else
    {
    Serial.println(F("Vérification module DS3231 : OK."));
    }

  if (rtc.lostPower())
    {
    // following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    };

  // Initialisation du capteur DHT11
  Serial.print(F("Vérification du capteur DHT11 : "));
  int chk = DHT11.read(DHT11PIN);
  switch (chk)
    {
    case DHTLIB_OK:
      Serial.println(F("OK."));
      break;
    default:
      Serial.println(F("Erreur inconnue."));
      break;
    }

  // Initialisation BMP085
  Serial.print(F("Vérification du capteur BMP085 : "));

  // Vérification de la connexion du capteur
  if (!bmp.begin())
    {
    Serial.print(F("Pas de capteur BMP085 détecté ... Vérifier le câblage ou l'adresse I2C !"));
    while (1);
    }
  else
    {
    Serial.println(F("Ok."));
    }

  // Initialisation SDCard
  if (!SD.begin(CS_PIN))
    {
    Serial.println(F("Initialization SDCard failed !"));
    while (1);
    }
  else
    {
    // Ouverture du fichier DATA0001.LOG :
    dataFile = SD.open("DATA0001.LOG", FILE_WRITE);
    // Si le fichier est ouvert, écrire dedans :
    if (dataFile)
      {
        dataFile.println(nomProg[0]);
        dataFile.print(F("Enregistrement : "));
        DateTime now = rtc.now();
        dataFile.print(daysOfTheWeek[now.dayOfTheWeek()]);
        dataFile.print(F(" "));
        horodatage();
        dataFile.println();
        dataFile.print(F("Pas de mesures : "));
        Serial.print(F("Pas de mesures : "));
        if (pasMesures >= 0 && pasMesures < 60)
          {
            dataFile.print(pasMesures);
            dataFile.println(F(" seconde(s)."));
            Serial.print(pasMesures);            
            Serial.println(F(" seconde(s)."));
            
          }
        else if (pasMesures >= 60 && pasMesures < 3600)
          {
            pasMesures = pasMesures/60;
            dataFile.print(pasMesures);
            dataFile.println(F(" minute(s)."));
            Serial.print(pasMesures);  
            Serial.println(F(" minute(s)."));
          }
        else if (pasMesures >= 3600 && pasMesures <= 7200)
          {
            pasMesures = pasMesures/3600;
            dataFile.print(pasMesures);
            dataFile.println(F(" heure(s)."));
            Serial.print(pasMesures);
            Serial.println(F(" heure(s)."));
          }      
        dataFile.println(F("Date\tHeure\tDHTHumidite (%)\tDHTTemperature (deg C)\tPression (hPa)\tTemperature BMP085 (deg C)"));
        //Fermeture du fichier DATA0001.LOG
        dataFile.close();
        Serial.println(F("SETUP : fichier DATA0001.LOG ouvert, début enregistrement."));
        }
        // Sinon, afficher une erreur :
        else
          {
            Serial.print(F("SETUP : Erreur d'ouverture DATA0001.LOG."));
            Serial.println(F("Enregistrement annulé."));
          }
    }
  delay(100);
}

//----------------------------
//     BOUCLE PRINCIPALE
//----------------------------

void loop ()
{
  //Ouverture fichier DATA0001.LOG
  dataFile = SD.open("DATA0001.LOG", FILE_WRITE);
  if (dataFile)
    {
    writeSD();
    dataFile.close();
    Serial.println(F("LOOP : Données enregistrées sur DATA0001.LOG."));
    }
  else
    {
    Serial.println(F("LOOP : Erreur d'ouverture DATA0001.LOG"));
    }
  delay(tempo);
}

//--------------------------------------
//     FONCTIONS SUPPLEMENTAIRES
//--------------------------------------

void horodatage()
{
  DateTime now = rtc.now();
  dataFile.print(now.day());
  dataFile.print(F("/"));
  dataFile.print(now.month());
  dataFile.print(F("/"));
  dataFile.print(now.year());
  dataFile.print(F(" - "));
  dataFile.print(now.hour());
  dataFile.print(F(":"));
  dataFile.print(now.minute());
  dataFile.print(F(":"));
  dataFile.print(now.second());
}

void writeSD()
{
  horodatage();

  // Lecture des données sur DHT11
  int dhtHumi = DHT11.humidity;
  int dhtTemp = DHT11.temperature;

  // Ecriture des données DHT11 sur SD
  dataFile.print(F("\t"));
  dataFile.print(dhtHumi);
  dataFile.print(F("\t"));
  dataFile.print(dhtTemp);
  dataFile.print(F("\t"));

  // Lecture données BMP85
  /* Get a new sensor event */
  sensors_event_t event;
  bmp.getEvent(&event);
  float temperature;

  // Ecriture des données BMP085 sur SD
  if (event.pressure)
    {
    dataFile.print(int(event.pressure));
    dataFile.print(F("\t"));
    bmp.getTemperature(&temperature);
    dataFile.println(temperature);
    }
  else
    {
    Serial.println(F("LOOP : BMP085 error"));
    }
}

:slight_smile: bravo!

Merci pour l'aide apporté :wink:

Je viens de découvrir un nouveau problème ... :cold_sweat:

Ma variable tempo renvoie une valeur incohérente à partir de l'index 6 du tableau "pas".

Pas de mesures : 40
Tempo : 4294941760

Pour les index précédents, le calcul de la variable tempo se fait correctement :

Programme [DS3231_SDCard_DHT11_BMP085_V04]
Pas de mesures : 30
Tempo : 30000

J'ai testé plusieurs choses en constatant l'erreur :
1 - modifier le type du tableau "pas" en int
2 - remplacer "multiplier" par sa valeur dans la formule tempo

// Tableau stockant les différentes valeurs de pas (en secondes).
int pas [] = {1, 2, 5, 10, 20, 30, 40, 50, 60, 120, 180, 240, 300, 600, 1200, 1800, 3600, 7200};//Index : 0 à 17

// Sélection du pas par son index dans le tableau.
int pasMesures = pas[6];

// Création de la temporisation à partir du pas de mesures défini.
const int multiplier = 1000;
unsigned long tempo = pasMesures * 1000;

La valeur de tempo est aussi incohérente si je déclare la variable en type long uniquement :

Programme [DS3231_SDCard_DHT11_BMP085_V04]
Pas de mesures : 40
Tempo : -25536

Je suppose que ça vient des valeurs du tableau "pas", mais je ne comprends pas pourquoi.
Si quelqu'un a une idée !
Merci.

tempo doit être un unsigned long et pas un long

le type des pas n'est pas char * (un pointeur vers un caractère !!)

// Tableau stockant les différentes valeurs de pas (en secondes).
const [color=red]char *[/color] pas [] = {1, 2, 5, 10, 20, 30, 40, 50, 60, 120, 180, 240, 300, 600, 1200, 1800, 3600, 7200};

faut partir sur des unsigned int.

enfin quand on fait des maths sans rien préciser, c'est en entier, donc quand vous faites cela, même si le résultat va dans un unsigned long, le calcul à droite du égal est d'abord fait en entier (donc sur 16 bits et ça déborde)

const int multiplier = 1000;
unsigned long tempo = pasMesures * 1000;

il faut donc forcer le calcul en unsigned long, en rajoutant [color=red]ul[/color] à la fin de la constante par exemple ou en faisant un cast explicite

const unsigned long  multiplier = 1000ul;
unsigned long tempo = pasMesures * multiplier;

ou

const unsigned long  multiplier = 1000ul;
unsigned long tempo = (unsigned long) pasMesures * multiplier;

par exemple

Je teste et je vous dis ce qu'il en est.

Impeccable ! 8)

J'ai repris ce bout de code :

const unsigned long  multiplier = 1000ul;
unsigned long tempo = (unsigned long) pasMesures * multiplier;

Merci J-M-L :wink:

Je voudrais maintenant pousser un peu plus loin mon projet, en ajoutant une fonctionnalité Wifi pour communiquer avec un site web dédié qui afficherait les valeurs des capteurs à intervalle régulier.

Je me suis un peu renseigné, j'ai quelques pistes :

  • Yun Shield, la solution la plus simple et compatible avec mon matériel actuel j'imagine.
  • modules WeMos
  • Arduino Yun, actuellement indisponible, mais paraît très intéressant en capacité mémoires, avec en plus la présence d'un slot SD.

Je cherche quelque chose de simple à programmer, avec suffisamment de mémoire pour ne pas être bloqué.
Pour l'instant ma préférence va plutôt au Yun, mais il va falloir attendre !

Je suis preneur de vos conseils, que ce soit pour le matériel ou pour la partie programmation.
Le site web est déjà créé, je travaille actuellement sur l'affichage des valeurs avec Google Charts.

PS : il y a quelques temps, j'ai acheté un ESP-01S.
Erreur de ma part, je ne m'étais pas assez documenté, du coup je le laisse de côté pour ce projet.