Go Down

Topic: Transfert valeurs de SD vers Array [] ? (Read 869 times) previous topic - next topic

AlienArea51

Bonsoir @ tous
Comme l'intitulé l'indique ,je souhaite recuperer des valeurs inscrites dans un fichier (test.txt) sur SD CARD  et de les transferer dans un tableau , ARRAY[]   .
Est-ce possible ?
Pouvez-vous m'aider ?

Merci
William
The truth is elsewhere !!

Jean-François

Message 271, ici :

http://arduino.cc/forum/index.php/topic,89413.270.html


Content de te revoir  XD
MacBook intel core 2 duo  os X snow Leopard 10.6<br/> eMac PPc G4  os X Leopard 10.5<br/>powerbook G4 os X Leopard 10.5
imac PPC G3 os X Pa

AlienArea51

Salut J-F
Merci ,moi de mème  ;)

J'utilise le lecteur SD de Adafruit , je galère , je ne comprend pas pourquoi ça ne fonctionne pas  :smiley-eek: :smiley-eek:

Code: [Select]


char valeurs[60];
/
/
/
/
/

myFile = SD.open("test.txt",FILE_READ);
  if (myFile!=false) {
         for (int lect =0; lect <myFile.size(); lect++) {
      myFile.seek(lect); // se positionne à la position lect
   valeurs[lect]= myFile.read();
 
    }
   
    // close the file:
    myFile.close();
  } else {
  // if the file didn't open, print an error:
   Serial.println("error opening test.txt");
  }


Ai-je fait une erreur ??
@+
The truth is elsewhere !!

skywodd

Salut,

Dans ta boucle :
Code: [Select]
for (int lect =0; lect <myFile.size(); lect++) {
  myFile.seek(lect); // se positionne à la position lect
  valeurs[lect]= myFile.read();
}


