créer Tableau de valeur qui varie

Bonjour cher Forum Arduino,

J'ai créé un bout de code pour un système de badges avec crédit qui fonctionne très bien actuellement.

Je n'arrive pas à simplifier le code en utilisant un tableau pour les crédits, afin de remplacer "credit_B1","credit_B2",...,"credit_B10" dans une seule variable.

Merci d'avance pour l'aide que vous pourrez m'apporter :slight_smile:

voici le bout de code :

//Déclaration des Librairies et PIN....

// Déclaration des constantes liées au délai
unsigned long previousMillis = 0;

// Déclaration des constantes liées au bouton et au crédit
int credit_min = 0;          // Variable crédit minimum
byte tagok = 0;               // Variable pour différencier les types de Badge
 
int credit_B1 = 5;              // Nombre de crédit Badge 1
int credit_B2 = 5;              // Nombre de crédit Badge 2
int credit_B3 = 5;              // Nombre de crédit Badge 3

//etc.... jusqu'à 10 badges différents....

//------------------------------------------------------------------------------------//
//------------------------------  DEFINITION DES VARIABLES  --------------------------//
//------------------------------------------------------------------------------------//

//Permet d'afficher les chiffres sur le 7 segment 
const byte digit[11] = { 
                    B11111100,  // 0
                    B01100000,  // 1
                    B11011010,  // 2
                    B11110010,  // 3
                    B01100110,  // 4
                    B10110110,  // 5
                    B10111110,  // 6
                    B11100000,  // 7
                    B11111110,  // 8
                    B11100110,  // 9
                    B00000000   // clean
                    };
                    
//---------------------------------------------------//
// Code des Badges
unsigned long sernum[13] = {0,            //poste 0 N° badge lue
                            1669386246,   //Badge 1
                            3009123561,   //Badge 2
                            3009327833,   //Badge 3
                            0,            //Badge 4
                            0,            //Badge 5
                            0,            //Badge 6
                            0,            //Badge 7
                            0,            //Badge 8
                            0,            //Badge 9
                            0,            //Badge 10
                            0,            //Badge 11
                            2778220336};  //Carte Master(12)

//------------------------------------------------------------------------------------//
//---------------------- INITIALISATION DE LA CARTE ET DES SORTIES -------------------//
//------------------------------------------------------------------------------------//
 
void setup() 
{
  Serial.begin(9600);        // Initialiser communication avec le serial
//.......
  Serial.println("Présentez votre badge sur le lecteur ...");
}  
 
//------------------------------------------------------------------------------------//
//--------------------------------  PROGRAMME  ---------------------------------------//
//------------------------------------------------------------------------------------//

