LOCODUINO

Parlons Arduino => Débuter => Discussion démarrée par: likiki le octobre 23, 2021, 09:55:01 am

Titre: Lecture d'une carte SD
Posté par: likiki le octobre 23, 2021, 09:55:01 am
Bonjour a tous,

Je rame depuis plusieurs jours sur la problème suivant:

J'ai des données sur une carte SD qui sont très simple.

0
-760
-1080
-1530
-1865
-2018


1) J'arrive a les écrire sur la carte dans une fichier .txt

2) j'arrive a les lire et a les afficher tel quel dans le moniteur série

3) je n'arrive pas a mettre chaque chiffre dans une variable distincte utilisée ensuite dans le programme du style :

don1 = 0
don2 = -760
don3 = -1080

etc etc

Je sèche grave et ne trouve rien sur le net la dessus.

Par avance, merci de votre aide.
Titre: Re : Lecture d'une carte SD
Posté par: Dominique le octobre 23, 2021, 11:10:58 am
Je vous propose de regarder les tableaux de variables avec un index permettant de se déplacer dans le tableau en même temps que la lectures des données dans la carte SD.

Cet article pourrait vous aider:
 https://www.locoduino.org/spip.php?article227 (https://www.locoduino.org/spip.php?article227)
Titre: Re : Lecture d'une carte SD
Posté par: chris_bzg le octobre 23, 2021, 12:02:22 pm
Bonjour Christian,

Si les données de la carte SD ont été écrites dans un fichier .TXT, alors ce sont des chaînes de caractères ASCII. En conséquence, tu ne peux pas affecter une chaîne de caractères dans une variable numérique.
Il faut au préalable transformer cette chaîne de caractères en une valeur numérique.
Ou bien changer le mode d'écriture sur la carte SD.

C'est donc dans cette voie que je te conseille de chercher.
Amicalement.

Christian
Titre: Re : Lecture d'une carte SD
Posté par: Pierre59 le octobre 23, 2021, 12:28:09 pm
Bonjour

On a déjà parlé de ce problème sur le forum, mais je n'arrive pas à trouver où.

Pierre
Titre: Re : Lecture d'une carte SD
Posté par: chris_bzg le octobre 23, 2021, 06:50:35 pm
C'est hélas l'inconvénient majeur d'un forum : pour retrouver l'information, c'est le bordel !  ;)
Titre: Re : Lecture d'une carte SD
Posté par: Dominique le octobre 23, 2021, 07:22:48 pm
A toutes fins utiles, regarder ce tuto :
https://www.carnetdumaker.net/articles/lire-et-ecrire-des-donnees-sur-une-carte-sd-avec-une-carte-arduino-genuino/ (https://www.carnetdumaker.net/articles/lire-et-ecrire-des-donnees-sur-une-carte-sd-avec-une-carte-arduino-genuino/)
Titre: Re : Re : Lecture d'une carte SD
Posté par: likiki le octobre 23, 2021, 07:56:36 pm
A toutes fins utiles, regarder ce tuto :
https://www.carnetdumaker.net/articles/lire-et-ecrire-des-donnees-sur-une-carte-sd-avec-une-carte-arduino-genuino/ (https://www.carnetdumaker.net/articles/lire-et-ecrire-des-donnees-sur-une-carte-sd-avec-une-carte-arduino-genuino/)

