Comment lire le contenu d'un fichier LittleFS

Bonjour à toutes et à tous,

je deviens de plus en plus chèvre.

Avec un fichier LittleFS,si j'écris : Serial.println(file.read());, je vois bien sur le moniteur série, le contenu de la ligne lue.

Or, le résultat de file.read() est un entier !!

Si j'écris String str = file.read(); j’obtiens bien entendu une erreur.

Alors, comment je fais pour mettre le résultat de file.read(); dans un String ?

Cordialement.

Pierre.

Peut-être bien String str = String(file.read()); pour convertir l'entier en String.

https://docs.arduino.cc/built-in-examples/strings/StringConstructors/

En utilisant cette méthode, je vois que file.read() ressort la valeur ASCII de chaque caractère contenu dans mon fichier.

Si j'utilise char str = char(file.read());, je ressors les caractères eux-mêmes.

Je vais essayer de me débrouiller avec ça.

Mon but est de ressortir les valeurs numériques de mon fichier qui ressemble à ça :

"PA = ",3000\n
"Tmax = ",70\n
"Tmin = ",65\n
"Tseuil = ",50\n

Cordialement.

Pierre.

bizarre... read() ne lit qu'un octet, pas tout le fichier.

De mémoire, il doit exister readBytes pour lire plusieurs octets.
Probablement lié à ça :

file.readBytes(buffer, length)

Ce n'est pas ce que dit @ChPr, il parle juste de read() mais ne parle pas de la taille.

La fonction read() retourne un entier qui est indicatif du succès de l'opération, il faut aller chercher le résultat dans le buffer

➜ faudrait comprendre comment @ChPr utilise read() où quelle bibliothèque (GitHub - lorol/LITTLEFS: LittleFS library for arduino-esp32 ?)

Bon, j'ai été imprécis dans ce que j'ai dit. Ce n'est pas un Serial.Println(), mais un Serial.write() que j'ai fait. Voilà le code.

Pour autant, ce qui m'a troublé, est l'affichage dans le moniteur série, qui se résume à 5 lignes, malgré que le compteur d'opération soit à 65, ce qui est le nombre de caractères du fichier et donc le nombre de Serial.write().

    uint8_t i = 0;
    while(file.available()) {
      Serial.write(file.read());
      i++;
    }
    Serial.print("i = ");Serial.println(i);
PA : ,3000
Tmax : ,60.00
Tmin : ,58.00
Tseuil : ,54.00
Mode : ,1
i = 65

Cordialement.

Pierre.

OK

ceci explique cela.

dans votre cas vous utilisez l'API read() qui renvoie un entier. Cet entier vaut -1 s'il y a erreur de lecture et si la lecture s'est bien passée, l'octet lu est dans l'octet de poids faible de cet entier.

Comme vous testez file.available(), le read() va toujours fonctionner et retourner dans son octet de poids faible le caractère lu et ça tombe bien puisque lorsqu'on passe un int à une fonctoin attendant un byte (votre Serial.write()) le compilateur extrait l'octet de poids faible.

Si vous voulez accumuler cela dans un buffer

    uint8_t i = 0;
    char bufferChar[100]; // assez grand
    while(file.available()) {
      char r = file.read(); // tronque l'entier et prend l'octet de poids faible
      Serial.write(r);
      bufferChar[i++] = r; // il faudrait tester qu'on ne déborde pas, j'ai la flemme là
    }
    bufferChar[I] = '\0'; // on termine le buffer proprement,il faudrait tester qu'on ne déborde pas, j'ai la flemme là

ou avec une String

    uint8_t i = 0;
    String bufferString;
    while(file.available()) {
      char r = file.read(); // tronque l'entier et prend l'octet de poids faible
      Serial.write(r);
      bufferString += r; 
      i++;
    }

read() lit un octet sans l'interpréter et le passe à write() qui le transfert sans l'interpréter.

Donc ton fichier ne contient pas un entier, il contient la représentation textuelle d'un entier.

Au final, quel et ton problème? Qu'est-ce que tu veux faire exactement?

Je l'ai annoncé dans le post #3 et je viens de le résoudre (un premier jet) avec les deux fonctions suivantes :

bool litOctet(char chr, char *res) { 
  *res = chr; // Retourne dans res le caractère reçu
  return chr != '\n'; // Retourne vrai tant que ce n'est pas '\n'
}

void initParams(String fchIni) {
  if (!LittleFS.exists(fchIni)) { // Création du fichier
    File file = LittleFS.open(fchIni, FILE_WRITE);
    file.print("PA : ," + String(pMaxSurplus) + "\n");
    file.print("Tmax : ," + String(teta0Max) + "\n");
    file.print("Tmin : ," + String(teta0Min) + "\n");
    file.print("Tseuil : ," + String(teta0Seuil) + "\n");
    file.print("Mode : ," + String(modeFct) + "\n");
    file.close();
  } else { // Lecture du fichier
    File file = LittleFS.open(fchIni);
    String str[5] = {"", "", "", "", ""}; // Initialisation des 5 chaînes
    char chr;
    uint8_t i = 0;
    while(file.available()) {
      while (char(file.read()) != ',' && file.available()) { // Ne lit rien jusqu'à la ','
      }
      while (litOctet(file.read(), &chr) && file.available()) { // Lit les octets jusqu'au '\n'
        str[i] += chr;
      };
      Serial.println(str[i]); // Ecrit chacune des 5 chaînes
      i++;
    }
    file.close();
  }
}

Cordialement.

Pierre.

Je pense qu’il voulait dire que read retourne un int pas un byte.

Comme je l’ai expliqué ça sert à retourner soit l’octet lu, soit une valeur d’erreur (qui sera codée sur les octets supplémentaires - si ça retournait qu’un byte on ne pourrait pas savoir puisque les 256 valeurs sont possibles).

Il faut faire le test dans l’autre sens

Tester déjà s’il y a quelque chose à lire et si oui vous le lisez

while (file.available() && file.read() != ',') ….

Quand vous faites un ET logique entre deux conditions le compilateur s’arrête dès qu’il connaît le résultat donc ici si on n’a rien à lire, on n’essaye pas de faire read().

Sinon je ne comprends pas pourquoi vous avez écrit cette fonction, c’est un peu la même écriture pour attendre la fin de ligne

char r;
while (file.available() && (r= file.read()) != '\n`) …. // ajouter r à la chaîne 

Ou plus lisible

while(file.available()) {
  char r = file.read();
  if (r == '\n') break; // on sort du while, on a Lu la ligne
  str[i] += r;
}

C'est vrai, j'avais mis file.available() dans mes tests pour ne tomber dans une boucle infinie, mais il effectivement plus judicieux de le mettre en premier.

Pour la deuxième boucle while, je n'avais pas trouvé de manière élégante sans employer une fonction annexe ; vous me l'avez fournie.

Cordialement.

Pierre.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.