Fichier et Liste chainee

Bonjour Tout le monde, je suis nouvelle sur ce forum.
Je travaille sur un systeme de controle d'acces dont la base de donnée est sur une carte SD(fichier .csv), mon souci est d'automatisé mon tableau a chaque enregistrement dans le fichier. pour cela j'ai essaye 'liste chainee' pour augmenter la taille de mon tableau sans revenir dans le prog pour changer la taille.
Je n'aarive pas à ni lire le fichier , ni charger le fichier dans la liste.
Voici mon prog.

Svp ou se trouve le balise de code



#include <SPI.h>
#include <SD.h>

#define ss 4


int lig  = 5;
int col = 4;


String recu;
String tout;
String lire;

typedef struct liste   // definition d'un type 
{
  String clavier;            // valeur dans l'element
  struct liste *next;    // adresse du prochain element
}liste;                 // Liste est now un type

File file;



void setup() {
  
Serial.begin(9600);
  SPI.begin();
  pinMode(ss, OUTPUT);
  if (SD.begin(ss)) {
    Serial.println("SD init");
  }
  else {
    Serial.println("Rien");
  }

  file = SD.open("Acces.csv");

  if (SD.exists("Acces.csv")) {
    Serial.println("Le fichier est là");
  }
  else {
    Serial.println("Fichier introuvable");
  }
 //lecture de l'entete du fichier
 file.readStringUntil(';'); 
 file.readStringUntil(';');
 file.readStringUntil(';');
file.close();

}
 
void loop() {
// Ajouter une ligne da ns mon fichier
//Liste==int, char, String
file = SD.open("Acces.csv");
liste *ma_liste = NULL;

Ajouter_fin(&ma_liste,recu);
affich(ma_liste);

file.close();
}

// creation des fonctions de type Liste
// premiere fonction: une nouvelle
// deuxieme fonction : ajout_element


//-----------fonction ajout en fin de ligne dans la liste--------
void Ajouter_fin(liste **li, String pof)
{
 file = SD.open("Acces.csv");
  liste * element; // creation d'un new element
  element = malloc(sizeof(liste)); //malloc de la taille du type à allouer(liste)
  if(element == NULL){
    Serial.println("alloc echec"); 
    exit(EXIT_FAILURE);
  }
  while(Serial.available()>0){
    recu = Serial.readString();
    Serial.println(recu);
    file = SD.open("Acces.csv");
    element-> clavier = recu; 
    element ->clavier = pof;
    element -> next = NULL;
    file.print(element->clavier); // ecrit dans le fichier
    Serial.println(recu);
    
  }
  // Affectation des valeurs 

file.close();
}


//----------------fonction affichage-----------
void affich(liste *li)
{
  while(li){
    Serial.println(li->clavier);
    li = li -> next;
   
  }
}

//---------------fonction chargement--------------
liste *lecture(){         //charger le fichier d                                                                                                                                                                                                                                                                                                                                                                                                                                                           ans la liste
  liste * fiche =malloc(sizeof(liste));
  String tab[lig][col]="";
  file = SD.open("Acces.csv");
  lire = file.readStringUntil(';');
  lire.remove(0, 1);
//  return lire;
  Serial.println(lire);
  Serial.println("---------");
  fiche= tab[lig][col]->lire;
  for(int i=0; i<lig; i++){
    for(int j=0; j<col; j++){
      Serial.println(tab[i][0]); 
    }
  }
   
file.close();
}

Bonjour,

Tu parles d'automatiser un tableau mais il n'y a aucun tableau.

Je ne vois pas très bien ce que tu vas faire de next une fois que ta liste sera écrite sur une carte SD.
next c'est un pointeur, c'est donc une adresse en mémoire. qui n'a de sens que dans le contexte courant. Si tu relis ton fichier plus tard les données ne seront probablement pas placées en mémoire aux mêmes adresses et donc ton pointeur va te faire lire n'importe quoi.
Dans le cas d'une liste chaînée stockée sur un média externe, le lien entre les éléments ne peut être qu'une référence à un enregistrement déjà existant.
Tu ne dis pas quel Arduino tu utilises mais les listes chaînées c'est un peu mal adapté à un CPU avec peu de mémoire.
Mettre un objet String dans une liste et faire écrire ladite liste sur une carte SD, je ne sais pas trop ce que ça donne. Tu as déjà essayé de lire un objet String que tu aurais écrit dans un fichier.

Je ne suis pas fan de String, que j'utilise très peu mais pour moi, la seconde affectation écrase la première.

d'accord c'est noté
Tout d'abord je dois enregistrer une nouvelle ligne dans mon fchier contenant l'ID, nom et l'autorisation de la personne, avec un tableau statique cela ne prend pas compte l'ajout d'une nouvelle ligne c'est pour cela que je suis partie avec 'liste'
mon fichier est suite:
1245895021;ZTouty Fall;1;A
le Z et A c'est pour faciliter la lecture du fichier

#include <SD.h>
#include<SPI.h>
#include<SoftwareSerial.h>



#define ss 4
#define relais 10



String code_ad = "code1234";
String code;

