Erreur ouverture de fichier sur carte SD

Bonjour, Il y a quelque jours, j'ai posté au sujet d'un fichier corrompu sur une carte SD lors du setup. Je viens de trouver la ligne qui pose problème. Mais je ne comprend pas car ce niveau de mon code fonctionne parfaitement depuis un bon moment. Dans mon setup, j'ai une séquence de boot dont voici un extrais:

...
//Buzzer------------------------------------------------------------------
  t = 100;                                                     //Bip de démarage
  Buzzer();

  //SD Card-----------------------------------------------------------------
  while (!SD.begin(4))                                          // Boucle tant qu'il n'y a pas de carte SD
  {
    Serial.println("Erreur carte ou Pas de carte SD!");
    sd = 0;
    t = 2000;                                                   // Bip de 2 seconde
    Buzzer();
    delay(2000);
  }
  Etat = "##################################";
  FilDeLo();
  Etat = "Carte SD Started!";
  FilDeLo();                                                    // Ecrit l'évenement sur la SD
  sd = 1;

  //Base De Données sur SD--------------------------------------------------
  Serial.println("Charge Base de donnee ");
  Fichier = "BDD.TXT";
  BaseDeDonnees(BDD);                                          [color=red] La fonction qui appelle le fichier endomagé[/color]
  Serial.println("Base de donnee ok");                          // Extraction

  //GSM Sim800l-------------------------------------------------------------
...

Si dessous la fonction Fil de l'eau

int FilDeLo()
{
  //-----------------------
  Rtc();
  texte = horloge;                                       //composition de la ligne de texte
  texte += " -- ";
  texte += Etat;
  File dataFile = SD.open("FILDELO.TXT", FILE_WRITE);    [color=red]Voici la ligne qui génère le bug[/color]
  if (dataFile)                                          //Si le fichier est dispo sur la carte, on écrit dedans
  {
    dataFile.println(texte);
    dataFile.close();
    Serial.println(texte);
  }
  else {                                                 //Si le fichier n'est pas dispo sur la carte on génère une erreur
    Serial.println("Erreur fichier inaccessible sur la carte");
  }
  //-----------------------
}

Il semble que cette ligne corrompe le fichier 'BDD.TXT' que j'ouvre par la suite dans la fonction 'BaseDeDonnees(BDD)'. Je suis obligé de le remplacer car des éléments y sont effacé et d'autres écrites.

Pour vous, qu'es qui cloche? Merci.

La fonction qui charge la base de données:

//Chargement base de données
String BaseDeDonnees(String tab[41][8])
{
  // Ouvre le  fichier de configuration
  File config_file = SD.open(Fichier, FILE_READ);
  //Serial.println("Lecture carte SD!");

  //------------------------------------------------
  while (config_file.available() > 0 )                        // Tant que non fin de fichier
  {
    y = 0;                                                    // Initialisation du numerot de olonne
    i = 0;                                                    // nombre de carractere de la ligne
    while ((SDbuffer[i++] = config_file.read()) != '\n')      // Récupère une ligne entière dans le buffer
    {}
    if (SDbuffer[0] == '\0' || SDbuffer[0] == '/') continue;  // Ignore les lignes vides ou les lignes de commentaires
    SDbuffer_lenght = i;                                      // On garde de côté le nombre de char stocké dans le buffer
    SDbuffer[i - 1] = '\t';                                   // Remplace le dernier carractere (\n par \t) pour uniformiser

    j = 0;                                                    // Position du carractere dans la cellule
    while (i > 0)                                             // Travaille sur les colonnes du tableau
    {
      while (SDbuffer[SDbuffer_lenght - i] != '\t')           // Travaille sur les lignes du tableau
      {
        buffer2[j] = SDbuffer[SDbuffer_lenght - i];           // Ajoute un carracterre dans la cellule
        i--;                                                  // Décompte le nombre de carracteres restant
        j++;                                                  // Position du carractere dans la cellule
      }
      buffer2[j] = '\0';                                      // Cloture la cellule
      i--;
      j = 0;
      String buffer3 = String(buffer2);                       // Transforme la valeur en String
      //Serial.println(buffer3);
      tab[x][y] = buffer3;                                    /* Stoque la valeur dans le tableau           /!\    */
      y++;                                                    // Passe à la colone suivante
    }
    x++;                                                      // Passe à la ligne suivante
  }
  config_file.close();                                        // Ferme le fichier de configuration
  return tab[41][8];
  //------------------------------------------------
}

Merci

Ca ne parle à personne?

pour le problème du fichier, je ne sais pas, mais en revanche sur :

if (SDbuffer[0] == '\0' || SDbuffer[0] == '/') continue;  // Ignore les lignes vides ou les lignes de commentaires

est-ce que ça ne devrait pas plutot être SDbuffer[0] == '\n' pour ignorer une ligne vide ? Il me semble qu'une ligne vide va contenir \n\t\0 ou \n\0 (selon la terminaison de ligne windows/unix) mais pas directement \0

