Lister les fichiers d'une carte SD

Bonjour,

Je cherche à lister les fichiers d'une carte SD pour les intégrer ensuite dans un tableau de fichiers.
J'utilise cet exemple, mais tous les fichiers ne sont pas listés.

#include <SPI.h>
#include <SD.h>

#define path "/"
#define CSPin 10

String *songList;
File dir;
int nSongs = 0;


void setup() {
  Serial.begin(115200);
  while(!Serial){delay(0);}

  Serial.println("Program started");
  if (!SD.begin(CSPin)) {
    Serial.println("SD initialization failed!");
    //while (1);
  }
  Serial.println("SD initialization done.");

  dir = SD.open(path);
  listSongs(dir);
}

void loop() {
  // put your main code here, to run repeatedly:

}



void listSongs(File folder){
  nSongs = 0;

  while(true){
    File entry = folder.openNextFile();
    if(!entry){
      folder.rewindDirectory();
      break;
    }else{
    nSongs++;
    }   
    entry.close();
  }

  Serial.print("Songs found:");
  Serial.println(nSongs);

  songList =(String*) malloc(nSongs);

  Serial.println("Songs List:");

  for(int i = 0; i < nSongs; i++){
    File entry = folder.openNextFile();
    songList[i] = entry.name();
    entry.close();
    Serial.println((String)songList[i]);
  }
}

J'ai des fichiers de type .STL et .IDL.
Exemple:

DSL-LTL.IDL, DSL-LTL.STA

Je voudrais que la liste des fichiers *.IDL fasse apparaitre les fichiers dans la console série l'un après l'autre séparés par une virgule et sans le suffixe.
Par exemple:

List Motors:DSL-LTL, DSL-BIG

J'obtiens ça:

Program started
SD initialization done.
Songs found:27
Songs List:
SYSTEM~1
DSL-LTL.IDL
DSL-LTL.STA

Alors que ma liste est la suivante:

  DSL-LTL.IDL    	
  DSL-LTL.STA    	
  DSL-BIG.IDL    	
  DSL-BIG.STA    	
  DSL-120.IDL   
  DSL-120.STA    
  DSL-180.IDL    		
  DSL-180.STA

Merci pour votre aide.

Pierre

Le code actuel rencontre quelques problèmes pour générer une liste correcte des fichiers .IDL de votre carte SD, probablement en raison de l'utilisation incorrecte de malloc et de la façon dont vous lisez les fichiers. Voici une version améliorée qui devrait résoudre ces problèmes :

Filtrez les fichiers pour n'inclure que ceux ayant l'extension .IDL. Supprimez le suffixe .IDL pour chaque nom de fichier avant de l'ajouter à la liste. Stockez les noms de fichiers dans un tableau dynamique, en les séparant par des virgules pour l'affichage.

Voici le code corrigé

#include <SPI.h>
#include <SD.h>

#define CSPin 10

String *songList;
File dir;
int nSongs = 0;

void setup() {
  Serial.begin(115200);
  while (!Serial) { delay(0); }

  Serial.println("Program started");
  if (!SD.begin(CSPin)) {
    Serial.println("SD initialization failed!");
    return;
  }
  Serial.println("SD initialization done.");

  dir = SD.open("/");
  listSongs(dir);
}

void loop() {
  // Empty loop
}

void listSongs(File folder) {
  nSongs = 0;

  // Compter le nombre de fichiers `.IDL`
  while (true) {
    File entry = folder.openNextFile();
    if (!entry) {
      folder.rewindDirectory();
      break;
    }
    if (String(entry.name()).endsWith(".IDL")) {
      nSongs++;
    }
    entry.close();
  }

  Serial.print("Songs found: ");
  Serial.println(nSongs);

  // Allouer de la mémoire pour stocker les noms des chansons
  songList = new String[nSongs];
  
  int songIndex = 0;
  
  // Lire les fichiers et les stocker dans `songList`
  while (true) {
    File entry = folder.openNextFile();
    if (!entry) {
      folder.rewindDirectory();
      break;
    }

    String fileName = entry.name();
    if (fileName.endsWith(".IDL")) {
      // Retirer le suffixe ".IDL"
      fileName = fileName.substring(0, fileName.length() - 4);
      songList[songIndex++] = fileName;
    }
    entry.close();
  }

  // Afficher la liste des fichiers dans la console série
  Serial.print("List Motors: ");
  for (int i = 0; i < nSongs; i++) {
    Serial.print(songList[i]);
    if (i < nSongs - 1) {
      Serial.print(", ");
    }
  }
  Serial.println();

  // Libérer la mémoire allouée
  delete[] songList;
}

Merci beaucoup,

Ca fonctionne parfaitement :slight_smile:

Autre question :slight_smile:

J'utilise les sons avec la fonction suivante:
void play(const char *filename)

Je voudrais donc reconstruire le nom réel du son en char*

J'ai essayé ça, mais ça ne fonctionne pas.

String SOUNDMOTOR="DSL-LTL";
String Idl;
String Sta;

...

    Idl = SOUNDMOTOR + ".IDL";
    Sta = SOUNDMOTOR + ".STA";

    int str_len1 = Idl.length() + 1;
    int str_len2 = Sta.length() + 1;
    // Prepare the character array (the buffer) 
    char char_array1[str_len1];
    char char_array2[str_len2];
    // // Copy it over 
    Idl.toCharArray(char_array1, str_len1);
    Sta.toCharArray(char_array2, str_len2);

Pour ensuite lancer une commande:

tmrpcm.play(Sta);

ou

tmrpcm.play(Idl);

Je pense avoir trouvé en utilisant:

    Idl = SOUNDMOTOR + ".IDL";
    Sta = SOUNDMOTOR + ".STA";

...

tmrpcm.play(Sta.c_str());//.STA

En tout cas, ça compile, reste à voir si c'est bien le son que je veux qui est lancé.

Bonsoir pierrotm777

Si ça ne fonctionne pas, ajoute le path:
#define path "/"
devant le nom du fichier:
Idl = path + SOUNDMOTOR + ".IDL";

Cordialement
jpbbricole

ça fait très chatGPT comme style :slight_smile:

Ok, merci pour ton aide.
A+

Vous auriez écrit ça comment ? :slight_smile:

Ecrit quoi ?

Vous écrivez "ça fait très chatGPT comme style".

Comment auriez vous écrit ça ?

autrement :slight_smile:

Je ne dis pas que ce n'est pas du français, je dis que c'est une tournure de phrase que chatGPT utilise.

Je me demande donc si @aliarifat794 n'avait pas utilisé chatGPT pour vous répondre :interrobang: (comme vous auriez pu le faire d'ailleurs pour avoir des idées)

Après je peux me tromper, c'était juste une interrogation

Je n'ai jamais encore utilisé chatGPT pour trouver une solution de code.
Un ami l'a fait afin de tenter de trouver comment le CRC d'un récepteur Graupner SPCM est calculé.
chatGPT n'avait pas donné de résultat faute d'un DUMP du récepteur trop court !
Mais je pense bien y revenir :slight_smile: