Erreur SD begin

Bonjour, j’ai fait un programme pour enregistrer sur une carte SD les données d’un capteur, tout fonctionne le fichier se crée, par contre de temps en temps j’ai une erreur avec SD begin et donc la carte SD n’est pas initialisée , je doit enlever la SD la remettre et reset pour que le programme se lance.

Merci,

/* Dépendances */
#include <SPI.h> // Pour la communication SPI
#include <SD.h>  // Pour la communication avec la carte SD


/** Broche CS de la carte SD */
const byte SDCARD_CS_PIN = 4; // A remplacer suivant votre shield SD

/** Nom du fichier de sortie */
const char* OUTPUT_FILENAME = "PAR.csv";


/** Fichier de sortie avec les mesures */
File file;


/** Fonction setup() */
void setup() {
  analogReference(INTERNAL1V1); //Prend 1,1v comme réference
  /* Initialisation du port série (debug) */
  Serial.begin(115200);
  /* Initialisation du port SPI */
  pinMode(4, OUTPUT);
  pinMode(53, OUTPUT); // Arduino UNO
  digitalWrite(4,HIGH);

  /* Initialisation de la carte SD */
  Serial.println(F("Initialisation de la carte SD ... "));
  if (!SD.begin(4)) {
    Serial.println(F("Erreur : Impossible d'initialiser la carte SD"));
    Serial.println(F("Verifiez la carte SD et appuyez sur le bouton RESET"));
    for (;;); // Attend appui sur bouton RESET
  }

  /* Ouvre le fichier de sortie en écriture */
  Serial.println(F("Ouverture du fichier de sortie ... "));
  file = SD.open(OUTPUT_FILENAME, FILE_WRITE);
  if (!file) {
    Serial.println(F("Erreur : Impossible d'ouvrir le fichier de sortie"));
    Serial.println(F("Verifiez la carte SD et appuyez sur le bouton RESET"));
    for (;;); // Attend appui sur bouton RESET
  }
  
  /* Ajoute l'entête CSV si le fichier est vide */
  if (file.size() == 0) {
    Serial.println(F("Ecriture de l'entete CSV ..."));
    file.println(F("Date; tension(mv); PAR(µE)"));
    file.flush();
  }
}


/** Fonction loop() */
void loop() {

  /* Réalise la mesure */
 float valeurlue = analogRead(A0); //Lit la valeur de l'entrée 0 comprise entre 0 et 1023 en comparant avec la référence (1023= 0v ; 0=1,1v)
 float tension = valeurlue *(1,1/1023);
 int PAR = tension * (1000 / 30); //Conversion car 1000µE = 30mv  A CHANGER APRES ETALLONAGE
 int date= 5;
  /* Affiche les données sur le port série pour debug */ 
  
  Serial.print(valeurlue);
  Serial.print(F("; "));
  Serial.print(tension);
  Serial.print(F("; "));
  Serial.println(PAR);
   
  /* Enregistre les données sur la carte SD */
  file.print(date);
  file.print(F("; "));
  file.print(tension);
  file.print(F("; "));
  file.println(PAR);
  file.flush();
  delay(10000);
}

Certainement une carte SD de mauvaise qualité...

SD.h est une copie d’une ancienne version de la librairie SDFat. Il y a des évolutions dans SDFat qui font qu’elle est plus performante → utilisez SdFat

Parfois suivant les cartes, le begin() ne répond pas la première fois - des soucis de vitesse de clock ou si vous avez plusieurs appareils sur le bus SPI.

Vous pourriez éventuellement essayer quelques fois de suite

bool sdCardErreur = true;
for (byte i = 0; i < 10; i++) {
  sdCardErreur  = (SD.begin(CS_PIN) != 0);
  if (!sdCardErreur) break;
  delay(500); // on attend un peu avant de re-essayer
}

if (sdCardErreur) {
    Serial.println(F("Erreur begin()"));
    while(1); // on bloque car la carte ne fonctionnera pas
}

Dans cette bibliothèque, il existe la fonction errorHalt () que tu pourrais insérer avant ou à la place du while (1) pour afficher les messages d'erreur renvoyés par la carte. Ça donnerait éventuellement d'autres informations sur le pourquoi du problème.

Effectivement (pas besoin du while() si vous le mettez avant car le halt arrête tout - ça appelle une autre fonction de la librairie qui boucle sans fin) - on peut aussi utiliser errorPrint() dans la boucle for pour afficher les erreurs sans arrêter