Go Down

Topic: Séparer les données dans un fichier CSV sur carte SD. (Read 2071 times) previous topic - next topic

kooxy

Bonjour,

J'ai un projet sur le feu dans lequel je dois lire des données dans un fichier csv. j'arrive la le lire avec la fonction seek(), mais cette fonction ne me permet pas de séparer les donées à chaque ';' .
J'ai vu sur intenet qu'il faudrait que j'utilise la fonction strtok :

Code: [Select]

#include <string.h>

char *record = "name:bob";  // a quoi sert l'étoile ?
char *p, *i;  // a quoi sert l'étoile ?

void setup() {

  Serial.begin(9600);
  Serial.println("Starting..");
 
   //  First strtok iteration
   p = strtok_r(record,":",&i);
   Serial.print(p);
   Serial.print(" = ");

   //  Second strtok iteration
   p = strtok_r(NULL,":",&i);
   Serial.print(p);
   Serial.println("");

}

void loop () {
}


Le problème c'est que le char  *record est déja défini. J'aimerais pouvoir faire la même chose avec un char qui serait lu dans le fichier csv. il y aurais plusieurs lignes avec 2 paramètres.

exemple du fichier csv :

50;LOW
1000;HIGH
HIGH;2000






Merci

fdufnews


kamill

Bonjour,

C'est simple, il faut lire ta ligne dans un buffer puis l'analyser  
Code: [Select]
char buf[20];
 // ici lecture du fichier csv dans buf
 
 char *p1=strtok(buf,";");
 char *p2=strtok(NULL,";");
 
 Serial.println(p1);
 Serial.println(p2);

kooxy

Parfait

Mais si j'ai plusieurs lignes ?
et plus de 2 variables par lignes ?? (rare)

kamill

Bin, c'est à toi de décider si tu veux les traiter toutes ou quelle ligne tu veux traiter.

kooxy

Il faudrait toutes les lire pour avoir tout les paramètres

kamill

Tu fais une boucle tant qu'il y a des données dans le fichier, tu lis la ligne et tu la traites.

kooxy

Ok

par contre petit souci a la lecture :

Code: [Select]
#include <SD.h>
#include <SPI.h>




void setup() {
File fichierlog;
char  buf[20];

              // Open serial communications and wait for port to open
               Serial.begin(9600);
               while (!Serial) {}
                 ; // wait for serial port to connect. Needed for native USB port only

     
     
               Serial.print("Initialisation de la carte SD ...");

               if (!SD.begin(4)) {
                                    Serial.println("initialisation echouee !");
                                    return;
                                  }
               Serial.println("initialisation reussie.");
 

fichierlog = SD.open ("READTEST.csv", FILE_READ);

while (fichierlog.available() != 0) {
                                      Serial.write(fichierlog.read());
                                      buf=fichierlog.read();       
                                    }

}

void loop() {


}


portion qui posse problème :
Code: [Select]


File fichierlog;
char  buf[20];


while (fichierlog.available() != 0) {
                                      Serial.write(fichierlog.read());
                                      buf=fichierlog.read();   // cette ligne pause problème
                                    }

message d'erreur :
incompatible types in assignment of 'int' to 'char [20]'


pourtant dans ce programme ça marche :
Code: [Select]
#include <SPI.h>
#include <SD.h>

File myFile;

void setup() {

  Serial.begin(9600);
  while (!Serial);
 
 Serial.print("Initializing SD card...");

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

}

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

}

 void readSDSettings(){
 
 char character;
 String settingName;
 String settingValue;

 
 myFile = SD.open("config.csv");
 if (myFile) {
 while (myFile.available()) {
 character = myFile.read();
 while((myFile.available()) && (character != ';')){
 character = myFile.read();
 }


 }
 myFile.close();
 }
 }


Où est la faute dans le 1er programme ?

kamill

essai ça pour la lecture d'une ligne
Code: [Select]
 static char buf[50];
 int i;
 for (i=0; fichierlog.available() && i<sizeof buf-1; i++)
 {
   buf[i]=fichierlog.read();
   if (buf[i]=='\n')
     break;                // fin de ligne
 }
 buf[i]=0;                 // fin de la chaine

kooxy


kooxy

Bonjour,

Comment je pourrai boucler en fonction du nombre de lignes ??

En initialisant un autre compteur et boucler tant que compteur<nb de lignes ??
je ne sais pas trop comment m'y prendre pour la programmation.

Merci de votre aide

kamill

Bonjour,

