Problème inconnu avec le lecteur/carte SD.

Bonjour à la communauté !

Alors, jusqu'a présent, je me contentais toujours de parcourir les forums et, en général, je trouvais réponse à mes questions. Mais, aujourd'hui, je n'ai plus le choix. Je me trouve dans une impasse.

Peux importe les solutions que je trouve en parcourant les forums, elle marche, puis elle marche plus et ca dans une boucle while(1)......

Bref !

Je remercie d'avance l'ensemble des personne qui participeront à ce post.


Mon projet :

Je possède un atelier que je qualifierai, d'atelier de mécanique.
Problème --> taux d'humidité haut et température basse = rouille sur les machines et outils
Solution :
Mesurer l'humidité et l'hydrométrie pour mettre en route une soufflerie afin de renouveler l'air. (souvent, il fait plus chaud à l'extérieur de l'atelier)
(souvent, il fait plus chaud à l'extérieur de l'atelier) (mesure du delta T sur 1 semaine avec prise de mesure 1/h).Refaire la porte de l'atelier, mais, avant, voir la résistance thermique de la porte de l'atelier.


J'ai donc utilisé un Arduino UNO pour réaliser ces mesures avec les équipements suivants :
capteur BME680 dans l'atelier
capteur BME280 à l'extérieur
un lecteur de carte SD pour récupérer les mesures pour ensuite exploiter les mesures.

Il y a environ 4 mois, après avoir tout assemblé sur une carte percé, tout fonctionnais bien.

Aujourd'hui, j'ai repris le projet et je me retrouve avec de gros dysfonctionnements avec le lecteur ou la carte SD ou les deux.

Après avoir lu beaucoup de forum sur le sujet de la carte SD, j'ai intégré un circuit intégré 74HC125 afin de baisser la tension du BUS SPI à la carte SD. (apparemment la carte SD travail en 3,3V)

Au début, cela fonctionnait bien, puis le lendemain, plus rien ne fonctionnais.

j'ai donc continué mes recherches, et je suis tombé sur une nouvelle bibliothèque "SdFat.h" , la

De nouveau, tout fonctionnait ! Puis le lendemain, plus rien !

Je ne sais absolument plus quoi faire du tout.
Et je n'ai absolument aucune envie d'abandonner ce super projet qui pourrait grandement régler mon problème.

Mais aussi de formater en FAT16 puis en FAT32.

Sur une carte SD (2Go), je n'arrive même plus à la formater, car elle serait devenue protéger ... J'ai cherché à comment hoter la protection mais rien n'y fait.

Du coup, il me reste qu'une carte SD de 16Go en FAT32 qui "fonctionne" à moitié ...
En gros, avec la librairie d'Arduino, je lance le programme CardInfo qui indique si la carte et bien connecté, bien inséré, etc et le type de carte avec sont format (Fat xx).
Et un coup sur 100 il trouve la carte, mais dit que le format n'est pas bon. (même après reformage en FAT32 avec un pc Windows).
Ou alors il fonctionne UNE fois et après c'est terminer pour les autres 100 fois. Enfin voilà. Je ne sais plus du tout quoi faire... Cette maudite carte SD me rend fou !Ah, aussi, j'ai acheté un deuxième lecteur, mais fonctionne toujours po...

Je suis impatient d'échanger avec vous, et en espérant que l'on puisse trouver une solution à ce problème.

Pour ce qui est du code :

#include <SPI.h>
#include <Wire.h> 
#include "Adafruit_BME680.h"
#include "SparkFunBME280.h"
#include "SdFat.h"
SdFat SD;

#define PIN_BME_INT 4
#define PIN_SD 10
#define ADRESSE_BME280 0x76 //Uses default I2C address 0x76 or 0x77
#define PIN_LED_GREEN 3
#define PIN_LED_RED 2
#define PIN_START 6
#define NB_JOUR 7
#define NB_HEURE 24
#define NB_HEURES_EN_MINUTE 250//60000//0x36EE80 // 3 600 000 ms in HEX --> 1 heure



void setup() {
  
  // ******************* DECLARATION DES VARIABLES *******************
  BME280 bme280_out; //Variable de type BME280 
  Adafruit_BME680 bme680_in(PIN_BME_INT);//Variable de type BME680
  File dataHygro; //Variable de type File (stock le fichier pour l'écriture)
  String nomFichier = "HYG.txt";  
  uint8_t nbJour = 0, nbHeure = 0;
  // ******************* DECLARATION DES VARIABLES *******************


  // ******************* INITIALISATION CARTE *******************
  Wire.begin();

  pinMode(PIN_LED_GREEN,OUTPUT);
  pinMode(PIN_LED_RED,OUTPUT);
  pinMode(PIN_SD,OUTPUT);
  //pinMode(10,OUTPUT); // si SD autre que 10 ...
  pinMode(PIN_START,INPUT_PULLUP);
  // ******************* INITIALISATION CARTE *******************


  // ******************* INITIALISATION CARTE SD *******************
  if(!SD.begin(PIN_SD)) erreurInitialisation("carteSD");
  // ******************* INITIALISATION CARTE SD *******************
  

  // ******************* OUVERTURE FICHIER + ECRITURE ENTETES (créer le fichier si non présent) *******************
  delay(20);
  if(!(dataHygro = (SD.open(nomFichier,FILE_WRITE)))) erreurInitialisation("ouvertureFichierEcriture");
  dataHygro.println("Jour;Heure;Temperature_in;Temperature_out;Hygrometrie_in;Hygrometrie_out");
  dataHygro.close();
  // ******************* OUVERTURE FICHIER + ECRITURE ENTETES (créer le fichier si non présent) *******************


  // ******************* INITIALISATION CAPTEUR INTERIEUR "bme680_in" *******************
  bme680_in.setTemperatureOversampling(BME680_OS_8X);
  bme680_in.setHumidityOversampling(BME680_OS_2X);
  bme680_in.setPressureOversampling(BME680_OS_4X);
  bme680_in.setIIRFilterSize(BME680_FILTER_SIZE_3);
  bme680_in.setGasHeater(320, 150); // 320*C for 150 ms
  delay(20);
  if(!bme680_in.begin()) erreurInitialisation("capteurInterieur");
  // ******************* INITIALISATION CAPTEUR INTERIEUR "bme680_in" *******************


  // ******************* INITIALISATION CAPTEUR EXTERIEUR "bme280_out" *******************
  bme280_out.settings.commInterface = I2C_MODE;
  bme280_out.settings.I2CAddress = ADRESSE_BME280;  
  //bme280_out.setI2CAddress(ADRESSE_BME280);
  bme280_out.settings.runMode = 1;
  bme280_out.settings.filter = 0;
  bme280_out.settings.tStandby = 0;
  bme280_out.settings.tempOverSample = 1;
  bme280_out.settings.pressOverSample = 1;
  bme280_out.settings.humidOverSample = 1;
  delay(10);
  if(!bme280_out.begin()) erreurInitialisation("capteurExterieur");
  // ******************* INITIALISATION CAPTEUR EXTERIEUR "bme280_out" *******************



  // ******************* FREEZE LE CODE *******************
  do {
    digitalWrite(PIN_LED_RED,HIGH);
    delay(500);
    digitalWrite(PIN_LED_GREEN,HIGH);
    delay(500);
    digitalWrite(PIN_LED_RED,LOW);
    delay(350);
    digitalWrite(PIN_LED_GREEN,LOW);
    delay(350);
  } while(digitalRead(PIN_START));
  // ******************* FREEZE LE CODE *******************


  
    // ******************* ACQUISITION DES DONNEES -- TOUTES LES HEURES __ PENDANT 1 SEMAINE *******************
    do  {
      for(nbJour = 1; nbJour <= NB_JOUR; nbJour++) {
        for(nbHeure = 1; nbHeure <= NB_HEURE; nbHeure++)  {
      
        if(!(dataHygro = (SD.open(nomFichier,FILE_WRITE)))) erreurInitialisation("ouvertureFichierEcriture");
        if (!bme680_in.performReading()) erreurInitialisation("lectureCapteurBME680");
   
        dataHygro.print(ecritureJour(nbJour));
        
        dataHygro.print(";");
        dataHygro.print(nbHeure);
        dataHygro.print(";");
        
        dataHygro.print(bme680_in.temperature, 0);
        dataHygro.print(";");
        dataHygro.print(bme280_out.readTempC(), 0);
        dataHygro.print(";");
        
        dataHygro.print(bme680_in.humidity, 0);
        dataHygro.print(";"); 
        dataHygro.print(bme280_out.readFloatHumidity(), 0);
        dataHygro.print("\n");
        
        dataHygro.close();
   
        delay(NB_HEURES_EN_MINUTE);
          
        }
      }
    } while(nbJour < NB_JOUR);
    
    
    if(!(dataHygro = (SD.open(nomFichier,FILE_WRITE)))) erreurInitialisation("ouvertureFichierEcriture");
    dataHygro.print("FIN");
    dataHygro.close();

    
    digitalWrite(PIN_LED_GREEN,HIGH);
    while(1); // FREEZE
    
  // ******************* ACQUISITION DES DONNEES -- TOUTES LES HEURES __ PENDANT 1 SEMAINE *******************

}