String recois; 
String recu;
String string;
String lire;
int i,j ;


 
String ligne[3][4];


SoftwareSerial soft (6,2);
File file;

void setup() {
  Serial.begin(9600);
  SPI.begin();
  soft.begin(9600);
  
  pinMode(ss, OUTPUT);
  if(SD.begin(ss)){
    Serial.println("SD init");
  }
  else{
    Serial.println("Rien");
  }
 file = SD.open("Acces.csv");

  if (SD.exists("Acces.csv")) {
    Serial.println("Le fichier est là");
  }
  else {
    Serial.println("Fichier introuvable");
  } 


//lecture de l'en tête
file.readStringUntil(';');
file.readStringUntil(';');
file.readStringUntil(';');
//fin de lecture

//Allocation dynamique des tableaux
//lecture d'une ligne avec 3 colonnes
for( i =0; i<2; i++){
  for( j=0;j<3;j++){
   ligne[i][j]=nom();  // remplissage
}
Serial.println(ligne[i][1]);
}

 file.close();
 pinMode(relais, OUTPUT);
}


 void loop(){
  
file = SD.open("Acces.csv");
  
while(1){
  if(soft.available()>0){
    while(soft.available()>0){
      recois = soft.readString();
      if(recois.length()==10){
        Serial.println(recois);
        Serial.println("okay");
        //break;
      }
   Serial.println("-----");
   comparaison();
   
    }
    
  }
  
 break;
}
//while(1){   
  if(Serial.available()>0){
    Serial.println("Partie administratif");
    Serial.println("Taper votre code administratif");
    while(Serial.available()>0){
      code = Serial.readString();
      Serial.println(code);      // affichage du code-ad
      Serial.println(code_ad);
      if((code.indexOf(code_ad)>=0)){  //comparaison des codes
        Serial.println("1ére condition remplie!!!");
        }
        else{
          Serial.println("Vous n'êtes pas autorisé à enregistrer"); 
          }  
        
     if(((ligne[i][0]).indexOf(recois)<0) && (code.indexOf(code_ad)>=0) ){
      Serial.println("2éme condition remplie");
      Serial.println("Début d'enregistrement");
      Enregistre();
    }
    else{
      Serial.println("Pas d'enregistrement"); 
     
    }

 }
 } 
//}
file.close();
 
 }
 

 

//----------------------------Les fonctions------------------------ 
 



 String nom(){  // extraction des noms
  lire = file.readStringUntil(';');
  lire.remove(0,1);  //pour enever les 2 caractères de plus qui sont dans le fichier
  return lire;
  Serial.println(lire);
   
}




 String comparaison(){
  file = SD.open("Acces.csv");
  int ind = 0,e=0;
  for( i=0; i<4; i++){   // les elements du tableau
    if((ligne[i][0]).indexOf(recois)>=0){   // verifier si l'id est dans le tableau
        ind =i;
        Serial.println(ligne[ind][1]);
        e=1;
      }   
       }
 if(e==1){
  if((ligne[ind][2]).indexOf(String(1))>=0){
    Serial.println("Autorisé: ");
    Serial.println(ligne[ind][1]);
    soft.print("Bienvenue : ");
    soft.println(ligne[ind][1]); //retour au lecteur
    delay(100);
    digitalWrite(relais, LOW);
    delay(1000);
    digitalWrite(relais, HIGH);
     }
      else{
        Serial.println("Non autorisé");
        soft.print(ligne[ind][1]);
        soft.println("Non autorisé à passer par cette porte");
        delay(100);
        }
 }
 else{
  Serial.println("Vous n'êtes pas dans la base de donnée");
  soft.print("Vous n'êtes pas dans la base de donnée");
  delay(1000);
   }
     file.close(); 
  }


  
     
      

  
String Enregistre(){
//si la personne n'est pas dans la BDD et que le code_ad est bon
 while(1){
  while(Serial.available()>0){
    recu = Serial.readString();
    Serial.println(recu);
    file = SD.open("Acces.csv", FILE_WRITE);
    string += recois;
    string += ";" ;
    string += recu ;
    file.seek(file.position());
    file.print(string);        // savely dans la BDD
    file.close();
    Serial.println(string);
    Serial.println("Enregistrement reussi");
    }
          
   }
        
  }

    
  
  
        




 
 
 









 
//String ReadLine(){
//  file = SD.open("Carte.csv");
//  Serial.println("hi");
//    static char buf[100];
//    int ligne =0;
//    char *ID;
//    int i;
//    char *Ident;
//    char * porte;
//  if(file.available()){
//    while(file.available()){
//      for(i=0; i< sizeof buf-1; i++){
//        buf[i] = file.read();
//        if(buf[i] =='\n'){
//          break;
//      }
//      }
//    buf[i] =0;
//   ligne ++;
//   //Serial.println(buf);
//ID= strtok(buf, ";");
//Ident = strtok(NULL, ";");
//porte=strtok(NULL, ";");
////Serial.println(Ident);
//    }
// // 20 nbre d'ID -> nbre de lignes  
//for(int i=0; i<4;i++){
// copie_id[i]=ID;
// Serial.println(copie_id[1]); 
//}
//   
//// // tableau de noms 
//for(int i=0; i<4;i++){
// copie_no[i]=Ident;
// Serial.println(copie_no[2]);
//  
//}
////
//// //Tableau de porte
//for(int i=0; i<4;i++){
// copie_porte[i]=porte;
// Serial.println(copie_porte[2]); 
//  }
//    
//  }
//  file.close();
//} 

