Projet multi lecteur rfid pour projet d'éduc pop

Bonjour.
Je travail pour un organisme d'éducation populaire sur une série d'ateliers pour présenter différentes facette des mécanismes impliqués dans les processus d'évolution et de disparition d'espèce. Ma demande concerne une activité visant à parler des espèces endogènes.
Afin de rendre le propos plus interactif, le but serait de placer des figurines animales sur différents lieux d'un planisphère pour retrouver leur zone d'origine.
J'ai eu donc l'idée d'associer un arduino avec des lecteurs RFID.
Le principe du montage est simple : Si la carte rfid est placée au bon endroit alors l'écran affiche : "espece reconnue" si la carte n'est pas placée au bon endroit alors l'écran affiche "espece non présente ici."

probleme : Je n'ai aucune compétence en code et en arduino. Donc, utilisation à base d'I.A car je n'ai malheureusement pas la possibilité de faire autrement ( pas de budget et pas de temps)
Je souhaiterai donc que quelqu'un puisse me dire si ce code fonctionne vraiment.
Je vous remercie d'avance.



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

#define NB_LECTEURS 6

// LCD I2C
LiquidCrystal_I2C lcd(0x27, 16, 2);

// Pins SS (SDA) pour chaque lecteur
const byte ssPins[NB_LECTEURS] = {10, 8, 7, 6, 5, 4};
// Pins RST pour chaque lecteur
const byte rstPins[NB_LECTEURS] = {9, 3, 2, A0, A1, A2};

// Création des lecteurs RFID
MFRC522 lecteurs[NB_LECTEURS] = {
  MFRC522(ssPins[0], rstPins[0]),
  MFRC522(ssPins[1], rstPins[1]),
  MFRC522(ssPins[2], rstPins[2]),
  MFRC522(ssPins[3], rstPins[3]),
  MFRC522(ssPins[4], rstPins[4]),
  MFRC522(ssPins[5], rstPins[5]),
};

// Tableau des UID valides (exemples fictifs à remplacer par les vrais UID de tes cartes)
byte uids[NB_LECTEURS][4] = {
  {0x11, 0x22, 0x33, 0x44},  // UID carte 0 → lecteur 0
  {0xAA, 0xBB, 0xCC, 0xDD},  // UID carte 1 → lecteur 1
  {0x01, 0x02, 0x03, 0x04},  // UID carte 2 → lecteur 2
  {0x10, 0x20, 0x30, 0x40},  // UID carte 3 → lecteur 3
  {0xA1, 0xB2, 0xC3, 0xD4},  // UID carte 4 → lecteur 4
  {0x55, 0x66, 0x77, 0x88}   // UID carte 5 → lecteur 5
};

// Compare un UID à un UID connu
bool compareUID(byte *uid1, byte *uid2) {
  for (byte i = 0; i < 4; i++) {
    if (uid1[i] != uid2[i]) {
      return false;
    }
  }
  return true;
}

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

  lcd.init();
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print("Systeme RFID Pret");
  delay(2000);
  lcd.clear();

  // Initialisation des lecteurs
  for (int i = 0; i < NB_LECTEURS; i++) {
    lecteurs[i].PCD_Init();
    delay(100); // petit délai pour éviter conflits
  }
}

void loop() {
  for (int i = 0; i < NB_LECTEURS; i++) {
    if (!lecteurs[i].PICC_IsNewCardPresent() || !lecteurs[i].PICC_ReadCardSerial()) {
      continue;
    }

    Serial.print("Lecteur ");
    Serial.print(i);
    Serial.print(" a lu l'UID : ");
    for (byte j = 0; j < lecteurs[i].uid.size; j++) {
      Serial.print(lecteurs[i].uid.uidByte[j], HEX);
      Serial.print(" ");
    }
    Serial.println();

    // Vérifie si l'UID correspond à celui attendu pour ce lecteur
    if (compareUID(lecteurs[i].uid.uidByte, uids[i])) {
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Espece reconnue");
    } else {
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Espece non");
      lcd.setCursor(0, 1);
      lcd.print("presente ici");
    }

    delay(3000);
    lcd.clear();

    lecteurs[i].PICC_HaltA();
    lecteurs[i].PCD_StopCrypto1();
  }
}
1 Like

Bonjour aurion64

As tu déjà câblé au moins 1 lecteur ?
Ou as tu un problème de schéma ?

A+
Cordialement
jpbbricole

Si tu as déjà câblé au moins un lecteur, tu peux éditer le programme, modifier cette variable:
define NB_LECTEURS 6
En mettant 1 ensuite télécharger le sketch.

Pour l'instant, Je reconnais que n'ayant ni le matériel c'est très hypothétique.
Je suis aller chercher pas mal de schéma en ligne et ce qui s'est déjà fait.

Nottament.
Je prendrai une photo ou je ferrai un schéma lorsque j'aurai le matériel en main. malheureusement celui ci est susceptible de bouger vu que je dépends de la possibilité d'avoir accès à tel ou tel fournisseur.
Et comme mon délais est très court je commence déjà a voir niveau code ce que ca peut donner...
(Je sais je fais les choses dans un désordre complet...)

