Enregistrer plusieurs badge RFID

Bonjour

Pour mon projet (contrôle d'accès), j'essaye d'ajouter une fonctionnalité qui est d'enregistrer trois badges, qui déverrouille et lorsqu'on veut en enregistrer un quatrième, le plus ancien ne marche plus pour que le quatrième le remplace. Comme ça il y a toujours que trois badge qui peut déverrouiller le contrôle d'accès.

Le problème, c'est que je suis débutant et j'ai essayé plusieurs chose mais ça été un échec pour l'instant.

Je vous met à disposition mon code (ne fonctionne pas pour enregistrer de nouveau badge)

/*****************************************************************************************************************************************
  BIBLIOTHEQUES UTILISEES
*****************************************************************************************************************************************/
#include <Keypad.h> // Bibliothèque pour le clavier
#include <Password.h> // Bibliothèque pour le mot de passe
//#include <simpleMinuteur.h> // Bibliothèque pour le minuteur
#include <SPI.h> // Bibliothèque pour le capteur RFID
#include <MFRC522.h> // Bibliothèque pour le capteur RFID
#include <Adafruit_Fingerprint.h>
#include <SoftwareSerial.h>


/*****************************************************************************************************************************************
  DEFINITION DES NUMERO DE BROCHE UTILISES
*****************************************************************************************************************************************/
#define relais A0



int carte = 12;

String codebon;
String codebon2;
String codebon3;
String compteur;
String compteur2;
String compteur3;


#define SDA_PIN 10
#define RST_PIN 9

#define RX A1
#define TX A2

char texteRecu;
unsigned int randNumber;

SoftwareSerial BT(A4, A5);

SoftwareSerial mySerial(A2, A3);
Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial);

/*****************************************************************************************************************************************
  DEFINITION D'UN OBJET ("Variable") DE TYPE MFRC522
*****************************************************************************************************************************************/


/*****************************************************************************************************************************************
  DEFINITION D'UN OBJET ("Variable") DE TYPE PASSWORD
*****************************************************************************************************************************************/
Password pwd = Password("1234"); // Définit le mot de passe

/*****************************************************************************************************************************************
  DEFINITION DES VARIABLES et Initialisation
*****************************************************************************************************************************************/
int nbCodeMauvais = 0;

const byte ROWS = 4; // 4 Ligne
const byte COLS = 3; // 3 Colonne

char clavier[ROWS][COLS] = { // Définit les symboles sur les boutons du clavier
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'*', '0', '#'}
};
byte rowPins[ROWS] = {8, 7, 2, 3}; // Broche pour les lignes
byte colPins[COLS] = {4, 5, 6}; // Broche pour les colonnes

Keypad keypad = Keypad( makeKeymap(clavier), rowPins, colPins, ROWS, COLS); // Créé une variable de nom keypad de la fonction Keypad


/*****************************************************************************************************************************************
  CONFIGURATION CARTE ARDUINO UNO
*****************************************************************************************************************************************/
void setup() {

  Serial.begin(9600);
  SPI.begin(); // Met les broches SLCK, MOSI et SS en sortie, met SCLK et MOSI au niveau bas et SS au niveau haut
  BT.begin (9600);
  randomSeed(analogRead(1));



  pinMode(relais, OUTPUT);





  while (!Serial);                                     //Tant qu'il n'y a pas de liaison série, attendre                                         //Attendre 100 ms
  Serial.println("\n\nAdafruit finger detect test");   //Afficher le texte dans le port série
  finger.begin(57600);                                 //Règle la vitesse de liaison série
  delay(5);                                            //Attendre 5 ms
  /* if (finger.verifyPassword())                         //Si le capteur est bien branché
    {
     Serial.println("Found fingerprint sensor!");       //Affiche que le capteur et bien branché
    } else                                               //Sinon
    {
     Serial.println("Did not find fingerprint sensor :("); //Affiche que le capteur est mal branché
     while (1) {                                        //Tant que le capteur est mal branché
       delay(1);                                        //Attendre
     }
    }*/
}

