Bonjour,
Pour un projet perso, j'ai besoin de lire un fichier type CSV depuis une carte SD.
Pour la lecture SD pas de problème, mais ou le problème arrive, c'est lorsque je veux enregistrer les données récupérées dans un tableau de structure.
Dans ces données, il y a 7 éléments par ligne :
- Les 3 premiers sont des entiers (int)
- Le 4e est une chaine de caractère "char *".
- Les 3 derniers sont des "uint16_t"
J'ai créé ci-dessous un script allégé qui reproduit mon erreur.
Son fonctionnement dans cet exemple :
- Dans le setup, je vais lire le contenu de la carte.
- à l'aide de "fileSD.read()", je lit chacune des lignes du fichier dans un "while". Chacun des caractères est lu, et stockés dans une chaine jusqu'à ce que je rencontre le caractère de fin de ligne (\n).
- Je dirige la lecture vers la console pour vérification, ma ligne est OK.
- Avec la fonction strtok(), je décompose mes données, qui sont toutes séparées par un ";".
- Au fur et à mesure du découpage, je stock ma donnée dans le tableau de structure.
- A la fin du traitement, je vérifie chacune des données stockées, tout est OK.
- Une fois toute les lectures terminées, le programme revient dans le "setup".
- Je fait une boucle sur le nombre de ligne lue, et pour chacune de ces lignes, j'affiche le contenu stocké dans le tableau (ce qui devrait être la même chose que la précédente lecture).
Et la c'est le drame
Les INT et les UINT16_T sont correct, mais la chaine de caractère est du n'importe quoi.
Ce que j'obtient dans la console (le 2 dernières lignes ne sont pas bonne) :
Lecture de La Carte...
Fichier message.txt ouvert.
7;8;0;Dèbut de démo;2;50;2000
0 -> 7 - 8 - 0 - Dèbut de démo - 2 - 50 - 2000
2;2;1;Scroll_Up;30;30;1000
1 -> 2 - 2 - 1 - Scroll_Up - 30 - 30 - 1000
0 ->> 7 - 8 - 0 - ⸮?⸮⸮?lb 0⸮⸮? - 2 - 50 - 2000
1 ->> 2 - 2 - 1 - - 30 - 30 - 1000
Ce que j'attend et que je devrais avoir (sauf que je dois me planter quelque part) :
Lecture de La Carte...
Fichier message.txt ouvert.
7;8;0;Dèbut de démo;2;50;2000
0 -> 7 - 8 - 0 - Dèbut de démo - 2 - 50 - 2000
2;2;1;Scroll_Up;30;30;1000
1 -> 2 - 2 - 1 - Scroll_Up - 30 - 30 - 1000
0 ->> 7 - 8 - 0 - Dèbut de démo - 2 - 50 - 2000
1 ->> 2 - 2 - 1 - Scroll_Up - 30 - 30 - 1000
Voici le contenu de la carte SD :
7;8;0;Dèbut de démo;2;50;2000
2;2;1;Scroll_Up;30;30;1000
Le code Arduino :
#include <SD.h>
// Parametrage SD card
#define SD_CS_PIN 4
#define MESSAGE_FILE "test.csv"
struct sTxtAffiche {
int efIn;
int efOut;
int posTxt;
char* txt;
uint16_t vIn;
uint16_t vOut;
uint16_t pause;
} ;
sTxtAffiche TxtAffiche[] = {};
int nbrLigne = 0;
void setup() {
Serial.begin(115200);
// Init SD card
if (!SD.begin(SD_CS_PIN)) {
Serial.println(F("Erreur Initialisation de la carte !"));
Serial.println(F("Verifiez la carte SD et appuyez sur le bouton RESET"));
while (1) {}
} else {
Serial.println("initialization done.");
}
// EcrireSD();
LectureSD();
for(int i = 0; i <= nbrLigne; i++) {
Serial.print(i); Serial.print(" ->> "); Serial.print(TxtAffiche[i].efIn); Serial.print(" - "); Serial.print(TxtAffiche[i].efOut); Serial.print(" - ");
Serial.print(TxtAffiche[i].posTxt); Serial.print(" - "); Serial.print(TxtAffiche[i].txt); Serial.print(" - ");
Serial.print(TxtAffiche[i].vIn); Serial.print(" - "); Serial.print(TxtAffiche[i].vOut); Serial.print(" - "); Serial.println(TxtAffiche[i].pause);
}
}
void loop() {
// put your main code here, to run repeatedly:
}
void LectureSD() {
char fileChar;
String ligneText;
Serial.println("Lecture de La Carte... ");
// On ouvre le fichier à lire.
File fileSD = SD.open(MESSAGE_FILE, FILE_READ);
if(fileSD){
int ligneEnCours = 0;
// Fichier ouvert, on exécute le traitement.
Serial.print("Fichier "); Serial.print(MESSAGE_FILE); Serial.println(" ouvert.");
while(fileSD.available() > 0) {
// On lit le caractère courant
fileChar = fileSD.read();
// On vérifie si on est en fin de ligne
if (fileChar == '\n') {
// Nous sommes en Fin de ligne, on traite la ligne courante.
char str_array[ligneText.length()]; // On crée un tableau de la longueur de la ligne "ligneText"
ligneText.toCharArray(str_array, ligneText.length()); // On converti la String "ligneText" en Char, que l'on stock dans notre tableau.
Serial.println(str_array);
TxtAffiche[ligneEnCours].efIn = atoi(strtok(str_array, ";"));
TxtAffiche[ligneEnCours].efOut = atoi(strtok(0, ";"));
TxtAffiche[ligneEnCours].posTxt = atoi(strtok(0, ";"));
// ***** Je pense que le problème vient de cette ligne ci dessous *****
TxtAffiche[ligneEnCours].txt = strtok(0, ";");
TxtAffiche[ligneEnCours].vIn = atoi(strtok(0, ";"));
TxtAffiche[ligneEnCours].vOut = atoi(strtok(0, ";"));
TxtAffiche[ligneEnCours].pause = atoi(strtok(0, ";"));
Serial.print(ligneEnCours); Serial.print(" -> "); Serial.print(TxtAffiche[ligneEnCours].efIn); Serial.print(" - "); Serial.print(TxtAffiche[ligneEnCours].efOut); Serial.print(" - ");
Serial.print(TxtAffiche[ligneEnCours].posTxt); Serial.print(" - "); Serial.print(TxtAffiche[ligneEnCours].txt); Serial.print(" - ");
Serial.print(TxtAffiche[ligneEnCours].vIn); Serial.print(" - "); Serial.print(TxtAffiche[ligneEnCours].vOut); Serial.print(" - "); Serial.println(TxtAffiche[ligneEnCours].pause);
ligneEnCours ++ ;
ligneText = "" ;
} else {
// Nous ne sommes pas en fin de ligne.
ligneText += fileChar; // On ajoute le caractère Lu à la ligne "ligneText".
}
}
fileSD.close();
nbrLigne = ligneEnCours - 1;
}
}
void EcrireSD() {
SD.remove(MESSAGE_FILE);
File myFile = SD.open(MESSAGE_FILE, FILE_WRITE);
if (myFile) {
myFile.println("7;8;0;Dèbut de démo;2;50;2000");
myFile.println("2;2;1;Scroll_Up;30;30;1000");
myFile.close();
Serial.println("Ecriture OK.");
}
}
Je pense que le problème se situe dans l'enregistrement du texte à cette ligne :
TxtAffiche[ligneEnCours].txt = strtok(0, ";");
Car si je met en dur :
TxtAffiche[ligneEnCours].txt = "Toto";
J'ai bien "Toto" de retourné à la fin du programme.
J'ai testé également avec :
String valTemp = (String)strtok(0, ";");
TxtAffiche[ligneEnCours].txt = valTemp.c_str();
Les signes retournés sont différents, mais je n'ai jamais ma chaine de caractères attendue.
Je ne comprend pas pourquoi si je met en dur, cela fonctionne.
Et je ne comprend pas non plus pourquoi, à la première interrogation de mon tableau, la valeur "TxtAffiche[ligneEnCours].txt" est correct, et qu'ensuite elle ne l'est plus à la fin du programme.
Si quelqu'un a un idée du problème, je vous remercie par avance.