void loop() 
{       
  // Détecte la présence d'un badge devant le RFID
  if ( ! rfid.PICC_IsNewCardPresent()) {
    return; }

  // Lecture du badge pour réccupérer son UID
  if ( ! rfid.PICC_ReadCardSerial()) {
    return; }

  //Afficher l'UID sur le moniteur série
  Serial.print("UID Badge [");
  String content= "";

  for (byte i = 0; i < rfid.uid.size; i++) 
    {  //Converti UID Binaire en Hexa
     content.concat(String(rfid.uid.uidByte[i], HEX)); 
    }
  //Compare le UID lu avec ceux du tableau de codes déjà enregistré
  sernum[0] = *((unsigned long *)rfid.uid.uidByte); 
  Serial.print(sernum[0]);
  Serial.print("] ");
  tagok = 0;

  for  (byte i = 1; i < 12; i++) {
    if (sernum[0] == sernum[i]) tagok = 1; // badge reconnue dans le tableau
  }
  if (sernum[0] == sernum[12]) tagok = 255; // carte master reconnue
  
//IIIIIIIIIIIIIIIIIIIIIIIIIIIIIII BADGE NON RECONNU  IIIIIIIIIIIIIIIIIIIIIIIIIIIIII//

  if (tagok == 0) 
  { 
    Serial.println("Bagge INCONNU");
    Serial.println();
    LED_Rouge();       //void pour allumer led rouge+Buzzer
  }
  
//IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII BADGE RECONNU IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII//

  if (tagok == 1 )
  {         
    Serial.print("Badge OK");
    previousMillis = millis();                 //RESET le temps pour la boucle while
    
    //00000000000000000000000000000000  sernum[1]  00000000000000000000000000000000//   
  
    if (sernum[0] == sernum[1]) {        // Affiche Nom du Badge et Crédit sur Moniteur 
      Serial.println(" - Badge 1 ");
      Serial.print("Credits= ");
      Serial.println(credit_B1);             // Affiche le crédit lié au badge 1
      
      byte chiffre = digit[credit_B1];    // Affiche Crédit restant du badge sur le 7 segment
      digitalWrite(latchPin, LOW);                  
      shiftOut(dataPin, clockPin, LSBFIRST, chiffre); 
      digitalWrite(latchPin, HIGH);
      LED_Verte();              //void pour allumer led verte+Buzzer
      
      if (credit_B1==0) {     //Si credit vide alors erreur
        LED_Rouge();
      }
      else {
      // Attend appui sur le bouton pour décompter
      while ((sernum[0] == sernum[1]) && (millis() - previousMillis < 10000)) { 
        if(digitalRead(bouton_play)==HIGH){
          if (credit_B1!=credit_min){
            credit_B1--;                             //si appui sur le bouton alors décompte crédit badge 1

      // Affiche Nouveau Crédit restant sur le badge    
      Serial.print("New credits= ");
      Serial.println(credit_B1);
      
      byte chiffreMoins = digit[credit_B1]; // Affiche New Crédit restant du badge sur le 7 segment
      digitalWrite(latchPin, LOW);                  
      shiftOut(dataPin, clockPin, LSBFIRST, chiffreMoins); 
      digitalWrite(latchPin, HIGH);
      LED_Bleu();                          //void pour allumer led bleu+Buzzer
      break;     
          }    
     }
       if ((digitalRead(bouton_play)==LOW) && (millis() - previousMillis > 10000)){
        break; 
    } } } }
    
    //00000000000000000000000000000000  sernum[2]  00000000000000000000000000000000//   
    
     //idem.....
    
    //00000000000000000000000000000000  sernum[3]  00000000000000000000000000000000// 
    
     // idem.....
    
    //00000000000000000000000000000000  sernum[4]  00000000000000000000000000000000// 
     //idem.....
     //etc......

//IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII  CARTE MASTER  IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII//

  if (tagok == 255) 
  {
    if (sernum[0] == sernum[12]) Serial.println("- Carte MASTER");


    //Allume LED VERTE puis BLEU + Double Buzzer son OK + ...

   }
   delay(2000);
   clean_7seg();     // on éteint le 7 segment
}

salut , pour creer un tableau avec 10 membres :

int credit_B[9] = {};

pour affecter une valeur au 5eme membre du tableau :

credit_B[4] = {254};

Première remarque :

  String content= "";
  for (byte i = 0; i < rfid.uid.size; i++)
    {  //Converti UID Binaire en Hexa
     content.concat(String(rfid.uid.uidByte[i], HEX));
    }

Cette variable content ne sert à rien, et l'utilisation de String peut amener des problèmes de fragmentation mémoire.

Ce code pourrait être factorisé bien au delà des variables crédit.
Regrouper les crédits dans un tableau n'apportera pas grand chose, attendu que tu ne parcours même pas la liste des N° de série pour trouver le N° du badge dans la liste.

En regroupant les N° de série et crédits dans une structure :

#define NACCOUNT      12

struct account
{
  unsigned long sernum;
  int credit;
};

struct account accountList[NACCOUNT] =
{
  2778220336, 0,  //Carte Master(0)
  1669386246, 5,  //Badge 1
  3009123561, 5,  //Badge 2
  3009327833, 5,  //Badge 3
  0, 0,           //Badge 4
  0, 0,           //Badge 5
  0, 0,           //Badge 6
  0, 0,           //Badge 7
  0, 0,           //Badge 8
  0, 0,           //Badge 9
  0, 0,           //Badge 10
  0, 0,           //Badge 11
};

// Ensuite on accède au N° de série par accountList[X].sernum, et au crédit par accountList[X].credit.
// Il ne reste plus qu'à parcourir le liste avec une boucle

for(int i = 0 ; i < NACCOUNT ; i++) {
  if (id == accountList[X].sernum) {
    // ici le N° est OK
    // le crédit : accountList[i].credit
  }
}

Tu vois l'idée ?

Stocker l'ID du badge lu dans sernum[0] n'est pas une bonne idée. Utilise plutôt une variable séparée.
Je collerais en 0 plutôt l'ID du master, ainsi si la liste s'allonge il ne change pas de place.

Ensuite je pense que tu es conscient qu'en cas de redémarrage les crédits repartent de leur valeur initiale. Il faudra bien les enregistrer quelque part : EEPROM par exemple.

iznobe:
salut , pour creer un tableau avec 10 membres :

int credit_B[9] = {};

Heu, non!!
pour creer un tableau avec 10 membres :

int credit_B[10] = {};

par contre, l'index pour parcourir le tableau ira de 0 à 9 :wink:

Merci beaucoup pour vos propositions :smiley:

@hbachetti quelle excellente idée le tableau en 2 dimension avec les valeurs credit et sernum 8)
La formulation me plait, je vais essayer de l'adapter à ce que j'ai déjà fait...

