Exercice avec des badges RFID en C/C++ avec Stm32duino

Description

La RFID est une technologie qui code des données numériques dans des étiquettes RFID (également appelé des TAGS RFID) et qui permet ensuite de lire ces données. Le tout se fait sans contact entre le transmetteur et l’émetteur. Ces badges sont constitués d’une puce électronique et d’une antenne qui lui permet de répondre à une certaine fréquence. Pour venir lire ces données ils faut donc avoir un lecteur à la même fréquence.

Le badge RFID est utilisé dans différents type d’applications telles que :

  • les objets comme avec des codes barres.
  • les passeports, carte de transport, carte de fidélité, badge d’appartement, carte bancaire et tout type de carte permettant d’identifier une personne.
  • gestion de l’inventaire.
  • contrôle de l’accès aux zones restreintes.
  • l’identification d’animaux dont le badge RFID est implanté sous la peau et permettant de retrouver des informations sur le propriétaire ou encore l’antécédent médical de l’animal.

Fun fact : les Amiibo de Nintendo sont en réalité de simples figurines et cartes utilisant la RFID.

De façon générale les badges RFID contiennent un identifiant censé être unique. Ces identifiants sont utilisés avec des bases de données pour retrouver les informations liées à un identifiant précis.

A travers cet exercice nous verrons comment retrouver l’identifiant contenu dans un badge. Enfin dans la partie pour aller plus loin, nous mettrons en place un mini-projet de simulation d’une porte sécurisée à l’aide d’un badge RFID.

Montage

Pour faire le montage nous utilisons un lecteur de badge RFID de référence RFID-RC522 et qui fonction à une fréquence de 13,56MHz. Ce lecteur dispose d’une portée de lecture d’environ 3cm et communique en protocole SPI.

On vient connecter le lecteur de badge en suivant ce schéma :

Schéma de montage lecteur RFID

La correspondance entre le lecteur de badge et la carte ST Nucleo est la suivante :

Lecteur RFID ST Nucleo
SDA D10
SCK D13
MOSI D11
MISO D12
GND GND
RST D9
3.3V 3.3V

Programme

Pour simplifier le code nous utilisons une bibliothèque externe. Pour récupérer cette bibliothèque veuillez suivre ce lien. Elle est contenue dans un fichier .zip qu’il faut dézipper et ensuite déplacer le dossier avec son contenu pour le mettre dans \Documents\Arduino\libraries. Le fichier du projet Arduino est quant à lui disponible en suivant ce lien.

Etape 1 : On importe les librairie dans notre code. On déclare aussi un objet monModuleRFID qui permettra d’utiliser la librairie RFID. Et enfin on déclare un tableau nommé UID pour stocker l’identifiant du badge.

#include <SPI.h>
#include <RFID.h>

//Création d'un objet monModuleRFID
RFID monModuleRFID(10,9);

//Tableau de stockage de l'UID
int UID[5];

Etape 2 : Dans cette étape, nous configurons la fonction setup. Pour cela nous venons initialiser la liaison série, la communication SPI ainsi que la librairie du module RFID.

void setup()
{
  //Initialisation des librairies
  Serial.begin(9600);
  SPI.begin();
  monModuleRFID.init();
}

Etape 3 : Cette étape est la fonction loop qui constitue le cœur du programme. Cette fonction va venir detecter la présence d’un badge, le lire, stocker son UID dans le tableau définit précédemment et afficher le tout dans le moniteur série.

void loop()
{
    //Si un badge est detecté
    if (monModuleRFID.isCard()) 
    {  
          //Si on lit un badge
          if (monModuleRFID.readCardSerial()) 
          {        
            Serial.print("UID lu : ");
            for(int i=0;i<=4;i++)
            {
              UID[i]=monModuleRFID.serNum[i];     //Stockage de l'UID
              Serial.print(UID[i],DEC);           //Affichage de l'UID
              if(i!=4)
                Serial.print(".");
            }
            Serial.println("");
          }          
          monModuleRFID.halt();
    }
    delay(500);    
}

Résultat

Il ne vous reste plus qu’à appuyer sur le bouton téléverser pour transférer le programme puis allez dans le menu Outils puis Moniteur Série pour observer le résultat !