et aussi à la fin tu fais : return tab[41][8]; est-ce que c'est bien le but de retourner uniquement cette valeur précise du tableau ? (uniquement celle correspondant aux indices 41 et 8 ) De plus cette valeur qui est retournée n'est utilisée à priori nulle part, puisque quand la fonction BaseDeDonnee() est appelée dans ton code rien ne lit cette valeur. Du coup je ne vois pas bien comment ce qui est lu dans la fonction et chargé dans tab va se recopier dans BDD... ou alors il faudrait passer la référence vers BDD à la fonction, au lieu de copier BDD dans tab, et de ne rien en faire ensuite. Ou alors y'a un truc que j'ai pas suivi.

Il me semble que tu pourrais faire plutot BDD = BaseDeDonnee(); pour appeler la fonction.

et ensuite à la fin de la fonction BaseDeDonnee faire return tab; (sans spécifier d'indices) de sorte que tout le tableau soit copié dans le tableau BDD. Mais à ce compte là si BDD est global (j'en sais rien) pourquoi ne pas travailler directement avec lui dans la fonction ?

Bonjour bricofoy,

bricofoy: est-ce que ça ne devrait pas plutot être SDbuffer[0] == '\n' pour ignorer une ligne vide ? Il me semble qu'une ligne vide va contenir \n\t\0 ou \n\0 (selon la terminaison de ligne windows/unix) mais pas directement \0

Je viens de faire l’essai, l'un ou l'autre donne le même résultat.

bricofoy: et aussi à la fin tu fais : return tab[41][8]; est-ce que c'est bien le but de retourner uniquement cette valeur précise du tableau ? (uniquement celle correspondant aux indices 41 et 8 ) De plus cette valeur qui est retournée n'est utilisée à priori nulle part, puisque quand la fonction BaseDeDonnee() est appelée dans ton code rien ne lit cette valeur. Du coup je ne vois pas bien comment ce qui est lu dans la fonction et chargé dans tab va se recopier dans BDD... ou alors il faudrait passer la référence vers BDD à la fonction, au lieu de copier BDD dans tab, et de ne rien en faire ensuite. Ou alors y'a un truc que j'ai pas suivi.

Il me semble que tu pourrais faire plutot BDD = BaseDeDonnee(); pour appeler la fonction.

et ensuite à la fin de la fonction BaseDeDonnee faire return tab; (sans spécifier d'indices) de sorte que tout le tableau soit copié dans le tableau BDD. Mais à ce compte là si BDD est global (j'en sais rien) pourquoi ne pas travailler directement avec lui dans la fonction ?

Finalement, BDD est créé comme variable globale et du coup j'ai abandonné tab et de ce fait la ligne 'return tab[41][8];'

Je cherche encor d’où viens mon bug.

bonjour,
as tu essayé les exemples de la lib SD pour voir si ce n’est pas la carte ou le lecteur qui pose pb?
formattage de la SD en fat 32 et fais les tests après

Bonjour, J'ai effectivement reformaté la SD en fat 32, et j'ai essayé la fonction séparément. Mais le bug sur 'BDD' arrive quand on ouvre le fichier 'Fildelo'. Le problème peut il venir du nom du fichier 'File' tampon qui est différent dans les 2 fonctions?

Zarb94: Bonjour, J'ai effectivement reformaté la SD en fat 32, et j'ai essayé la fonction séparément. Mais le bug sur 'BDD' arrive quand on ouvre le fichier 'Fildelo'. Le problème peut il venir du nom du fichier 'File' tampon qui est différent dans les 2 fonctions?

c'est ce que j'allais dire après que tu ais fait le test.

2 noms de fichiers

 Serial.println("Charge Base de donnee ");
  Fichier = "BDD.TXT";
File dataFile = SD.open("FILDELO.TXT", FILE_WRITE);

J’ai trouvé!
Des fois le hasard… J’avais donc fais un code reprenant uniquement la fonction ‘BaseDeDonnees()’ et je viens de me rendre compte que le tampon était trop petit par rapport aux taille de lignes. Je viens de l’augmenter, charger mes codes pour test et c’est reparti.
Merci pour votre aide. Point positif, j’ai suivi quelques conseil de bricofoy et désormais, j’utilise un tableau globale.

HS
Dans cette même fonction, à la fin, je prend mon char extrait de la base de données, je le converti en string et je le rentre dans mon tableau.
Selon vous y aurait il un moyen d’optimiser tout ça car je trouve toute cette partie laborieuse ‘String buffer3 = String(buffer2);’ et ça utilise beaucoup de variables.

Pourquoi ne pas charger directement tes lignes du fichier caractère par caractère dans chaque lignes d'un tableau de char ? au final tu auras quasiment la même chose sans tout "l'emballage" propre au type String.

Quitte à convertir au cas par cas une ligne du tableau en String si tu as des opérations à faire dessus comme rechercher un extrait ou autre