Si tu connais le nombre de lignes tu peux boucler sur le nombre de lignes.
Autrement tu peux lire les lignes jusqu'à la fin du fichier comme ceci:
Code: [Select]
 static char buf[50];
 int ligne=0;
 while (fichierlog.available())
 {
   int i;
   for (i = 0; fichierlog.available() && i < sizeof buf - 1; i++)
   {
     buf[i] = fichierlog.read();
     if (buf[i] == '\n')
       break;                // fin de ligne
   }
   buf[i] = 0;               // fin de la chaine
   ligne++;
   // *** ici traitement de la ligne ***
   // ...
 }

kooxy

Merci infiniment !!! tout fonctionne parfaitement !!


Fichier csv :

125000;ON;LU ?;ET Cela ?
test;9999999;;
kamill ;Merci !;Au top;


Code Finale (pour ceux qui avais le même soucis ^^) :
Code: [Select]
#include <SD.h>
#include <SPI.h>


File fichierlog;
static char buf[50];
int i;
int c;
int ligne=0;

char *p1;
char *p2;
char *p3;
char *p4;




void setup() {
 

 
              // Ouverture du port série
               Serial.begin(9600);
               while (!Serial) {};

     
// -----------------------Initialisation de la carte SD------------------------------

     
               Serial.print("Initialisation de la carte SD ...");

               if (!SD.begin(4)) {
                                    Serial.println("initialisation echouee !");
                                    return;
                                  }
               Serial.println("initialisation reussie.");
 

//------------------------Ouverture du fichier csv-----------------------------------

fichierlog = SD.open ("READTEST.csv", FILE_READ);

//------------------------Lecture du fichier csv-------------------------------------

 while (fichierlog.available())
 {
   int i;
   for (i = 0; fichierlog.available() && i < sizeof buf - 1; i++)
   {
     buf[i] = fichierlog.read();
     if (buf[i] == '\n')
       break;                // fin de ligne
   }
   buf[i] = 0;               // fin de la chaine
   ligne++;


//-------------séparation des données d'une ligne (ici 4 données max)-------------

 p1=strtok(buf,";");
 p2=strtok(NULL,";");
 p3=strtok(NULL,";");
 p4=strtok(NULL,";");

//------------------Verification de la lecture et du découpage--------------------
 
 Serial.println(p1);
 Serial.println(p2);
 Serial.println(p3);
 Serial.println(p4);

 
 
}
}

void loop() {


}



Résultat sur le port série :
Code: [Select]
Initialisation de la carte SD ...initialisation reussie.
125000
ON
LU ?
ET Cela ?

test
9999999



kamill
Merci !!!!!!
Au top





Initialisation de la carte SD ...initialisation reussie.
125000
ON
LU ?
ET Cela ?

test
9999999



kamill
Merci !!!!!!
Au top



Merci beaucoup Kamill !! :)

kooxy

Rebonjour,

J'ai encore un petit soucis.
Le programme marche nikel mais il faudrait recouper une donnée en plusieurs autres.

voila mon fichier csv :

R1=OFF ET R2=OFF;N;CONDITION INITIALES
R1=ON;N;ETAPE1
E1=VRAI ET E2=FAUX;B;TRANSITION 1
R2=ON;N;ETAPE2
T=3000;B;TRANSITION 2
R2=OFF;N;ETAPE3
E1=FAUX ET E2=VRAI ;B;TRANSITION 3
R1=OFF;N;ETAPE4
T=0;B;TRANSITION 4
R1=OFF ET R2=OFF;N;ETAPE5
T=0;B;TRANSITION 5
R1=OFF ET R2=OFF;N;ETAPE6
T=0;B;TRANSITION 6
R1=OFF ET R2=OFF;N;ETAPE7
T=0;B;TRANSITION 7

j'aimerais par exemple pour la 1ère ligne séparer R1/OFF/R2/OFF.
Ça me permettrai ensuite de parametrer

R1(relais1) eteint et R2(relais2) eteint.


Je pensais utiliser la fonction strchr est-ce correct ?
Le probleme est aussi qu'il faut faire toutes les lignes mais elles ne sont pas au même format. est-ce possible ?

Merci

fdufnews

Je pensais utiliser la fonction strchr est-ce correct ?
Pourquoi strchr? pourquoi ne pas utiliser la même méthode avec strtok en changeant le séparateur.
Tu peux faire des accès successifs à strtok en changeant le séparateur à chaque appel ou  bien tu peux  passer une liste de séparateurs à la fonction.

Go Up