void loop(void) {}


void erreurInitialisation(String errorLvl) {
  
  if (errorLvl == "carteSD") {
    while(1) {
      digitalWrite(PIN_LED_RED,HIGH);
      delay(350);
      digitalWrite(PIN_LED_RED,LOW);
      delay(350);
    }
  }
  if (errorLvl == "capteurInterieur") {
    while(1) {
      digitalWrite(PIN_LED_GREEN,HIGH);
      delay(350);
      digitalWrite(PIN_LED_GREEN,LOW);
      delay(350);
    }
  }
  if (errorLvl == "capteurExterieur") {
    while(1) {
      digitalWrite(PIN_LED_GREEN,HIGH);
      digitalWrite(PIN_LED_RED,HIGH);
      delay(350);
      digitalWrite(PIN_LED_RED,LOW);
      delay(350);
    }
  }
  if (errorLvl == "ouvertureFichierEcriture") {
    while(1) {
      digitalWrite(PIN_LED_RED,HIGH);
      digitalWrite(PIN_LED_GREEN,HIGH);
      delay(350);
      digitalWrite(PIN_LED_GREEN,LOW);
      delay(350);
    }
  }
  if (errorLvl == "lectureCapteurBME680") {
    while(1) {
      digitalWrite(PIN_LED_RED,HIGH);
      digitalWrite(PIN_LED_GREEN,HIGH);
    }
  }
  /*
  if (errorLvl == "fermetureFichier") {
    while(1) {
      digitalWrite(PIN_LED_RED,HIGH);
      digitalWrite(PIN_LED_GREEN,LOW);
      delay(350);
      digitalWrite(PIN_LED_RED,LOW);
      digitalWrite(PIN_LED_GREEN,HIGH);
      delay(350);
    }
  }*/
}


String ecritureJour(uint8_t jour) {

  switch (jour) {
    case 1 :
      return("Lundi");
      break;
    case 2 :
      return("Mardi");
      break;
    case 3 :
      return("Mercredi");
      break;
    case 4 :
      return("Jeudi");
      break;
    case 5 :
      return("Vendredi");
      break;
    case 6 :
      return("Samedi");
      break;
    case 7 :
      return("Dimanche");
      break;
  }

  return ("erreur");
}

Quelle carte? Une adafruit? Librairie SDfat d'origine ou fork?

  • La carte SD est une Sandisk 16GB
  • Le lecteur de carte SD est une version générique
  • J'utilise la version SDFat de Adafruit. (Mais 'ai aussi utilisé celle de fork, que je n'utilise plus d'ailleurs)