Un souci possible est que les lecteurs MFRC522 que l’on trouve un peu partout sont de qualité variable et l’on voit passer de nombreux posts où l’usage de plusieurs lecteurs MFRC522 connectés au même arduino ne donne pas satisfaction, ça plante etc…

Le site la bibliothèque en parle, cf par exemple

Et autres #191, #277 Ou encore #263

Vu le budget, je me tourne en effet vers ce genre de lecteur (et parce que les fournisseurs auquel j'ai accès sont extrêmement limités également.)
Mais je note que cela peut être un problème et que je vais devoir être vigilant à ce propos.

Bonjour aurion64

Ca donne du piment à la chose :wink:

En fin d'après-midi ou demain, je fais l'essai de ton programme, mais avec un seul lecteur.

Je pratique pas mal l'IA (ChatGPT) qui, en général donne des programmes d'assez bonne qualité.

A+
Bonne après-midi
jpbbricole

Un grand merci à Tous.
Je sais que j'en demande beaucoup donc sachez que c'est fortement apprécié ( et promis des que le dispositif sera fini je vous ferai de belles photos)

dans le lien GitHub que j'ai donné il y a aussi des codes pour du multi-lecteur, ça pourra vous donner des idées.

sinon j'avais un code dans un coin, je ne me souviens plus si j'avais fini de tester et si ça fonctionnait.

C'est un code peu habituel qui permet de tracer en temps réel le dépôt et le retrait de carte sur différents lecteurs, ici j'avais un lecteur sous une carte représentant les continents.

J'ai pas le matos sous la main pour tester, mais si quelqu'un peut ou veut le faire....

// ---------------------------------------------------------------------------------------
// Classe pour créer une abstraction liée à chaque lecteur
// ---------------------------------------------------------------------------------------
#include <SPI.h>
#include <MFRC522.h>

class LecteurRFID {
  public:
    LecteurRFID(byte brocheSS, byte brocheReset, byte id, const char* nom)
      : lecteur(brocheSS, brocheReset), id(id), nom(nom), identifiantPresent(false),
        identifiantPresentPrec(false), identifiantDetecte(false), compteurErreurs(0), chrono(0) {
      carteCourante.size = 0;
      cartePrecedente.size = 0;
    }

    void begin() {
      lecteur.PCD_Init();
    }

    void tester() {
      byte tailleTampon = 2;
      byte tamponAtqa[tailleTampon];

      identifiantPresentPrec = identifiantPresent;
      compteurErreurs += 1;
      if (compteurErreurs > 2) identifiantDetecte = false;

      if (lecteur.PICC_RequestA(tamponAtqa, &tailleTampon) == lecteur.STATUS_OK) {
        if (!lecteur.PICC_ReadCardSerial()) return;
        compteurErreurs = 0;
        identifiantDetecte = true;
        carteCourante = lecteur.uid;
      }

      identifiantPresent = identifiantDetecte;

      if (identifiantPresent && !identifiantPresentPrec) {
        Serial.print("Lecteur "); Serial.print(id); Serial.print(" ("); Serial.print(nom); Serial.print(") : identifiant #");
        afficherUID(carteCourante); Serial.println(" détecté.");
        chrono = millis();
      }
      else if (!identifiantPresent && identifiantPresentPrec) {
        Serial.print("Lecteur "); Serial.print(id); Serial.print(" ("); Serial.print(nom); Serial.print(") : identifiant #");
        afficherUID(carteCourante); Serial.print(" retiré après "); Serial.print(millis() - chrono); Serial.println(" ms.");
      }

      if (identifiantPresent && identifiantPresentPrec &&
          ((cartePrecedente.size != carteCourante.size) ||
           (memcmp(cartePrecedente.uidByte, carteCourante.uidByte, carteCourante.size) != 0))) {
        Serial.print("Lecteur "); Serial.print(id); Serial.print(" ("); Serial.print(nom); Serial.print(") : identifiant ");
        afficherUID(cartePrecedente);
        Serial.print(" remplacé après "); Serial.print(millis() - chrono);
        Serial.println(" ms.");
        Serial.print("Nouvel identifiant "); afficherUID(carteCourante); Serial.println(" détecté.");
        chrono = millis();
      }

      // Mise à jour de la carte précédente à la fin
      cartePrecedente = carteCourante;
    }

  private:
    MFRC522 lecteur;
    MFRC522::Uid carteCourante;
    MFRC522::Uid cartePrecedente;
    byte id;
    const char* nom;

    bool identifiantPresent;
    bool identifiantPresentPrec;
    bool identifiantDetecte;
    int compteurErreurs;
    unsigned long chrono;

    void afficherUID(MFRC522::Uid& carte) {
      for (byte i = 0; i < carte.size; i++) {
        if (carte.uidByte[i] < 0x10) Serial.write('0');
        Serial.print(carte.uidByte[i], HEX);
      }
    }
};

// ---------------------------------------------------------------------------------------

const byte brocheReset = 9; // partagée par tous les lecteurs

LecteurRFID lecteurs[] = {
  {2, brocheReset, 0, "Afrique"},   // broche SS = 2
  {3, brocheReset, 1, "Europe"},    // broche SS = 3
  {4, brocheReset, 2, "Asie"},      // broche SS = 4
  {5, brocheReset, 3, "Amérique"},  // broche SS = 5
  {6, brocheReset, 4, "Océanie"}    // broche SS = 6
};

const byte nbLecteurs = sizeof lecteurs / sizeof * lecteurs;

void setup() {
  Serial.begin(115200);
  while (!Serial) yield();
  SPI.begin();
  for (auto& lecteur : lecteurs) lecteur.begin();
}

void loop() {
  for (auto& lecteur : lecteurs) lecteur.tester();
}

Bonjour aurion64

J'ai testé ce programme, mais avec un seul lecteur, il est parfaitement opérationnel :slightly_smiling_face:

A+
Cordialement
jpbbricole

Si vous avez toujours le montage sous la main, même avec un seul lecteur - je suis preneur d’un test sur le code que j’ai posté qui doit dire quand on pose une carte mais aussi quand on l’enlève. Il suffit de modifier le tableau des lecteurs pour ne conserver qu’une seule entrée avec la bonne broche SS.

Merci

(Si ça ne fonctionne pas j’enlèverai le code car pas la peine de polluer le forum avec des bugs)

Bonsoir J-M-L

Ca fonctionne impeccable!

Lecteur 0 (Afrique) : identifiant #076CDAEE détecté.
Lecteur 0 (Afrique) : identifiant #076CDAEE retiré après 1352 ms.
Lecteur 0 (Afrique) : identifiant #076CDAEE détecté.
Lecteur 0 (Afrique) : identifiant #076CDAEE retiré après 3899 ms.
Lecteur 0 (Afrique) : identifiant #076CDAEE détecté.
Lecteur 0 (Afrique) : identifiant #076CDAEE retiré après 6330 ms.

Une toute belle soirée à vous!
jpbbricole

1 Like

Merci pour le test.

On trouve souvent des codes qui font une itération pour voir la présence d’une carte mais celui ci vous dira aussi si la carte s’en va.

Merci à Tous pour votre aide.
On est toujours en attente pour la commande de matériel mais j'espère pouvoir faire les tests rapidement.

Pour info, à titre de curiosité et comme j'avais un petit moment, je viens de faire un test avec trois lecteurs et des fils un peu longs

➜ ça ne fonctionne pas de manière satisfaisante. J'ai eu un, puis deux modules qui fonctionnent avec le code ci dessus modifié pour 3 lecteurs mais jamais les 3 et pas forcément le premier et second sur le bus, des fois c'était le premier et le dernier.

(les 3 lecteurs fonctionnent séparément)

je pense qu'il faudra soigner sérieusement le câblage et avoir un peu de chances sur les modules comme dit au post #5...

Bonne nouvelle, je viens d'avoir le matériel.
Demain, je tenterai de faire le montage afin de pouvoir le valider avec vous.
Un grand merci à tous de m'aider dans cette aventure et on croise les doigts.

Apres quelques petites déconvenues je pense avoir fini le montage provisoire. Je suis désolé si ce n'est pas très propre, c'est mon premier circuit un peu ambitieux et j'admets faire avec les moyens du bord pour le matériel.
Pour l'instant je souhaiterai avoir une validation avec pour être sur que je ne vais pas faire griller la moitié du circuit lorsque je vais le brancher avec l'ordinateur.
Pour les infos voici ce que j'ai.
manuel de l'écran. ( il semble etre en 5V ) https://joy-it.net/files/files/Produkte/RB-TFT1.8/RB-TFT1.8_Manual_2023-01-06.pdf

les photos du montage, j'en rajouterai si besoin.
Il manque la source d'alimentation






de l'arduino ( et un bouton on/off sur celle ci).
Ce qui m'ennui c'est que si l'écran doit etre sur du 5 volt et les lecteur sur du 3V, ca me demande 2 source d'alim différentes non?


Plus image suplémentaire de l'écran.

Difficile de suivre un plat de spaghetti sur les photos

Prenez un bout de papier une règle et un crayon et dessinez le circuit - ce sera plus parlant !

Pas du tout, il est en 3.3V et en plus ils disent que les entrées/sorties ne sont pas tolérantes 5V et qu'il faut utiliser des circuits d'adaptation pour passer les lignes de données de 5V à 3V.

  1. USAGE WITH ARDUINO
    The screen has a logic level of 3.3 V, which means that a voltage converter
    is required for the use with the Arduino. Using it without a voltage converter can cause damage to the TFT.

et à la page suivante dans le tableau on voit clairement que l'écran est alimenté à partir de la sortie 3.3V de l'Arduino.


Et c'est une chance, il vaudrait mieux ne pas mettre sous tension dans ces conditions.