Comme tu l'as si bien deviné, à termes je souhaite sauvegarder ce tableau sur la EEPROM. Que dois-je faire pour prévoir cela ? :sweat_smile:

lecture avec EEPROM.get(), écriture avec EEPROM.put()

Est ce que mon code est correct ?

void loop() 
{       
  // Détecte la présence d'un badge devant le RFID
  if ( ! rfid.PICC_IsNewCardPresent()) {
    return; }
  // Lecture du badge pour réccupérer son UID
  if ( ! rfid.PICC_ReadCardSerial()) {
    return; }

  //Afficher l'UID sur le moniteur série

  for(int i = 0 ; i < NACCOUNT ; i++) {
    if (id == accountList[i].sernum) {
      Serial.print("Badge OK - ");
      //(UID Badge [........] )
      Serial.print("UID Badge [");Serial.print(accountList[i].sernum);Serial.println("] ");
      //(Credits : X)
      Serial.print("Credits= ");Serial.println(accountList[i].credit);  

      byte chiffre = digit[accountList[i].credit]];    // Affiche Crédit du badge X sur le 7 segment
      digitalWrite(latchPin, LOW);                  
      shiftOut(dataPin, clockPin, LSBFIRST, chiffre); 
      digitalWrite(latchPin, HIGH);
      LED_Verte();              //Allume Led Verte+Buzzer
    }
    while (id == accountList[i].sernum) && (millis() - previousMillis < 10000)) { //délai avant break
        if(digitalRead(bouton_play)==HIGH){
          if (accountList[i].credit]!=credit_min){
            accountList[i].credit]--;                  //Décompte du crédit lié au badge X
            Serial.print("New credits= ");
            Serial.println(accountList[i].credit);
            byte chiffreMoins = digit[accountList[i].credit]]; // Affiche New Crédit restant du badge X sur le 7 segment
            digitalWrite(latchPin, LOW);                  
            shiftOut(dataPin, clockPin, LSBFIRST, chiffreMoins); 
            digitalWrite(latchPin, HIGH);
            LED_Bleu();
            break
          }
         } 
      else {
        if ((digitalRead(bouton_play)==LOW) && (millis() - previousMillis > 10000)){
        break; 
        }
       }
      } 
     }