Au premier abord rien n’apparait, c’est tout à fait normal ! En effet l’affichage ne s’éxécute que si l’on présente un badge sur le lecteur. Prenez donc un badge et approchez le du lecteur (suffisamment près pour qu’il soit lu). Vous devriez voir apparaitre ce genre de code :

Affichage des données de badge RFID

Vous n’avez pas de badge ? Pas de panique ! Prenez votre téléphone Android, activez le NFC dessus (Paramètre –> Connexions –> NFC) puis approchez le du lecteur.

Remarque 1 : Si vous utilisez votre téléphone il se peut que cela ne fonctionne pas pour la simple et bonne raison que certains téléphones ne proposent pas le NFC.

Remarque 2 : Si vous utilisez votre téléphone il se peut que certain d’entre vous remarquent que la valeur récupérée par le lecteur est différente à chaque fois que vous eloignez distinctement votre téléphone et que vous le remettez sur le lecteur. Il s’agit en réalité d’une sécurité mise en place par le téléphone et non d’un bug provenant du code.

Pour aller plus loin

Dans cette partie nous allons assembler plusieurs codes des parties précédentes afin de réaliser une porte sécurisée par un badge RFID. Pour cela nous allons donc utiliser :

  • un lecteur RFID pour récupérer l’information.
  • les 3 LED de la carte Nucleo pour faire un retour d’état à l’utilisateur.
  • un servo moteur permettant de faire pivoter la porte.

Voici l’idée de fonctionnement de ce mini projet :

  1. Dans un premier temps la LED bleu de la carte Nucleo s’allume indiquant à l’utilisateur que le système est prêt à enregistrer une carte. L’utilisateur vient donc prendre un badge RFID et le présente sur le lecteur de badge. L’enregistrement se termine quand la LED bleu s’éteint.
  2. Dans un second temps, si l’utilisateur présente la carte qu’il a enregistrée alors la LED verte s’allume et le système actionne le servo-moteur pour le faire pivoter à 90°. Au bout de 3 secondes le servo-moteur revient à sa position initiale et la LED verte s’éteint. Si l’utilisateur présente un badge non enregistré dans le système alors la LED rouge s’allume puis s’éteint au bout d’une seconde.
  3. L’idée est de voir comment se comporte le système et voir les informations qu’il traite. Par conséquent on vient afficher ces informations dans le moniteur série.

Montage :

On reprend le même montage que précédemment auquel nous venons ajouter en plus un servo-moteur. Nous réutilisons les LED de la carte Nucleo donc nous n’avons pas besoin de venir les cabler.

Schéma de montage lecteur RFID

La correspondance entre le servo-moteur et la carte ST Nucleo est la suivante :

Servo-moteur ST Nucleo
Signal D6
GND GND
3.3V 3.3V

Programme :

Pour simplifier le code nous (ré)utilisons la bibliothèque externe précédente et disponible via ce lien. Elle est contenue dans un fichier .zip qu’il faut dézipper et ensuite déplacer le dossier avec son contenu pour le mettre dans \Documents\Arduino\libraries. Le fichier du projet Arduino est quant à lui disponible en suivant ce lien.

Etape 1 : On importe les librairie dans notre code.

#include <SPI.h>
#include <RFID.h>
#include <Servo.h>

Etape 2 : On définit les ports utilisés par les LED. On en profite également pour initialiser les variables qui serviront à l’appel de nos librairies. Enfin on définit des variable globale qui viendront respectivement stocker les valeurs acquises (int UID[5]), stocker les valeurs du badge valide (int MASTERKEY[5]) et verifier si l’enregistrement est réalisé (int compteur).

//Ports utilisés
const char LED_BLEU = PB5;
const char LED_ROUGE = PB1;
const char LED_VERTE = PB0;

//Création des objets
RFID monModuleRFID(10,9);
Servo moteur;

//Variables globales
int UID[5]={};
int MASTERKEY[5]={};
int compteur = 0;

Etape 3 : Dans cette étape, nous configurons la fonction setup. Pour cela nous venons initialiser la liaison série, la communication SPI ainsi que la librairie du module RFID. Nous initialisons également les ports liés au moteur ainsi qu’aux LED.