J'ai re tenté de faire fonctionner l'ensemble avec l'exemple SdInfo :
cela à marché !

18:37:33.901 -> SdFat version: 10100
18:37:33.901 -> 
18:37:33.901 -> Assuming the SD is the only SPI device.
18:37:33.901 -> Edit DISABLE_CHIP_SELECT to disable another devic
18:37:35.549 -> SdFat version: 10100
18:37:35.549 -> 
18:37:35.549 -> Assuming the SD is the only SPI device.
18:37:35.616 -> Edit DISABLE_CHIP_SELECT to disable another device.
18:37:35.653 -> 
18:37:35.653 -> Assuming the SD chip select pin is: 10
18:37:35.690 -> Edit SD_CHIP_SELECT to change the SD chip select pin.
18:37:35.757 -> 
18:37:35.757 -> type any character to start
18:37:38.260 -> 
18:37:38.260 -> init time: 124 ms
18:37:38.294 -> 
18:37:38.294 -> Card type: SDHC
18:37:38.294 -> 
18:37:38.294 -> Manufacturer ID: 0X3
18:37:38.331 -> OEM ID: SD
18:37:38.331 -> Product: SC16G
18:37:38.365 -> Version: 8.0
18:37:38.365 -> Serial number: 0X1DC315B7
18:37:38.402 -> Manufacturing date: 4/2014
18:37:38.440 -> 
18:37:38.440 -> cardSize: 15931.54 MB (MB = 1,000,000 bytes)
18:37:38.474 -> flashEraseSize: 128 blocks
18:37:38.511 -> eraseSingleBlock: true
18:37:38.545 -> OCR: 0XC0FF8000
18:37:38.545 -> 
18:37:38.545 -> SD Partition Table
18:37:38.582 -> part,boot,type,start,length
18:37:38.582 -> 1,0X0,0XC,8192,31108096
18:37:38.616 -> 2,0X0,0X0,0,0
18:37:38.653 -> 3,0X0,0X0,0,0
18:37:38.653 -> 4,0X0,0X0,0,0
18:37:38.690 -> 
18:37:38.690 -> Volume is FAT32
18:37:38.690 -> blocksPerCluster: 64
18:37:38.726 -> clusterCount: 485936
18:37:38.726 -> freeClusters: 485932
18:37:43.036 -> freeSpace: 15923.02 MB (MB = 1,000,000 bytes)
18:37:43.072 -> fatStartBlock: 8790
18:37:43.110 -> fatCount: 2
18:37:43.110 -> blocksPerFat: 3797
18:37:43.143 -> rootDirStart: 2
18:37:43.143 -> dataStartBlock: 16384
18:37:43.179 -> 
18:37:43.179 -> type any character to start

J'ai ensuite ressayé :

18:39:52.515 -> SdFat version: 10100
18:39:52.553 -> 
18:39:52.553 -> Assuming the SD is the only SPI device.
18:39:52.590 -> Edit DISABLE_CHIP_SELECT to disable another device.
18:39:52.624 -> 
18:39:52.660 -> Assuming the SD chip select pin is: 10
18:39:52.698 -> Edit SD_CHIP_SELECT to change the SD chip select pin.
18:39:52.735 -> 
18:39:52.735 -> type any character to start
18:39:55.493 -> error: cardBegin failed
18:39:55.530 -> SD errorCode: 0X25,0XFF
18:39:55.564 -> 
18:39:55.564 -> type any character to start

Et top ! Marche pas !

Les codes d'erreur indiquent, si j'ai bien compris, une erreur de câblage.
Or j'ai rien touché depuis ... Et j'ai testé la continuité de ma carte voir si j'avais pas de fuites, mais rien...

La ou j'ai trouvé les infos pour les codes, dans un fichier html dans le dossier SdFat Adafruit : index.html