Faire une itération de 0 à myFile.size() est une trés mauvaise idée, si ton tableau est trop petit (et il va l'a être, taille tableau < taille fichier) tu va corrompre la mémoire (buffer overflow).

Ensuite tu peut améliorer ton code en virant le myFile.seek() de la boucle puisque myFile.read() fera l'incrémentation de la position dans le fichier automatiquement.

Code: [Select]
myFile.seek(SEEK_SET);
for (byte lect = 0; lect < tailleTableau; lect++) {
  valeurs[lect] = myFile.read();
}
Des news, des tuto et plein de bonne chose sur http://skyduino.wordpress.com !

infobarquee

bonjour,
je te mets mon code un peu lourd mais qui fonctionne.
sur ma SD j'ai par exemple des valeurs comme ceci
mini=1
maxi=2

le code pour lire la SD et recupérer les valeurs
Code: [Select]
int ar_strlen(const char *s)
{
  const char *p = s;

  while (*p != '\0')
    p++;
  return (size_t)(p - s);
}

char *ar_strchr(const char *s, int c)
{
  while (*s != '\0' && *s != (char)c)
    s++;
  return ( (*s == c) ? (char *) s : NULL );
}

char *ar_strstr(const char *haystack, const char *needle)
{
  size_t needlelen;

  if (*needle == '\0')
    return (char *) haystack;
  needlelen = ar_strlen(needle);
  for (; (haystack = ar_strchr(haystack, *needle)) != NULL; haystack++)
    if (ar_strncmp(haystack, needle, needlelen) == 0)
      return (char *) haystack;
  return NULL;
}

int ar_strncmp(const char *s1, const char *s2, size_t n)
{
  unsigned char uc1, uc2;

  if (n == 0)
    return 0;
  while (n-- > 0 && *s1 == *s2) {
    if (n == 0 || *s1 == '\0')
      return 0;
    s1++;
    s2++;
  }
  uc1 = (*(unsigned char *) s1);
  uc2 = (*(unsigned char *) s2);
  return ((uc1 < uc2) ? -1 : (uc1 > uc2));
}

int getNbr(char *line)
{
  int nbr;

  nbr = 0;
  while (*line >= '0' && *line <= '9') {
    nbr *= 10;
    nbr += *line - '0';
    line++;
  }
  return (nbr);
}

int getConf(char *val)
{

  File myFile;
  char line[100];
  char i;

  i = 0;
  if (!SD.exists("test.txt")) {
    myFile = SD.open("sos/test.txt");
    Serial.print(myFile);
  }
  else{
    myFile = SD.open("test.txt");
  }
  if (myFile > 0) {
    while ((line[i] = myFile.read()) > 0) {
      if (line[i] == '\n') {
        line[i] = '\0';
        i = 0;
        if (ar_strstr(line, val) && line[ar_strlen(val)] == '=') {
          myFile.close();
          return (getNbr(line + ar_strlen(val) + 1));
        }
      }
      else {
        ++i;
      }
    }
  }

  return 0;
}

mini = getConf("mini");
maxi = getConf("maxi");




AlienArea51

Bonjour Messieurs

@Skywodd
Merci
J'ai recuperé des bouts de programme à droite et à gauche ,et donc fait de multiples essais sans résultat , un peu pour ça que tu ai constater des erreurs .
j'ai bien enregistré 60 valeurs en ligne par ligne ,je suppose que ça n'a pas d'importance ??

Quote
myFile.seek(SEEK_SET);

Sert bien à mettre le pointeur en début de fichier ,c'est bien ça ?  , je ne sais pas si c'est le bon terme ?

@infobarquee
merci également de m'aider ,je vais peut-etre en baver un peu plus ,pour décrypter   XD ,car je ne suis pas doué , sauf si tu me dit de prendre la partie correspondant à l'ouverture et lecture SD ??

@+
William


The truth is elsewhere !!

skywodd


Quote
myFile.seek(SEEK_SET);

Sert bien à mettre le pointeur en début de fichier ,c'est bien ça ?  , je ne sais pas si c'est le bon terme ?

Ouaip c'est ça.
Des news, des tuto et plein de bonne chose sur http://skyduino.wordpress.com !

AlienArea51

@ Skywodd
Ok pour ça:
Quote
myFile.seek(SEEK_SET);

Par contre ,désolé d'avoir la comprenette difficile ,mais pour ça :
Quote
Faire une itération de 0 à myFile.size() est une trés mauvaise idée, si ton tableau est trop petit (et il va l'a être, taille tableau < taille fichier) tu va corrompre la mémoire (buffer overflow).


Je pense ,que j'ai mal interpreté la chose , en fait je déclare 60 dans mon tableau ,et la taille du fichier est de 228 Octets ,donc effectivement ça ne peut pas fonctionner  :smiley-red:
j'ai mélangé les choux et les carottes  XD ,il me faut en fait un moyen de calculer le nombre de valeurs entré dans la SD ! par contre là !!

The truth is elsewhere !!

infobarquee

a quoi ca sert d'avoir mis avant le code :)
Code: [Select]
le code pour lire la SD et recupérer les valeurs
c'est tout le code qui sert a récupérer les variables, donc tout prendre.

pour le nb de valeurs, j'utilise une variable=une ligne
donc il suffit de choper dans le code le nb de ligne, en l'occurence, je sais que j'ai 9 lignes d'ou le
Code: [Select]
while (*line >= '0' && *line <= '9') {
tu peux faire quelque chose comme ca
Code: [Select]
while (*line >= '0') {

AlienArea51

@infobarquee
Je plaisantait , bien sure qu'il faut tout  ;)   ,mais comme j'ai dit ,j'ai pas inventé la poudre , donc suffisamment dure de comprendre  ;)
et comme je suis loin de connaitre toute les subtilités du 'C'  !!!!

N'y a t-il pas un autre procédé ??

Merci pour ta patience  ;)
William
The truth is elsewhere !!

AlienArea51

Bonsoir
Donc voilà ,après moultes essais ,ça ne fonctionnait toujours pas ,la cause est simple ,je suis un boulet  :smiley-red:
Quote

   Serial.begin(9600);
pinMode(10, OUTPUT);
//SD.begin(10);    Voilà le Probleme


Maintenant ,ça fonctionne ,ouffff !
j'ai déclaré un tableau plus grand en attendant :

Code: [Select]

#include <SD.h>

File myFile;
char valeurs[300];


void setup()
{
   Serial.begin(9600);
pinMode(10, OUTPUT);
SD.begin(10);

// Transfert valeurs de SD vers Tableau
myFile = SD.open("test.txt",FILE_READ);
  if (myFile!=false) {
myFile.seek(SEEK_SET);
         for (int lect =0; lect <myFile.size(); lect++) {
     valeurs[lect]= myFile.read();
 
    }
   
    // close the file:
    myFile.close();

// lecture des valeurs du tableau vers moniteur
for (int i =0; i <myFile.size(); i++) { 
Serial.write( valeurs[i]);
}
}
}
void loop()
{

}


Je ne marque pas résolu Pour le moment car j'aurai certainement encore besoin de vos lumieres  ;)
les valeurs sont enregistrées de cette maniere :

Quote

30
40
50
60
ETC.. etc..

et souhaiterai faire ça (exemple ):

Quote

50,30,100
50,0,300
etc.. etc..


J'essaye seul ,et si je n'y arrive pas , je mentionnerai un gros HELP !!    :smiley-mr-green:

Merci
William


The truth is elsewhere !!

infobarquee

je croyais que pour la SD c'était la pin 4 et non 10
SD.begin(4);

AlienArea51

@ infobarquee

Quote

// On the Ethernet Shield, CS is pin 4. It's set as an output by default.
  // Note that even if it's not used as the CS pin, the hardware SS pin
  // (10 on most Arduino boards, 53 on the Mega) must be left as an output
  // or the SD library functions will not work.


Pour info  ;)
@+
William
The truth is elsewhere !!

skywodd


Je pense ,que j'ai mal interpreté la chose , en fait je déclare 60 dans mon tableau ,et la taille du fichier est de 228 Octets ,donc effectivement ça ne peut pas fonctionner  :smiley-red:
j'ai mélangé les choux et les carottes  XD ,il me faut en fait un moyen de calculer le nombre de valeurs entré dans la SD ! par contre là !!

On serait sur un ordinateur je t'aurai conseillé d'y allez à grand coup de malloc(), realloc(), et de sscanf(), sauf que faire du malloc quand on a que 2Ko de ram c'est pas une super idée.

Tu as besoin de TOUTES les valeurs, ou ton calcul peut juste se contenter de valeurs "glissante".
En gros est ce qu'il te faut charger toutes les valeurs avant ton calcul, ou est ce que tu peut faire un calcul "glissant" n'utilisant qu'une valeur à la fois ?

Chargement de tout -> tableau énorme de taille fixe -> pas génial
Chargement avec glissement -> pas de tableau, juste une variable -> tiptop


Pour la lecture d'une valeur :
Code: [Select]
#define TAILLE_BUF 30

// ...

char buf[TAILLE_BUF];
int valeur; // Valeur lu dans la ligne
byte i; // Itérateur

for(i = 0; i < (TAILLE_BUF - 1); i++) // Pour i allant de 0 à taille_buf - 1
  if((buf[i] = myFile.read()) == '\n') break; // place le char lu dans buf, si char == \n on stop tout (fin de ligne)

buf[i] = '\0'; // On clôture la chaine de caractére

if(sscanf(buf, "%d", &valeur) != 1) // Si sscanf retourne autre chose que 1 (= 1 valeur lu)
  valeur = 0; // gestion d'erreur

// Voir http://www.cplusplus.com/reference/clibrary/cstdio/sscanf/
Des news, des tuto et plein de bonne chose sur http://skyduino.wordpress.com !

AlienArea51

@Skywodd
merci Fabien,de t'investir.
Pour le moment ,la taille ,c'est pas trop important car je fixe le nombre de valeurs donc pas trop dure de donner un talon .
et excuse moi mais je n'ai pas trop envie de rentrer dans la complexitée ,suffisamment dure pour moi ( parfois je ne comprend pas le titre  XD :smiley-red:),Bref.
Je galère à fond , j'ai testé un truc , ça fonctionne mais bon !
Car entre le [ file.print() ,file.println() ,file.write() sans parler de CHAR de INT etc...] au secour , je pense que tu sais pourquoi je me penche là-dessus ??
Si non , c'est pour le MIDI .Je sais que je ne suis pas le 1er ni le dernier à c'etre penché sur le problème .
Donc, j'ai fait un fichier ou ce trouve la note et la vélocité , plus qu'a mettre la durée , j'ai bien la note sur le canal1 l'arret de cette note sur canal1 .
Mon souhait ,et là ça ce complique ,jouer une séquence au synthé ==>> enregistrer cette séquence sur SD et pouvoir la reprendre .

P.S: La catégorie débutant sur le Forum s'impose , notament pour ça ,les subtilités de programmation , car les !machin - truc* -bidule+  et j'en passe sur la réference Arduino laisse tomber .


@+
William


The truth is elsewhere !!

Go Up