void setup()
{
  //Initialisation des librairies
  Serial.begin(9600);
  SPI.begin();
  monModuleRFID.init();  

  //Initialisation des ports
  moteur.attach(6);
  pinMode(LED_BLEU, OUTPUT);
  pinMode(LED_ROUGE, OUTPUT);
  pinMode(LED_VERTE, OUTPUT);
  digitalWrite(LED_BLEU, HIGH);
  digitalWrite(LED_ROUGE, LOW);
  digitalWrite(LED_VERTE, LOW);
}

Etape 4 : Cette étape est la fonction loop qui constitue le cœur du programme avec les différentes actions citées précédemment. Afin de simplifier son explication on décompose le code.

void loop()
{
  //A la lecture d'un badge
  if (monModuleRFID.isCard()) 
  {  
    //Enregistrement de l'UID d'un badge 
    if (monModuleRFID.readCardSerial() && compteur == 0)
    {
      Serial.print("----------------------------------------\n| UID enregistré : ");
      for(int i=0;i<=4;i++)
      {
        MASTERKEY[i]=monModuleRFID.serNum[i];     //Recupere les 5 valeurs de l'UID
        Serial.print(MASTERKEY[i],DEC);
        if(i!=4)
          Serial.print(".");
      }
      Serial.println(" |\n----------------------------------------");
      compteur++;
      digitalWrite(LED_BLEU, LOW);
    }

Dans cette partie de code nous vérifions que le lecteur détecte un badge et que le compteur est à 0. Le compteur permet de vérifier si un badge a déjà été enregistré. Si c’est le cas alors cette valeur s’incrémente et il n’est alors plus possible de revenir dans cette boucle (à condition de ne pas faire appuyer sur le bouton reset de la carte Nucleo 😉). Dès que l’on entre dans cette boucle nous venons récupérer les valeurs une par une et on les stocke dans un tableau nommé MASTERKEY. On affiche le resultat dans le moniteur série et on éteint la LED.

    //Affichage de l'UID dans le moniteur série
    if (monModuleRFID.readCardSerial() && compteur != 0) 
    {        
      Serial.print("UID lu : ");
      for(int i=0;i<=4;i++)
      {
        UID[i]=monModuleRFID.serNum[i];
        Serial.print(UID[i],DEC);
        if(i!=4)
          Serial.print(".");
      }
      Serial.println("");

Cette partie de code est la même que celle que l’on a vue précédemment. Elle permet d’afficher dans le moniteur série l’UID du badge présenté sur le lecteur.

      //Vérification du badge et mise en marche du moteur
      if (UID[0] == MASTERKEY[0] && UID[1] == MASTERKEY[1] && UID[2] == MASTERKEY[2] && UID[3] == MASTERKEY[3] && UID[4] == MASTERKEY[4])
      {
        digitalWrite(LED_VERTE, HIGH);
        moteur.write(180);
        Serial.println("Porte ouverte");
        delay(3000);
        moteur.write(90);
        Serial.println("Porte fermée");
        digitalWrite(LED_VERTE, LOW);
      }
      else
      {
        digitalWrite(LED_ROUGE, HIGH);
        delay(1000);
        digitalWrite(LED_ROUGE, LOW);
      }          
      monModuleRFID.halt();
    }
  }   
}

Enfin cette dernière partie de code va comparer l’UID récupéré avec l’UID du badge enregistré. Si les deux UID sont les mêmes alors on allume la LED verte et on fait pivoter le moteur de 90°. On attend 3 secondes et revient à l’état initial. Un retour d’information dans le moniteur série est également fait. Sinon si les deux UID sont différents on allume la LED rouge pendant 1 seconde.

Résultat :

Il ne vous reste plus qu’à appuyer sur le bouton téléverser pour transférer le programme puis allez dans le menu Outils puis Moniteur Série pour observer le résultat !

Tout comme avant, au premier abord rien n’apparait, c’est tout à fait normal ! En effet l’affichage ne s’éxécute que si l’on présente un badge sur le lecteur. Prenez donc un badge et approchez le du lecteur (suffisamment près pour qu’il soit lu). Vous devriez voir apparaitre ce genre de code :

Affichage des données de badge RFID

Vous pouvez également regarder les 3 LED de la carte Nucleo. Elles devraient réagir en fonction du badge que vous présentez. Le servo-moteur devrait également réagir si vous lui présentez le bon badge.