Merci @Dominique, je connaissais, en aucun cas il ne parle du passage de la donnée vers une variable. Mais uniquement de la carte SD vers le moniteur série.

 :(
Titre: Re : Re : Lecture d'une carte SD
Posté par: likiki le octobre 23, 2021, 07:57:33 pm
C'est hélas l'inconvénient majeur d'un forum : pour retrouver l'information, c'est le bordel !  ;)

Bonjour, effectivement je n'ai rien trouvé en utilisant la fonction "rechercher".
Titre: Re : Re : Lecture d'une carte SD
Posté par: likiki le octobre 23, 2021, 07:59:22 pm
Bonjour Christian,

Si les données de la carte SD ont été écrites dans un fichier .TXT, alors ce sont des chaînes de caractères ASCII. En conséquence, tu ne peux pas affecter une chaîne de caractères dans une variable numérique.
Il faut au préalable transformer cette chaîne de caractères en une valeur numérique.
Ou bien changer le mode d'écriture sur la carte SD.

C'est donc dans cette voie que je te conseille de chercher.
Amicalement.

Christian

Bonjour Christian,

Oui effectivement, c'est LA solution, mais je n'arrive pas a la mettre en pratique. J'ai lue pas mal de chose (en anglais) mais pour y piger quelque chose ....

 :P
Titre: Re : Re : Lecture d'une carte SD
Posté par: likiki le octobre 23, 2021, 08:06:07 pm
Je vous propose de regarder les tableaux de variables avec un index permettant de se déplacer dans le tableau en même temps que la lectures des données dans la carte SD.

Cet article pourrait vous aider:
 https://www.locoduino.org/spip.php?article227 (https://www.locoduino.org/spip.php?article227)

Re @Dominique,

Je viens de parcourir (vitesse grand V) ce sujet, il parle de trains, ça me plais car là je comprend. Étant plutôt cartésien, le programme par l'exemple me sied.

Je vais lire cela de façon approfondis avant de me lancer dans la mise en pratique.

Dans tout les cas, je vous remercie tous d'avoir passé un peu de votre temps sur ma question.

Bonne soirée.
Titre: Re : Lecture d'une carte SD
Posté par: Pierre59 le octobre 24, 2021, 09:35:17 am
Bonjour

La lecture de la carte SD fournit des octets, dans le cas présent ces octets sont des caractères (issus d'un fichier .txt)

Les caractères chiffres ('0' à '9') doivent êtres transformés en un entier. Il est pratique de le faire en balayant les chiffres de gauche à droite, cela évite de les mémoriser. Pour cela on utilise l'algorithme de Hörner.

Voila ce que cela peut donner pour un nombre lu :

  int n=0; // le resutat
  char c; // le caractere courant
 
  c=lireSD(); // obtention d'un caractere
  while (c>='0' && c<='9') {
    n=n*10+c-'0'; // algorithme de Hörner
    c=lireSD(); // obtention d'un caractere
  }
  ecrire(n); // affichage du résultat

En pratique il faudra aussi tenir compte des signes '-' et des fins de ligne.

Pierre
Titre: Re : Lecture d'une carte SD
Posté par: dmskd le octobre 24, 2021, 09:46:12 am
Bonjour,

Si ça peut aider, voici la méthode que j'utilise:

Le fichier texte comprends des données écrites sous le format JSON. Exemple mon fichier locos.jso :

[
{"id":0,"name":"BB67300","address":2},
{"id":1,"name":"X4200","address":4},
{"id":2,"name":"X3800","address":5},
{"id":3,"name":"BB66000","address":1},
{"id":4,"name":"040DG-58","address":7},
{"id":5,"name":"A1A-A1A68537","address":6},
{"id":6,"name":"Adr-3","address":3},
{"id":7,"name":"Adr-8","address":8},
{"id":8,"name":"Adr-9","address":9},
{"id":9,"name":"Adr-10","address":10}
]

Le programme lit le fichier et le stocke dans une variable String ;
File locosFile;
String locos;

  locosFile = SD.open("locos.jso");
  if (locosFile) {
    while (locosFile.available()) {
      locos = locos + locosFile.readString();
    }
  }


Ensuite on désérialise les données JSON :
DynamicJsonDocument locosData(1024);

deserializeJson(locosData, locos);

Puis on dispose des données sous la forme suivante :
int locoAddress = locosData[*index]["address"];

Cordialement,
Dominique
Titre: Re : Re : Lecture d'une carte SD
Posté par: likiki le octobre 24, 2021, 12:08:48 pm
Bonjour

La lecture de la carte SD fournit des octets, dans le cas présent ces octets sont des caractères (issus d'un fichier .txt)

Les caractères chiffres ('0' à '9') doivent êtres transformés en un entier. Il est pratique de le faire en balayant les chiffres de gauche à droite, cela évite de les mémoriser. Pour cela on utilise l'algorithme de Hörner.

Voila ce que cela peut donner pour un nombre lu :

  int n=0; // le resutat
  char c; // le caractere courant
 
  c=lireSD(); // obtention d'un caractere
  while (c>='0' && c<='9') {
    n=n*10+c-'0'; // algorithme de Hörner
    c=lireSD(); // obtention d'un caractere
  }
  ecrire(n); // affichage du résultat

En pratique il faudra aussi tenir compte des signes '-' et des fins de ligne.

Pierre

Bonjour @Pierre

lire le fichier, ne me pose pas de problème.

(voir l'image en fichiers joints pour voir le résultat que j'obtiens sur le moniteur série)

Par contre comment reconnaitre la fin de ligne ?
Titre: Re : Lecture d'une carte SD
Posté par: Pierre59 le octobre 24, 2021, 01:16:34 pm
Bonjour

Suivant les systèmes la fin de ligne est marquée soit par le caractère ascii LF (codé '\n' en C), soit par les caractères ascii CR LF (codés '\r' et '\n' en C).

Pierre
Titre: Re : Lecture d'une carte SD
Posté par: likiki le octobre 24, 2021, 01:47:38 pm
Haaaa, voilà une information qui vas mettre bien utile.

Merci.
Titre: Re : Lecture d'une carte SD
Posté par: Jean-Luc le octobre 24, 2021, 07:58:34 pm
Bonsoir,

Si il s'agit d'écrire et de lire des données dans un fichier de la SD card, il est moins coûteux et plus simple d'écrire en binaire via write et de lire via read plutôt que de passer via des chaînes de caractères.

read et write ont notamment une version avec 2 arguments. Le premier est un pointeur vers les données en mémoire (un uint8_t ¨*) et le second le nombre d'octet.

Ainsi écrire un entier de 32 bits se ferait comme suit :

uint32_t donnee = 128000;
file.write((uint8_t *)&donnee, sizeof(donnee));

De manière symétrique, on lirait comme ceci :

file.read((uint8_t *)&donnee, sizeof(donnee));

Les deux méthodes retournent le nombre d'octets effectivement écrits ou lus. Ça permet de vérifier que tout se passe bien, que la carte n'est pas pleine, qu'on n'a pas atteint la fin de fichier :

if (file.read((uint8_t *)&donnee, sizeof(donnee)) != sizeof(donnee)) {
    // erreur
}

Je n'ai pas de SD card et je ne peux donc pas fournir un exemple testé.
Titre: Re : Lecture d'une carte SD
Posté par: likiki le octobre 29, 2021, 06:18:52 pm
J'ai cherché, trouvé et adapté, voilà ce que cela donne.

Je pense que cela vas en aider plus d'un.

/*
 * Récupération de données numérique present
 * sur une carte SD dans un fichier .txt
 * pour les mettre dans une variable
 * pour réutilisation dans le programme.
 *
 * 29/10/21
 *
 * C.A
 *
 */



#include <SPI.h>              // Interface pour carte SD
#include <SD.h>

#define sdCardCsPin  53       // Chip Select du lecteur de carte SD à adapter 9 pour UNO 53 pour MEGA

String logFileName = "";      // Nom du fichier d'enregistrement (Texte)
char logSdFileName[13];       //                     ""          (char)

int x, y, z;
// float xfl, yfl, zfl;

void setup()
{
  Serial.begin(9600);

  delay(500);
  //------------------------------------- Demarrage carte SD
  Serial.println("Initialisation carte SD...");         
  if (!SD.begin(sdCardCsPin))   // Si la carte SD ne repond pas
  {
    Serial.println("Carte SD out ou absente");
    return;
  }
  Serial.println("Carte SD OK\n");
 
  logFileName = "PosPlat.txt";  // longueur max 8+3 caractères
  logFileName.toCharArray(logSdFileName, 13);

 
  Serial.print("Niveau reseau ==> ");
  x = dataFileGetIndexValue(1);  // Rechercher la valeur à la ligne 1
  Serial.println(x);
 
  Serial.print("Position -1 ====> ");
  x = dataFileGetIndexValue(2);  // Rechercher la valeur à la ligne 2
  Serial.println(x);

  Serial.print("Position -2 ====> ");
  x = dataFileGetIndexValue(3);  // Rechercher la valeur à la ligne 3
  Serial.println(x);

  Serial.print("Position -3 ====> ");
  x = dataFileGetIndexValue(4);  // Rechercher la valeur à la ligne 4
  Serial.println(x);

  Serial.print("Position -4 ====> ");
  x = dataFileGetIndexValue(5);  // Rechercher la valeur à la ligne 5
  Serial.println(x);

  Serial.print("Position -5 ====> ");
  x = dataFileGetIndexValue(6);  // Rechercher la valeur à la ligne 6
  Serial.println(x);


  while(1){}

}

void loop()
{
}

float dataFileGetIndexValue(int lineIndex)
{
  String lineFromSd;
  float returnValue = -1;
  int valueIndex = 1;
 
  File dataFile = SD.open((String)logSdFileName, FILE_READ);

  if (dataFile)
  {
    while (dataFile.available())
    {
      lineFromSd = dataFile.readStringUntil('\n');
      String varName = lineFromSd.substring(0, lineFromSd.indexOf(":"));     // On prends la partie gauche pour extraire le nom de la variable
      varName.toUpperCase();                                                 // Le nom de la variable, mise en majuscule
      varName.trim();                                                        // Enlever les espaces inutiles
      String varValue = (lineFromSd.substring(lineFromSd.indexOf(":") +1));  // On prends la partie droite comme valeur
      if (valueIndex == lineIndex)                                           // Si arrivé à la ligne désirée
      {
        returnValue = varValue.toFloat();                                    // Que l'on transforme en valeur float
      }
      valueIndex ++;                                                         // Pour la ligne suivante
    }
  }
  else
  {
    Serial.println("BAD " + String(logSdFileName));
  }

  dataFile.clearWriteError();
  dataFile.close();

  return returnValue;
}

Une copie d'écran du résultat sur la pièce jointe.

Merci a tous pour votre aide précieuse.