//
//String save(){
//  
//  String pom;
//while(1){
//  if(Serial.available()>0){
//    while(Serial.available()>0){
//      com = Serial.readString();  //1er demande du moniteur
//      Serial.println(com);
//      if(com != "non"){
//        Serial.println("Veuillez entrer les coordonnées de la personne");
//      while(1){
//        while(Serial.available()>0){
//          pom = Serial.readString();  // 2em demande du moniteur 
//          file = SD.open("Acces.csv", FILE_WRITE);
//          Serial.println(file.position());
//          string += recois;
//          string += ";" ;
//          string += pom ;
//          file.seek(file.position());
//          file.print(string);
//          Serial.println(string);
//          Serial.println("Enregistrement reussi");
//          
//          file.close();
//          break;
//    }
//    
//        }
//       break; 
//      }
//    else{
//        Serial.println("pas d'enregistrement");
//        break;
//    }
//      
//    }
//  }
//}
//}

c'est avec 'liste' que je voudrais reprendre tout le prog

Désolé, mais je ne vois pas l'intérêt de la liste chaînée.
Si ton code n'a pas besoin de relire le fichier un système de liste est totalement inutile.
La liste chaînée n'a d'intérêt qui si tu cherches à te déplacer dans la liste mais là si j'ai bien compris tu as juste besoin d'enregistrer des informations dans l'ordre chronologique.
Tu n'as pas besoin d'avoir en mémoire toutes les données. Elles ne sont présentes que sur la carte SD?

Il faut savoir que lorsque tu ouvres un fichier en écriture, par défaut, tu ajoutes automatiquement les nouvelles données à la suite de celles qui y sont déjà.

les données sont sur la carte SD.
je dois relire fichier à chaque foois, vu que je compare pour verifier si la personne est dans la BDD et verifier aussi l'autorisation de la porte pour laisser rentrer .
le souci est que lorsque j'ajoute une nouvelle ligne, non seulement : l'enregistrement ne se fait pas tant que j'ai pas le nbre exact de la ligne dans le tableau, une fois que j'aie pu faire cela lors de la nouvelle lecture ca ne prend pas en compte la derniere ligne ajoutée tant j'ai pas modifier la taille du tableau
Sinon a part cela le code marche

Pour qu'il y ait une écriture effective, il faut vider le buffer d'écriture. Un ajout est gardé dans un buffer et n'est écrite que si le buffer est plein ou si on envoie un ordre flush. A chercher du côté de flush.
Il est aussi possible d'écrire non pas en fin de fichier, mais au milieu pour utiliser la SD comme un tableau.

du coup je dois vider le buffer a chaque enregistrement?

Oui. C'est un peu plus long parce que sur une carte, on ne peut écrire que des secteur de 512 octets à la fois. On fait pareil si on risque la coupure.

Pour un accès direct à des octets, il faut chercher du côté de la fonction seek() qui positionne le curseur au milieu du fichier.

file.seek(file.position());

avec cette instruction j'ai voulu me positionner à la position actuelle(fin de ligne) pour enregistrer

Cette instruction ne fait que se positionner la ou l'on est déjà. Elle ne sert donc à rien. Seek() permet surtout de se positionner n'importe où dans le fichier, pour lire un octet quelconque du fichier.

ok
j'ai laissé tomber la liste et le vecteur , en me basant sur un tableau statique d'une grande taille, lorsque j'enregistre, je remplie le tableau fur et à mesure jusqu'à la taille fixée.
pour le côte memo j'ai mis une partie sur la memo flash

Bonjour par ici
J'ai pas vraiment travaillé sur les cartes SD mais pour la fonction Enregistre que je viens de lire, je trouve qu'il y a un petit problème par rapport à ça. Je vois la variable string qui appelée ici mais n'est pas passée en argument à la fonction Enregistre puisque celle ci ne prends aucun argument. Pareil pour la variable recois. La variable recois vient d'où ??

Et je crois normalement si le fichier est ouvert en écriture et qu'on ajoute les données en fin de fichier, on a seulement besoin de récupérer ce qui est contenu dans la variable recu bien sûr avec la virgule à la fin. Et la fonction

suffit pour ajouter.
Aussi il faut préparer les données à enregistrer avant d'ouvrir le fichier; en règle générale la fonction

suit dans la foulé, l'ouverture du fichier.
Je crois qu'il faut tester aussi si le fichier est réellement ouvert puisque dans ce cas-ci c'est possible de perdre des données sans le savoir. Un text du genre

if(fichier) {
  // écrire à la fin du fichier
}

Autan pour moi je vois le contexte des deux variables string et recois.

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