J'ai ressayé un rebranchant et débranchant mon capteur BME680 en SPI et les codes d'erreur ont variés :

18:48:37.257 -> type any character to start
18:48:39.298 -> error: cardBegin failed
18:48:39.335 -> SD errorCode: 0X25,0XFF
18:48:39.368 -> 
18:48:39.368 -> type any character to start
18:48:51.392 -> error: cardBegin failed
18:48:51.429 -> SD errorCode: 0X37,0XC
18:48:51.429 -> 
18:48:51.429 -> type any character to start
18:48:57.345 -> error: cardBegin failed
18:48:57.383 -> SD errorCode: 0X43,0X1

0X25 --> avec ou sans carte ( sa dépend ...)
0X73 --> avec carte 2ème fois (reset)
0X43 --> avec carte 3ème fois (reset)
0X43 --> avec carte pour la 4ème fois (reset)

J'utilise le projet suivant d'enregistreur GPS. On a d'un côté une carte adalogger alimentée par USB/5 V mais qui fonctionne en interne en 3.3 V. On connecte la carte GPS qui peut être alimentée en 5 V ou en 3.3 V, depuis les sorties correspondantes de l'autre carte.

J'ai eu beaucoup de problème d'enregistrement des données. Ça démarrait correctement puis au bout de quelques minutes ou plusieurs heures, la carte principale redémarrait tout seule. Non seulement les fichiers de log en cours d'écriture étaient corrompus mais des fois c'était tout un dossier voir la carte qui devenait illisible. J'ai reformé un grand nombre de fois les cartes µSD avec le formateur officiel SD. Les cartes allaient très bien par ailleurs. J'ai pu les remplir de photos sur un PC et les relire sur un autre ordinateur. J'ai aussi une carte qui n'a jamais été reconnu par le script tout en étant saine par ailleurs. J'avais moins de plantage en alimentant la carte GPS en 5 V plutôt qu'en 3.3 V.

Finalement, à force de chercher sur internet, j'ai vu que l'auteur initial de la librairie SDFat se plaignait du fork d'adafruit qui poussait par défaut à fond les vitesses de transfert vers la carte SD par le bus SPI et qu'il recevait en retour beaucoup de signalement de bug. Alors, j'ai essayé de baisser la vitesse du bus SPI et ça a résolu mes problèmes:

  // Initialise SD card
  Serial.println("Initializing SD card...");
  // See if the SD card is present and can be initialized
//  if (!sd.begin(cardSelect, SD_SCK_MHZ(50))) {
  if (!sd.begin(cardSelect, SD_SCK_MHZ(4))) { // reducing SPI speed to avoid data corruption
    Serial.println("Panic!! SD Card Init failed, or not present!");
    Serial.println("Waiting for reset...");

Ça enregistre des heures sans plantage. La carte non reconnue fonctionne maintenant correctement. J'ai essayé d'enregistrer à 10 Hz ou lieu de 1 Hz et c'était stable.

Je ne sais pas si c'est le même problème pour toi mais, à voir les symptômes, je pense qu'il y a un problème sur le bus SPI. Vitesse? Conflit avec le capteur qui est aussi sur SPI?

Merci pour ton aide !

J'ai essayé avec ta méthode et cela a fonctionner !!!
Le plus étrange c'est qu'après avoir fait des tests, j'ai recommencé un nouveau code mais en oubliant de modifier la fréquence de communication !
Et cela fonctionne depuis quand même depuis plusieurs jours ...

Si le problème réapparait, je re modifierai la fréquence pour être certain que le problème viens de ce paramètre.

Merci encore pour ton aide précieuse.

Bonne continuation.
Martin

Merci pour le retour. Ça fait plaisir de savoir que l'aide a servi à quelque chose.

Sur le fond du problème, je ne sais pas d'où il vient. J'ai la sensation que l'histoire de la fréquence SPI est plus le symptôme d'un autre problème comme un défaut d'alimentation, sachant que j'utilise un composant assez consommateur, proche de 1W.