/*****************************************************************************************************************************************
  Programme Principal
*****************************************************************************************************************************************/
void loop()
{

  keypad.addEventListener(keypadEvent); // Créé un événement de nom keypadEvent si le clavier est utilisé
  keypad.getKey();
  // getFingerprintIDez();
  RFID();
  char key = keypad.getKey();


  /*if (BT.available()) {
    texteRecu = BT.read();
    }
    if (Serial.available()) {

    BT.write(Serial.read());
    }
    if (texteRecu == 'a')
    {
    Serial.println("Déverrouiller");
    entree();
    texteRecu = 'x';
    }*/
}



/*****************************************************************************************************************************************
  Fonction RFID() : Sous-Programme qui permet de lire les cartes RFID
*****************************************************************************************************************************************/
void RFID() {

#define SDA_PIN 10
#define RST_PIN 9

  MFRC522 mrfc(SDA_PIN, RST_PIN);
  mrfc.PCD_Init();

  if (! mrfc.PICC_IsNewCardPresent())               //Si il n'y a pas de carte
  {
    return;                                         //attendre
  }
  if (! mrfc.PICC_ReadCardSerial())                 //Si la carte n'est pas lu dans le moniteur
  {
    return;                                         //attendre
  }
  //afficher code du badge :
  String contenu = "";
  String nouveau = "";

  byte lettre;

  if (carte = 0) {
    for (byte i = 0; i < mrfc.uid.size; i++) {
      Serial.println(mrfc.uid.uidByte[i] < 0x10 ? "0" : " ");
      Serial.println(mrfc.uid.uidByte[i], HEX);           //Envoie le code HEX du badge utilisé
      nouveau.concat(String(mrfc.uid.uidByte[i] < 0x10 ? "0" : " "));
      nouveau.concat(String(mrfc.uid.uidByte[i], HEX)); //Sauvegarde le code sous contenu
    }
    nouveau = codebon;
    Serial.println("Code Changé");
    carte++;
    codebon = contenu;


  }

  for (byte i = 0; i < mrfc.uid.size; i++)            //mrfc.uid.size = Taille du code en HEX
  {

    Serial.print(mrfc.uid.uidByte[i] < 0x10 ? "0" : " ");
    Serial.print(mrfc.uid.uidByte[i], HEX);           //Envoie le code HEX du badge utilisé
    contenu.concat(String(mrfc.uid.uidByte[i] < 0x10 ? "0" : " "));
    contenu.concat(String(mrfc.uid.uidByte[i], HEX)); //Sauvegarde le code sous contenu
    contenu.toUpperCase();
    if (contenu.substring(1) == codebon)
    {
      Serial.println("Accès autorisé");           //Afficher accès autorisé
      Serial.println();
      entree();
      delay(2000);


    }


  }
}







/*****************************************************************************************************************************************
  Fonction entree qui permet de faire ouvrir la gâche
*****************************************************************************************************************************************/
void entree() {
  digitalWrite(relais, HIGH);
  delay(100);
  digitalWrite(relais, LOW);
}

Ou allez vous enregistrer ces données (que se passe t il en cas de panne de courant) ?
Quelle procédure d’enregistrement de nouveau badge avez vous prévue ?

Que fait le code que vous avez posté ?

Dans la librairie RFID il y a un exemple complet de gestion des accès, l’avez vous regardé ?

Merci pour l'exemple, je ne l'avais pas vu.

Donc globalement ce que je veux faire est la même chose que ce programme mais après l'avoir essayé il y a des choses que j'aimerais changé.

Par exemple, dans cette exemple il y a une carte "maîtresse" pour enregistrer ou supprimer des nouvelles cartes mais moi j'aimerais avoir cette fonctionnalité avec une application (déjà créé) donc est ce que c'est possible.

Pou enregistrer les données je comptais utiliser l'EEPROM comme dans l'exemple.

PS: je rappelle que je suis un très grand débutant alors les 3/4 des lignes du programmes exemple je comprend rien donc parfois je peux dire ou demandé des choses évidentes pour vous mais qui ne l'est pas pour moi.

Bouyou:
Par exemple, dans cette exemple il y a une carte "maîtresse" pour enregistrer ou supprimer des nouvelles cartes mais moi j'aimerais avoir cette fonctionnalité avec une application (déjà créé) donc est ce que c'est possible.

tout est possible, il suffit de le programmer :slight_smile:

PS: je rappelle que je suis un très grand débutant alors les 3/4 des lignes du programmes exemple je comprend rien

votre projet est alors sans doute trop ambitieux pour votre niveaux. Pour bien débuter avec l'arduino, un bon point de départ c'est de lire les tutos d'eskimon et autres exemples, ça vous permet de maîtriser la plateforme.

