Besoin d'aide - Ajout d'un accès badge dans un tableau (RFID)

Bonjour,
je suis en train de faire un projet de serrure de porte (on peut en voir pleins partout je sais...je suis désolé...) je me suis inspiré de codes existant, de vidéos et de réponses que j'ai pue trouver sur différents topics et forum. J'en suis à là: (voir code ci dessous).

Le concept, ouvrir l'électroaimant (pour une porte) lorsqu'un badge autorisé est passé devant le lecteur (c'est du RFID mais je passerais plus tard sur du NFC avec ce shield: celui là chez gotronic (mais c'est un autre soucis je m'en occuperais)

#include <SPI.h>      //bibliothèques
#include <MFRC522.h>  //**

#define RST_PIN         9   //pin reset RC522
#define SS_PIN          10  //pin SS RC522

const int Buzzer = 2;         //pin du buzzer sur breadboard
const int LedR = 3;           //pin de la Led rouge sur breadboard
const int LedV = 4;           //pin de la Led verte sur breadboard
const int Electroaimant = 5;  //pin de l'éléctroaimant (serrure via un relay) sur breadboard

int etatLedR = LOW;           //etat de base lors de l'initialisation
int etatLedV = LOW;           //**
int etatElectroaimant = LOW;  //**

MFRC522 monRFID(SS_PIN, RST_PIN); //RC522 initialisation



void setup() {
  pinMode(Buzzer, OUTPUT);          //pin Mode :
  pinMode(LedR, OUTPUT);            //**
  pinMode(LedV, OUTPUT);            //**
  pinMode(Electroaimant, OUTPUT);   //**

  SPI.begin();          //initialisation SPI
  monRFID.PCD_Init();   //RFID initialisation

  Serial.begin(9600);   //Com Série à 9600 baud

  digitalWrite(LedR, etatLedR);                     //mise à l'état de base
  digitalWrite(LedV, etatLedV);                     //**
  digitalWrite(Electroaimant, etatElectroaimant);   //**
  tone(Buzzer, 800, 50);  //bip d'initialisation Ok et passage à la boucle loop()
  delay(100);             //**
  tone(Buzzer, 800, 50);  //**
}



void loop() {
  if ( ! monRFID.PICC_IsNewCardPresent())  //Si Carte ou Badge RFID détécté
  {
    return;
  }
  if ( ! monRFID.PICC_ReadCardSerial())   //Si carte ou Badge RFID correctement lue
  {
    return;
  }

  String UID = "";

  for (byte i = 0; i < monRFID.uid.size; i++)
  {
    UID.concat(String(monRFID.uid.uidByte[i] < 0x10 ? " 0" : " "));   //"mise en page" en format HEX de l'UID
    UID.concat(String(monRFID.uid.uidByte[i], HEX));                  //**
  }

  UID.toUpperCase();

  if (UID.substring(1) == "97 F7 1E 39") //Code d'accès autorisé
  {
    digitalWrite(LedV, HIGH);           //allumer LED Verte
    digitalWrite(Electroaimant, HIGH);  //ouvrir serrure
    tone(Buzzer, 1200, 100);            //Bip content
    delay(125);                         //** (à voir pour changer delay(125); par millis())
    tone(Buzzer, 1800, 100);            //**
    delay(3000);                        //attente 3secondes (à remplacer plus tard par la fonction millis())
    digitalWrite(LedV, LOW);            //RàZ
    digitalWrite(Electroaimant, LOW);   //**
  }

  else  //Code d'accès refusé
  {
    digitalWrite(LedR, HIGH);   //allumer LED Rouge
    tone(Buzzer, 600, 100);     //Bip méchant
    delay(125);                 //** (à voir pour changer delay(125); par millis())
    tone(Buzzer, 400, 100);     //**
    delay(1000);                //attente 1 secondes (à remplacer plus tard par la fonction millis())
    digitalWrite(LedR, LOW);
  }
}

Donc j'ai ce code :arrow_heading_up:

Le soucis: j'aimerais pouvoir gérer l'accès de différents badge pas que d'un seul je me suis donc intéressé aux tableaux avec ce code (fonctionnel) si dessous:

#include <SPI.h>
#include <MFRC522.h>

#define SS_PIN 10    //Arduino Uno
#define RST_PIN 9
byte tagok = 0;

unsigned long sernum[11] = {0, 1669538043, 4062424836, 958330775, 0, 0, 0, 0, 0,0, 2671698952}; //poste 0 N° carte lue, poste 1 à 9 pour UID carte a tester, poste 10 carte master

MFRC522 mfrc522(SS_PIN, RST_PIN);        // Create MFRC522 instance.
MFRC522::MIFARE_Key key;
int led = 3;
void setup() {
  pinMode(led, OUTPUT);
  Serial.begin(9600);        // Initialize serial communications with the PC
  SPI.begin();                // Init SPI bus
  mfrc522.PCD_Init();        // Init MFRC522 card
Serial.println("SERIAL OK ");
}

void loop() {

  digitalWrite(led, LOW);
  // Look for new cards
  if ( ! mfrc522.PICC_IsNewCardPresent()) {
    return;
  }

  // Select one of the cards
  if ( ! mfrc522.PICC_ReadCardSerial())    return;

  Serial.print("Card UID:");    //Dump UID
  for (byte i = 0; i < 4; i++) {
    Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
    Serial.print(mfrc522.uid.uidByte[i], HEX);
  }

  sernum[0] = *((unsigned long *)mfrc522.uid.uidByte); //recup num serie lu long unsigned

  Serial.print(" ");
  Serial.print(sernum[0]);
  Serial.print(" ");
  Serial.print(sernum[0], HEX);
  Serial.print(" ");
  tagok = 0;
  for  (byte i = 1; i < 10; i++) {
    if (sernum[0] == sernum[i]) tagok = 1; // carte reconnue dans la liste

  }
  if (sernum[0] == sernum[10]) tagok = 255; // carte master reconnue

  if (tagok == 0) { // faire si carte inconnue
    Serial.print("TAG INCONNU");
  }
  if (tagok >0) //faire si carte reconnue
  {
    digitalWrite(led, HIGH);
    Serial.print("TAG OK ");
    if (sernum[0] == sernum[1]) Serial.print("Badge STOCK     " ); 
    if (sernum[0] == sernum[2]) Serial.print("Badge LABO      " ); 
    if (sernum[0] == sernum[3]) Serial.print("Bramble card OK " ); 
    if (sernum[0] == sernum[4]) Serial.print("Badge ANECHO    " ); 
    if (sernum[0] == sernum[10]) Serial.print("Badge MASTER    " ); 
    delay(50);
    digitalWrite(led, LOW);
  }

  if (tagok == 255) //faire si carte master reconnue
  {

    Serial.print("CARTE MASTER RECONNUE");

  }


Serial.println();

mfrc522.PICC_HaltA(); // Halt PICC

}

(code récupéré sur un topic: celui là, lien vers forum.arduino.cc)
donc jusqu'à là aucun soucis, mais j'aimerais, et je ne sais pas si c'est possible, qu'au passage d'un badge "admin ajout d'un accès", mes LEDs clignotent et que l'Arduino reste en attente d'un nouveau badge à scanner pour lui autoriser l'accès.
Et qu'au passage d'un badge "admin suppression d'un accès", mes LEDs clignotent et que l'Arduino reste en attente du badge à supprimer son accès.

Donc je ne sais pas comment faire... mais faudrait une taille de tableau variable (des accès autorisé) qu'il puisse stocker en lui les accès autorisés et en supprimer en fonction du type de badge admin scanné

Merci d'avance si quelqu'un à une solution
PS: j'espère avoir posté au bon endroit

oui et avec les balises de code et de l'info - bravo :slight_smile:

c'est typiquement une définition de programme qui se prête bien à la programmation par machine à états (cf mon tuto éventuellement)

Vous aurez différents états pour votre système

les évènements à traiter sont le temps qui passe (il faut un timeout pour sortir du mode admin au bout d'un certain temps si aucun badge n'est présenté ou refermer la porte un certain temps après son ouverture par exemple) et la présentation d'un badge.

1 Like

Tableau de taille variable : pas possible en C.
Mais tu peux contourner en faisant un tableau de structures. Dans ces structures, tu peux mettre des informations, comme par exemple la validité d'un badge.

Exemple :

struct badge {
    unsigned long sernum;
    bool validite;
    char* nom[];
};
badge badges[11];
badge[0] = {1669538043, true, "Admin"};
badge[1] = {4062424836, false, "Lesept"}; // Badge annulé

A tester...

on ne peut pas affecter comme cela

ce serait un const char* et le souci ensuite serait de changer le nom si on ajoute un nouveau badge.

il vaudrait mieux un tableau de longueur fixe

const size_t tailleMaxNom = 10;
const size_t nombreMaxDeBadges = 20;
 
struct Badge {
    uint32_t id;               // l'identifiant 
    bool estActif;             // vrai ou faux
    char* nom[tailleMaxNom+1]; // le nom (+1 pour le caractère nul de fin)
};

Badge lesBadges[nombreMaxDeBadges] = {
  {1669538043, true, "Admin"},
  {4062424836, false, "Lesept"},
  ...
};

Bonjour

créer un accès avec vérification du seul code UID est une aberration ...
Surtout que la c'est même du NUID

hello

je viens de chek et ton tuto est pas mal intéressant et tu as su complétement comprendre mes besoins et mon système, ton image est très parlante merci (et merci aussi pour le compliment de mon post mdr c'était mon premier post de ma vie sur arduino :sweat_smile:)

donc tu me conseille de faire une structure comme ça ?

const size_t tailleMaxNom = 10;
const size_t nombreMaxDeBadges = 20;
 
struct Badge {
    uint32_t id;               // l'identifiant 
    bool estActif;             // vrai ou faux
    char* nom[tailleMaxNom+1]; // le nom (+1 pour le caractère nul de fin)
};

Badge lesBadges[nombreMaxDeBadges] = {
  {1669538043, true, "Admin"},
  {4062424836, false, "Lesept"},
  ...
};

je vais essayer out cela mais si quelqu'un accepte de me donner des explications un peu plus pousser

à voir ce que vous mettez dans la structure. Le nom n'est pas forcément nécessaire si vous n'avez pas moyen d'en rentrer un lors de l'enregistrement d'un nouveau badge

je ferais plutôt

enum TypeBadge {ADMIN, UTILISATEUR, SUPER_UTILISATEUR}; 

const size_t nombreMaxDeBadges = 20;
 
struct Badge {
    uint32_t id;               // l'identifiant 
    bool estActif;             // vrai ou faux
    TypeBadge type;            // quels sont les droits associés
};

le type permettrait peut-être de différencier l'accès à certaines fonctions mais là encore il faudra un mode opératoire spécifique pour enregistrer les droits associés à un nouveau badge

dans mon cas j'ai une carte "admin ajouter accès" et une carte "admin supprimer accès" puis 20 utilisateurs maximum.

Hors je ne sais pas comment attribuer au tableau la valeur lue après scan de la carte "ajouter" par exemple

chaque badge scanné après le scan du badge recevra l'accès utilisateur hors je ne sais pas comment faire cela

vous pourriez créez les 2 badges Admin en dur et initialiser toutes les autres positions à inutilisées

enum DroitsBadge {ADMIN_AJOUT, ADMIN_RETRAIT, UTILISATEUR, INUTILISE}; 

const size_t nombreMaxDeBadges = 20;
 
struct Badge {
    uint32_t id;               // l'identifiant 
    DroitsBadge droits;            // le droits associés au badge
};

Badge lesBadges[nombreMaxDeBadges] = {
  {1669538043, ADMIN_AJOUT}, 
  {4062424836, ADMIN_RETRAIT}, 
}


void setup() {
  // on remplit les badges (en pratique il faudra sauver en EEPROM une première fois et ensuite relire)
  for (byte i = 2; i < nombreMaxDeBadges; i++) {
    lesBadges[i].id = 0;
    lesBadges[i]. droits = INUTILISE;
  }

  Serial.begin(115200);

  ...
} 

void loop() {}

Quand le badge ADMIN_AJOUT est détecté alors vous lisez le tableau dans l'ordre et vous prenez la première case ou l'attribut droits est INUTILISE ➜ c'est une case vide donc vous stockez la nouvelle carte à cet endroit. Si vous n'en trouvez pas c'est que le tableau est plein et on ne peut pas ajouter de cartes.

Quand le badge ADMIN_RETRAIT est détecté alors vous lisez le tableau dans l'ordre et si la case est de droit UTILISATEUR alors vous comparez l'id stocké à l'ID de la carte présentée. Si c'est le même alors vous pouvez détruire la carte à cet endroit en mettant son ID à 0 et en changeant droits à INUTILISE

donc ça c'est ce qu'il faut que je fasse dans ma void loop() c'est bien celà? j'espère arriver à le faire, sinon je vais reprendre mes cours en C sur les tableaux :joy:

la loop doit exécuter la machine à état dont j'ai donné une version initiale dans le schéma du post 2

le bout de code qui ajoute ou retire une carte se trouve dans le traitement d'un des changements d'état.

1 Like

Parfait demain je m'en occupe merci beaucoup pour tout ce que tu m'a apporté

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