Il est plutôt incomplet, mais semble en bonne voie.
Il manque en particulier une ligne essentielle:
id = *((unsigned long *)rfid.uid.uidByte);

Oui en effet petit oubli non-négligeable :grinning:

Qu'entends-tu par incomplet ?

je viens de compléter certaines ligne...

Void Loop(){

// Détecte la présence d'un badge devant le RFID
  if ( ! rfid.PICC_IsNewCardPresent()) {
    return; }
  // Lecture du badge pour réccupérer son UID
  if ( ! rfid.PICC_ReadCardSerial()) {
    return; }
    
  id = *((unsigned long *)rfid.uid.uidByte);
  previousMillis = millis();

  //Afficher l'UID sur le moniteur série

  for(int i = 0 ; i < NACCOUNT ; i++) {
    if (id == accountList[i].sernum) {
      Serial.print("Badge OK - ");
      //(UID Badge [........] )
      Serial.print("UID Badge [");Serial.print(accountList[i].sernum);Serial.println("] ");
      //(Credits : X)
      Serial.print("Credits= ");Serial.println(accountList[i].credit);
      
      byte chiffre = digit[accountList[i].credit]];    // Affiche Crédit du badge X sur le 7 segment
      digitalWrite(latchPin, LOW);                  
      shiftOut(dataPin, clockPin, LSBFIRST, chiffre); 
      digitalWrite(latchPin, HIGH);
      LED_Verte();   //Allume Led Verte+Buzzer
    }
    while (id == accountList[i].sernum) && (millis() - previousMillis < 10000)) { 
        if(digitalRead(bouton_play)==HIGH){
          if (accountList[i].credit]!=credit_min){
            accountList[i].credit]--;
            Serial.print("New credits= ");
            Serial.println(accountList[i].credit);
            byte chiffreMoins = digit[accountList[i].credit]]; // Affiche New Crédit restant du badge X sur le 7 segment
            digitalWrite(latchPin, LOW);                  
            shiftOut(dataPin, clockPin, LSBFIRST, chiffreMoins); 
            digitalWrite(latchPin, HIGH);
            LED_Bleu();  //Allume Led Bleu+Buzzer
            break
          }
         } 
       else {
        if ((digitalRead(bouton_play)==LOW) && (millis() - previousMillis > 10000)){
        break; 
        }
       }
      } 
     }
   else if (id != accountList[i].sernum){
    Serial.println("Bagge INCONNU");
    LED_Rouge();  //Allume Led Rouge+Buzzer
   }
}

Qu'entends-tu par incomplet ?

Incomplet car déclarations, setup(), fonctions annexes absents.

un conseil : plutôt que d'écrire un gros machin monolithique et tester ensuite, écris au fur à mesure, compile et teste. Si tu as le matériel bien entendu.

Re-Bonjour,

J'ai finalisé le code, le système fonctionne parfaitement seulement à la prochaine coupure de courant tous les crédits seront réinitialisés, et ce n'est pas le but. :-\

Voici la structure que je souhaite sauvegarder :

#define NB_COMPTE  12             // Nombre de Badge défini

struct Params
{
  char nom[10];                   // numéro des chambres (ex:CHAMBRE 3)
  unsigned long sernum;           // UID Badge
  int credit;                     // Nombre de crédit sur les badges (par défaut 5 crédits)
};

// On accède au données par Utilisateur[X].nom,
// Utilisateur[X].sernum, et Utilisateur[X].credit.

struct Params Utilisateur[NB_COMPTE] = {
  "MASTER",      2778220336,    0,  // Carte Master
  "CHAMBRE 1",   1669386246,    5,  // Badge 1
  "CHAMBRE 2",   3009123561,    5,  // Badge 2
  "CHAMBRE 3",   3009327833,    5,  // Badge 3
  "CHAMBRE 4",   0,             0,  // Badge 4
  "CHAMBRE 5",   0,             0,  // Badge 5
  "CHAMBRE 6",   0,             0,  // Badge 6
  "CHAMBRE 7",   0,             0,  // Badge 7
  "CHAMBRE 8",   0,             0,  // Badge 8
  "CHAMBRE 9",   0,             0,  // Badge 9
  "CHAMBRE 10",  0,             0,  // Badge 10
  "CHAMBRE 11",  0,             0,  // Badge 11
 //Nom Chambre,  UID Badge,   Nombre de Crédit
};

Comment puis-je dire à mon système :

  • Recherche dans EEPROM "UID Badge"
  • Si valide alors récupère "nombre de crédit" du badge dans EEPROM
  • Si décompte alors écrit dans EEPROM "nouveau crédit" dans EEPROM

Merci encore pour l'aide que vous pourrez m'apporter :smiley:

Pour alors déjà, il y a un problème de dimensionnement de tableau

char nom[10];                   // numéro des chambres (ex:CHAMBRE 3)

alors que tu mets dedans

"CHAMBRE 10",  0,             0,  // Badge 10

Il faut penser que les chaines de caractères ont un terminateur que l'on ne voit pas mais qui occupe quand même un élément du tableau donc il faudrait écrire

char nom[11];                   // numéro des chambres (ex:CHAMBRE 3)

Pour écrire et lire tes structures en EEPROM il faut regarder de ce coté:
EEPROMPut
EEPROMGet

Il y a même des exemples là: https://www.arduino.cc/en/Tutorial/EEPROMPuthttps://www.arduino.cc/en/Tutorial/EEPROMGet

ATTENTION à ne pas faire d'écritures inutiles sous peine de tuer l'EEPROM assez rapidement.

Il y a eu un projet similaire récemment ici (un peu long à lire, mais tout y est je pense)

Tu ne peux pas lire des éléments de tes données directement dans l'EEPROM.

l'EEPROM est juste une mémoire auxiliaire, elle n'est pas "en ligne" avec le processeur, pour lire/écrire dedans tu dois passer par les fonctions spéciales EEPROM.

Donc, pour sauver ton tableau (tout ton tableau) en EEPROM, tu le copies en EEPROM à l'adresse 0 (ou une autre adresse, c'est toi qui gère) avec la fonction qui va bien. Tu passes l'adresse du tableau et sa taille en octets ( utiliser sizeof() ).
C'est possible d'écrire seulement une partie, ou une donnée, mais c'est plus compliqué.
[EDIT] Y'a je crois une fonction intelligente qui n'écrit que les octets modifiés. Pour allonger la durée de vie de la prom.

[Edit]N'oublie pas de tester le codes de retour des fonctions, qui signalent un éventuelle erreur.
Si par exemple au démarrage tu n'arrives pas à lire l'EEPROM, il faut décider quoi faire.

Au démarrage après une coupure, il faut que tu déclares un tableau, avec rien dedans.
(ou utiliser le tableau existant, tel que compilé, s'il y en a un, pour remplacer ses valeurs).
Ensuite tu demandes de lire l'Eeprom à l'adresse 0, avec une autre fonction qui va bien, pour tant d'octets, et de poser le résultat à l'adresse du tableau.

Et voilà ! les données de l'EEPROM sont dans le tableau, utilise les normalement.

Bonjour à tous :slight_smile:

Merci pour vos réponses, cela m'a donné autant de réponse que de nouveau problème :sweat_smile:

lesept:
Il y a eu un projet similaire récemment ici (un peu long à lire, mais tout y est je pense)

J'ai pris le temps de tout lire, mais la personne utilise une interface web pour stocker ses données... Alors que je souhaite utiliser uniquement l'EEPROM.

fdufnews:
Il faut penser que les chaines de caractères ont un terminateur que l'on ne voit pas mais qui occupe quand même un élément du tableau donc il faudrait écrire

  • char nom[11]; // numéro des chambres (ex:CHAMBRE 3)*

Merci pour la correction, c'est quelque chose que je ne connaissais pas :smiley:

J'ai essayé un petit code pour comprendre comment lire ma structure, mais malheureusement je n'arrive pas à changer de ligne...
Voici le code:

#include <EEPROM.h>

float f = 0.00f;   //Variable pour stocker les données lues depuis l'EEPROM.
int eeAddress = 0; //Adresse EEPROM à partir de laquelle commencer la lecture

struct Params {
  char nom[11];
  uint32_t sernum;
  byte credit;
};
///////////////////////////////  ECRIRE SUR EEPROM  ///////////////////////////////
void write_eeprom() {
  EEPROM.put(eeAddress, f);
  eeAddress += sizeof(float); // Déplacer l'adresse vers l'octet suivant après le float 'f'.

  struct Params Badge[12] = {
    //  nom         sernum       credit
    "MASTER",    2778220336,     0,  // Carte Master
    "CHAMBRE 1", 1669386246,     1,  // Badge 1
    "CHAMBRE 2", 3009123561,     2,  // Badge 2
    "CHAMBRE 3", 3009327833,     3,  // Badge 3
    "CHAMBRE 4", 0, 0,               // Badge 4
    "CHAMBRE 5", 0, 0,               // Badge 5
    "CHAMBRE 6", 0, 0,               // Badge 6
    "CHAMBRE 7", 0, 0,               // Badge 7
    "CHAMBRE 8", 0, 0,               // Badge 8
    "CHAMBRE 9", 0, 0,               // Badge 9
    "CHAMBRE 10", 0, 0,              // Badge 10
    "CHAMBRE 11", 0, 0,              // Badge 11
  };

  EEPROM.put(eeAddress, Badge);
  Serial.println("Données Enregistrés !");
}
////////////////////////////////  LIRE SUR EEPROM  ///////////////////////////////////
void read_eeprom() {
  int eeAddress = sizeof(float); // Déplacez l'adresse vers l'octet suivant après le float 'f'.
  Params Badge; // Variable pour stocker l'objet personnalisé lu depuis l'EEPROM.
  EEPROM.get(eeAddress, Badge);

  Serial.println("Lecture des données... ");
  Serial.println(Badge.nom);
  Serial.println(Badge.sernum);
  Serial.println(Badge.credit);
}
////////////////////////////////  SETUP  ///////////////////////////////////////////
void setup() {
  Serial.begin(115200);
  while (!Serial) {
    ; // attendez que le port série se connecte. Nécessaire uniquement pour le port USB natif
  }

  write_eeprom();
  delay (1000);
  read_eeprom();
}


void loop() {

}

Actuellement j'affiche :

Données Enregistrés !
Lecture des données... 
MASTER
2778220336
0

et je souhaite pouvoir afficher par exemple :

Données Enregistrés !
Lecture des données... 
CHAMBRE 3
3009327833
3

Je pensais qu'il fallait utiliser :

Serial.println(Badge[3].nom); // Trouve "CHAMBRE 3"
ou
eeAddress = 3;
EEPROM.get(eeAddress, Badge.nom);

Je vous remercie de m'éclairer :smiley:

Tu t'es inspiré de l'exemple de la bibliothèque, mais tu n'en as pas compris la fonctionnement. Il stocke d'abord un float, puis une structure. Le eeAdress est là pour décaler le stockage de la structure après l'endroit où est stocké le float.

toi, tu n'as pas besoin de ça, tu veux juste stocker ton tableau de structure au début de l'EEPROM (en tout cas c'est ce que je suppsoe).
Donc pour stocker tu fais ça :

void write_eeprom() {

  struct Params Badge[12] = {
    //  nom         sernum       credit
    "MASTER",    2778220336,     0,  // Carte Master
    "CHAMBRE 1", 1669386246,     1,  // Badge 1
    "CHAMBRE 2", 3009123561,     2,  // Badge 2
    "CHAMBRE 3", 3009327833,     3,  // Badge 3
    "CHAMBRE 4", 0, 0,               // Badge 4
    "CHAMBRE 5", 0, 0,               // Badge 5
    "CHAMBRE 6", 0, 0,               // Badge 6
    "CHAMBRE 7", 0, 0,               // Badge 7
    "CHAMBRE 8", 0, 0,               // Badge 8
    "CHAMBRE 9", 0, 0,               // Badge 9
    "CHAMBRE 10", 0, 0,              // Badge 10
    "CHAMBRE 11", 0, 0,              // Badge 11
  };

  EEPROM.put(0, Badge);  // <-- on stocke à l'adresse 0
  Serial.println("Données Enregistrés !");
}

Pour lire la 3ème valeur, c'est plus compliqué, il faut savoir la taille d'une structure pour en sauter 2 :

void read_eeprom(int n) {
  int eeAddress = n * sizeof(Params); // Déplacez l'adresse vers l'octet suivant les n-1 premières données.
  Params Badge; // Variable pour stocker l'objet personnalisé lu depuis l'EEPROM.
  EEPROM.get(eeAddress, Badge);

  Serial.println("Lecture des données... ");
  Serial.println(Badge.nom);
  Serial.println(Badge.sernum);
  Serial.println(Badge.credit);
}

Ça donne ça :

#include <EEPROM.h>

float f = 0.00f;   //Variable pour stocker les données lues depuis l'EEPROM.
int eeAddress = 0; //Adresse EEPROM à partir de laquelle commencer la lecture

struct Params {
  char nom[11];
  uint32_t sernum;
  byte credit;
};
///////////////////////////////  ECRIRE SUR EEPROM  ///////////////////////////////
void write_eeprom() {

  struct Params Badge[12] = {
    //  nom         sernum       credit
    "MASTER",    2778220336,     0,  // Carte Master
    "CHAMBRE 1", 1669386246,     1,  // Badge 1
    "CHAMBRE 2", 3009123561,     2,  // Badge 2
    "CHAMBRE 3", 3009327833,     3,  // Badge 3
    "CHAMBRE 4", 0, 0,               // Badge 4
    "CHAMBRE 5", 0, 0,               // Badge 5
    "CHAMBRE 6", 0, 0,               // Badge 6
    "CHAMBRE 7", 0, 0,               // Badge 7
    "CHAMBRE 8", 0, 0,               // Badge 8
    "CHAMBRE 9", 0, 0,               // Badge 9
    "CHAMBRE 10", 0, 0,              // Badge 10
    "CHAMBRE 11", 0, 0,              // Badge 11
  };

  EEPROM.put(0, Badge);
  Serial.println("Données Enregistrés !");
}
////////////////////////////////  LIRE SUR EEPROM  ///////////////////////////////////
void read_eeprom(int n) {
  int eeAddress = n * sizeof(Params); // Déplacez l'adresse vers l'octet suivant les n-1 premières données.
  Params Badge; // Variable pour stocker l'objet personnalisé lu depuis l'EEPROM.
  EEPROM.get(eeAddress, Badge);

  Serial.println("Lecture des données... ");
  Serial.println(Badge.nom);
  Serial.println(Badge.sernum);
  Serial.println(Badge.credit);
}
////////////////////////////////  SETUP  ///////////////////////////////////////////
void setup() {
  Serial.begin(115200);
  while (!Serial);

  write_eeprom();
  delay (1000);
  read_eeprom(3);
}


void loop() {

}

et ça affiche ça :

Données Enregistrés !
Lecture des données...
CHAMBRE 3
3009327833
3

Merci de ta réponse lesept

J'y vois un peu plus clair déjà :smiley:

Dans le code que tu as remis, je pense que tu as oublié de supprimer "float f = 0.00f; "

En fait, je veux juste atteindre un élément précis d'une ligne pour pouvoir le lire et le modifier si besoin..

Par exemple:

  • Lire le nombre de crédit de la CHAMBRE 3, appliquer un décompte et mettre à jour le crédit.
  • Lire le UID du badge (sernum) et le remplacer par un nouveau

je suppose cela ne correspond plus...

int eeAddress = n * sizeof(Params);

Si, c'est fait pour lire ou écrire à la bonne adresse. Voici un exemple pour changer le crédit de la chambre 3 :

#include <EEPROM.h>

int eeAddress = 0; //Adresse EEPROM à partir de laquelle commencer la lecture

struct Params {
  char nom[11];
  uint32_t sernum;
  byte credit;
};

struct Params Badge[12] = {
  //  nom         sernum       credit
  "MASTER",    2778220336,     0,  // Carte Master
  "CHAMBRE 1", 1669386246,     1,  // Badge 1
  "CHAMBRE 2", 3009123561,     2,  // Badge 2
  "CHAMBRE 3", 3009327833,     3,  // Badge 3
  "CHAMBRE 4", 0, 0,               // Badge 4
  "CHAMBRE 5", 0, 0,               // Badge 5
  "CHAMBRE 6", 0, 0,               // Badge 6
  "CHAMBRE 7", 0, 0,               // Badge 7
  "CHAMBRE 8", 0, 0,               // Badge 8
  "CHAMBRE 9", 0, 0,               // Badge 9
  "CHAMBRE 10", 0, 0,              // Badge 10
  "CHAMBRE 11", 0, 0,              // Badge 11
};

///////////////////////////////  ECRIRE SUR EEPROM  ///////////////////////////////
void init_eeprom() {
  EEPROM.put(0, Badge);
  Serial.println("Données Enregistrées !");
}
////////////////////////////////  LIRE SUR EEPROM  ///////////////////////////////////
void read_eeprom(int n) {
  int eeAddress = n * sizeof(Params); // Déplacez l'adresse vers l'octet suivant après le float 'f'.
  Params Badge;
  EEPROM.get(eeAddress, Badge);

  Serial.println("Lecture des données... ");
  Serial.println(Badge.nom);
  Serial.println(Badge.sernum);
  Serial.println(Badge.credit);
}

void write_eeprom(int n) {
  int eeAddress = n * sizeof(Params); // Déplacez l'adresse vers l'octet suivant après le float 'f'.
  EEPROM.put(eeAddress, Badge[n]);
}
////////////////////////////////  SETUP  ///////////////////////////////////////////
void setup() {
  Serial.begin(115200);
  while (!Serial);

  init_eeprom();  // Première écriture
  read_eeprom(3); // Vérification des données chambre 3

  Badge[3].credit = 6;
  write_eeprom(3); // Modification des données chambre 3
  read_eeprom(3); // Vérification du changement
}

void loop() {

}

C'est super, ça marche nickel ! ;D

Si j'ai bien compris, le "void init_eeprom()" se fait seulement 1 fois lorsque je téléverse le programme ; il copie l'intégralité du tableau sur la EEPROM.

Juste une petite question : n'est-il pas préférable de mettre EEPROM.update() à la place EEPROM.put() ? Dans le but d'éviter trop d'écriture inutile..

EDIT: ça ne marche pas tant que ça finalement :confused: les crédits ne se décompte pas de la mémoire EEPROM mais de la flash...

void loop() {
int credit_min = 0;

  if (digitalRead(bouton_play) == HIGH) {
    if (Badge[3].credit != credit_min) {
      Badge[3].credit--;
      Serial.print("New Credits= "); Serial.println(Badge[3].credit);

      write_eeprom(3); // Modification des données chambre 3
      read_eeprom(3); // Vérification du changement
      delay (2000);
    }
  }
}

Même en mettant la void init_eeprom() en commentaire... À chaque fois que je reset c'est la valeur du tableau qui est reprise et non la nouvelle valeur du crédit après le décompte.

Je pense savoir d'où cela vient, c'est "Badge[3].credit " qui va directement chercher dans la structure et pas dans la mémoire EEPROM. Comment lire le crédit directement depuis la mémoire ?