Oui il est trop ambitieux pour moi mais le problème c'et que je suis en terminal et c'est mon projet donc j'essaye de faire au mieux.

c'est souvent une erreur de se précipiter vers l'objectif final en y comprenant rien et espérer que ça tombe en marche... vous avez du temps encore devant vous (surtout vu la situation sanitaire), accumulez de l'expertise sur la base du codage en C et C++, comprendre les exemples etc... vous y passerez sans doute quelques heures mais cet investissement sera sans doute bcp plus payant car vous comprendrez ce que vous faites ensuite..

Vous avez raison mais le problème c'est que j'ai plein d'autre chose à faire à côté (et croyez-moi c'est pas passé sa journée à joué au PC ou à la console) et je l'avoue ce n'est n'est pas vraiment un sujet qui me passionne.

Pour revenir à mon projet, j'ai une idée pour programmer ce que je veux faire mais pour cela j'essaye de lire dans le port série mais je n'y arrive pas. J'ai essayé avec "Serial.read" mais sans succès, avez vous une idée comment faire ?

Bouyou:
Pour revenir à mon projet, j'ai une idée pour programmer ce que je veux faire mais pour cela j'essaye de lire dans le port série mais je n'y arrive pas. J'ai essayé avec "Serial.read" mais sans succès, avez vous une idée comment faire ?

Pour écouter le port série (ou gérer un flux asynchrone genre keypad) vous pouvez jeter un oeil à mon petit tuto sur le sujet

vous comprenez bien que c'est votre projet et si ça ne vous passionne pas, ça ne nous passionne pas non plus de le faire pour vous...

OK merci je vais voir ça tout de suite.

Même si je n'aime pas trop ça (je vais pas faire semblant) j'apprécie votre aide parce que même si je n'apprécie pas trop la programmation, c'est mon projet de fin d'année donc faut au moins que j'essaye.

Je suis direct mais c'est le plus honnête et merci de l'être aussi.

Oui on comprend que ce projet est important pour vous, mais le faire à votre place ne va rien résoudre.

avez vous rédigé la spécification fonctionnelle par exemple ? exprimer comment vous voyer le truc fonctionner ? comment on rajoute un nouveau badge, que se passe-t-il en cas de coupure de courant, y-a-t-il un moyen de revenir aux badges de départ, que fait le système sinon en fonctionnement normal etc..

commencer par savoir là où vous voulez exactement aller et le documenter est une bonne première étape.

Bonjour

Merci pour votre tuto j'ai pu comprendre comment fonctionne le Serial.read.

Maintenant, j'ai essayé ce que je voulais faire et de nouveau problème sont apparu.

Déjà je vais vous expliquer, ce que je veux faire:

Quand le lecteur série lis la lettre "b", le lecteur de badge enregistre la carte dans une variable et après si on veut déverrouiller, quand on passe la carte, l'arduino regarde s'il s'agit du bon code et ouvre.

Maintenant ce qu'il se passe, quand j'envoi la lettre "b" et que je passe la carte, le code du badge est sur plusieurs ligne (je suis d’accord c'est pas très clair dis comme ça, une photo est plus clair) et donc évidemment ensuite en voulant déverrouiller cela ne fonctionne pas.

Une idée pour régler ce problème ?

#include <SPI.h> // Bibliothèque pour le capteur RFID
#include <MFRC522.h> // Bibliothèque pour le capteur RFID



String nouveau = "";
String codebon = "";
String contenu = "";

#define SDA_PIN 10
#define RST_PIN 9

void setup() {
  Serial.begin(9600);
  SPI.begin();

}

void loop() {
  RFID();
  nouveaubadge();
}

void RFID() {


  MFRC522 mrfc(SDA_PIN, RST_PIN);
  mrfc.PCD_Init();

  if (! mrfc.PICC_IsNewCardPresent())               //Si il n'y a pas de carte
  {
    return;                                         //attendre
  }
  if (! mrfc.PICC_ReadCardSerial())                 //Si la carte n'est pas lu dans le moniteur
  {
    return;                                         //attendre
  }
  for (byte i = 0; i < mrfc.uid.size; i++)            //mrfc.uid.size = Taille du code en HEX
  {
    Serial.print(mrfc.uid.uidByte[i] < 0x10 ? "0" : " ");
    Serial.print(mrfc.uid.uidByte[i], HEX);           //Envoie le code HEX du badge utilisé
    codebon.concat(String(mrfc.uid.uidByte[i] < 0x10 ? "0" : " "));
    codebon.concat(String(mrfc.uid.uidByte[i], HEX)); //Sauvegarde le code sous contenu
  }
  Serial.println();
  Serial.print("Message : ");
  codebon.toUpperCase();
  if (codebon.substring(1) == contenu)    //Si le code est bon
  {
    Serial.println("Accès autorisé");
  }
  else                                          //Si le code est mauvais
  {
    Serial.println("Accès refusé");             //Afficher Accès refusé

  }

}

void nouveaubadge() {

  MFRC522 mrfc(SDA_PIN, RST_PIN);
  mrfc.PCD_Init();

  if (Serial.available() > 0)
  {
    char Ncode = Serial.read();
    if (Ncode == 'b') {
      if (! mrfc.PICC_IsNewCardPresent())               //Si il n'y a pas de carte
      {
        return;                                         //attendre
      }
      if (! mrfc.PICC_ReadCardSerial())                 //Si la carte n'est pas lu dans le moniteur
      {
        return;                                         //attendre
      }
      for (byte i = 0; i < mrfc.uid.size; i++) {
        Serial.println(mrfc.uid.uidByte[i] < 0x10 ? "0" : " ");
        Serial.println(mrfc.uid.uidByte[i], HEX);           //Envoie le code HEX du badge utilisé
        nouveau.concat(String(mrfc.uid.uidByte[i] < 0x10 ? "0" : " "));
        nouveau.concat(String(mrfc.uid.uidByte[i], HEX)); //Sauvegarde le code sous contenu
      }
      
      
      nouveau = codebon;
      codebon = contenu;

      Serial.println("Badge Changé");

    }


  }
}

la photo

Maintenant ce qu'il se passe, quand j'envoi la lettre "b" et que je passe la carte, le code du badge est sur plusieurs ligne (je suis d'accord c'est pas très clair dis comme ça, une photo est plus clair) et donc évidemment ensuite en voulant déverrouiller cela ne fonctionne pas.

ben c'est parce que vous les imprimez en allant à la ligne... :o :confused:

        Serial.println(mrfc.uid.uidByte[i] < 0x10 ? "0" : " ");
        Serial.println(mrfc.uid.uidByte[i], HEX);           //Envoie le code HEX du badge utilisé

(le ln de println() )

Bonjour
Effectivement c'était tout con :cold_sweat:

Donc maintenant, j'ai continuer mon programme mais, je rencontre un nouveau problème.

J'ai l'impression que la valeur dans la variable "nouveau" n'est pas pris en compte.

Je m'explique: Normalement quand le programme lis la lettre "b", il demande de rapprochez la carte et sauvegarde son code dans la variable "nouveau".
Ensuite, lorsque que le lecteur lis une nouvelle carte, le programme regarde si le code de la nouvelle carte est le même que celui de la variable "nouveau", si oui, cela affiche "Accès autorisé" et si non cela affiche "Accès refusé".

Mais voila, cela ne fonctionne pas (donc il y a une erreur dans mon programme mais je la trouve pas), et je pense que le problème vient de la variable "nouveau", qui enregistre pas le code de la carte au début.

#include <SPI.h> // Bibliothèque pour le capteur RFID
#include <MFRC522.h> // Bibliothèque pour le capteur RFID

String nouveau = "";
String contenu2 = "";

#define SDA_PIN 10
#define RST_PIN 9

void setup() {
  Serial.begin(9600);
  SPI.begin();

}

void loop() {
  RFID();
  nouveaubadge();
}



void RFID() {


  MFRC522 mrfc(SDA_PIN, RST_PIN);
  mrfc.PCD_Init();

  if (! mrfc.PICC_IsNewCardPresent())               //Si il n'y a pas de carte
  {
    return;                                         //attendre
  }
  if (! mrfc.PICC_ReadCardSerial())                 //Si la carte n'est pas lu dans le moniteur
  {
    return;                                         //attendre
  }

  Serial.print("Code du badge :");                  //afficher code du badge :

  byte lettre;

  for (byte i = 0; i < mrfc.uid.size; i++)            //mrfc.uid.size = Taille du code en HEX
  {
    Serial.print(mrfc.uid.uidByte[i] < 0x10 ? "0" : " ");
    Serial.print(mrfc.uid.uidByte[i], HEX);           //Envoie le code HEX du badge utilisé
    contenu2.concat(String(mrfc.uid.uidByte[i] < 0x10 ? "0" : " "));
    contenu2.concat(String(mrfc.uid.uidByte[i], HEX)); //Sauvegarde le code sous contenu
  }
  Serial.println();

 

  if (contenu2 == nouveau)
  {
    Serial.println();
    Serial.print("Message : ");
    nouveau.toUpperCase();
    if (nouveau.substring(1))    //Si le code est bon
    {
      Serial.println("Accès autorisé");
      delay(50);
    }

  }
  else                                          //Si le code est mauvais
  {
    Serial.println("Accès refusé");             //Afficher Accès refusé

  }
}


void nouveaubadge() {

  MFRC522 mrfc(SDA_PIN, RST_PIN);
  mrfc.PCD_Init();

  if (Serial.available() > 0)
  {
    char Ncode = Serial.read();
    if (Ncode == 'b') {
      Serial.println("Approchez la carte du lecteur");
      delay(3000);
      if (! mrfc.PICC_IsNewCardPresent())               //Si il n'y a pas de carte
      {
        return;                                         //attendre
      }
      if (! mrfc.PICC_ReadCardSerial())                 //Si la carte n'est pas lu dans le moniteur
      {
        return;                                         //attendre
      }
      Serial.print("Code du nouveau badge :");                  //afficher code du badge :

      byte lettre;
      for (byte i = 0; i < mrfc.uid.size; i++) {
        Serial.print(mrfc.uid.uidByte[i] < 0x10 ? "0" : " ");
        Serial.print(mrfc.uid.uidByte[i], HEX);           //Envoie le code HEX du badge utilisé
        nouveau.concat(String(mrfc.uid.uidByte[i] < 0x10 ? "0" : " "));
        nouveau.concat(String(mrfc.uid.uidByte[i], HEX)); //Sauvegarde le code sous "nouveau"
      }



    }



    Serial.println();
    Serial.println("Badge Changé");

  }


}

Pourquoi passer par des Strings quand vous avez l’info dans un tableau (mrfc.uid.uidByte)... prenez un tableau similaire d’octets pour conserver votre copie (qu’on peut peut dupliquer d’un coup avec memcpy() )... et on peut même ensuite comparer deux segments mémoires avec memcmp()

Sinon il ne faut faire qu’une seule fois dans le setup la partie

 MFRC522 mrfc(SDA_PIN, RST_PIN);
  mrfc.PCD_Init();

et je pense qu’il faut mieux gérer le mode de présentation, la si vous ratez la fenêtre de trois seconde vous repartez dans la loop qui va écraser contenu2 avec le nouveau badge

Il faudrait une petite machine à etat, pas la peine d’avoir deux fois le code de lecture d’un badge. Faut juste l’appeler et récupérer L’identifiant du badge au bon moment

Bonjour

Bon je vais partir sur autre programme parce que je bloque sur celui-la mais avant j'aimerais bien savoir si cette ligne de code: Serial.print(mrfc.uid.uidByte *< 0x10 ? "0" : " "); *
Permet bien d'afficher le code en décimal.
J'aimerais savoir parce que c'est une des lignes du programmes que ne suis pas sur de comprendre et je voudrais vraiment comprendre à quoi elle sert.

Bouyou:
avant j'aimerais bien savoir si cette ligne de code: Serial.print(mrfc.uid.uidByte *< 0x10 ? "0" : " "); *
Permet bien d'afficher le code en décimal.[/quote]
L'expression ternaire
* *[color=blue]condition ? x : y[/color]* *
s'évalue à x si la condition est vraie et y si la condition est fausse.
donc ici on dit imprime "0" si mrfc.uid.uidByte[ i ] < 0x10, sinon imprime un espace.
C'est plus donc pour imprimer en HEXADECIMAL avec un ZERO si votre nombre (de 0x00 à 0xFF) n'a qu'un 'chiffre' (donc de 0x0 à 0xF on veut afficher 0x00 à 0x0F).
==> il ne faut pas afficher un espace si c'est plus grand que 0x10 mais rien du tout