10 Juin 2016

Arduino leçon 27 : RFID

RFID signifie Identification par Radio-Fréquence. On trouve aussi le sigle NFC (Near Field Communication) = communication à proximité.
pas FB

Le principe

Le badge ou la carte n'ont pas de source d'énergie (ni pile ni batterie) mais savent interpréter un message du module et utiliser l'énergie reçue de l'émetteur pour lui répondre. Le module émetteur décide alors s'il accepte de faire ce qui lui est demandé ou s'il refuse. Exemples : votre carte d'abonnement au bus, votre forfait ski, les portiques des grands magasins...

Le matériel

Le module actif

Le module RC522 que nous utilisons communique avec Arduino par une liaison SPI.

module RC522

Il reconnaît les différents badges, qu'ils soient en forme de cartes ou de porte-clés.

les modules passifs

Ces cartes ou ces badges ont une mémoire divisée en segments.
Le premier segment contient une série de numéros unique qu'on peut lire mais pas modifier. C'est son identifiant.
Les autres peuvent contenir des données modifiables.

cartes RFID badges RFID

Ces composants sont d'un usage général. Ils ne sont pas destinés au départ à Arduino.
Pour les utiliser, nous devons installer une bibliothèque.

Le montage

RFID et MEGA

Le premier programme


            /* RFID_et_Mega_2560.ino
           
            * Lit un badge RFID avec le lecteur RC522 connecté en SPI
            * Schéma des pins sur Arduino :
            * Relai ou diode verte : 47
            * alarme ou led rouge : 48
            * RST: Pin 49
            * MISO: Pin 50
            * MOSI: Pin 51
            * SCK: Pin 52
            * SS ou SDA: Pin 53
            * acquit : 42
            * adaptation par Michel Colmard d'un programme de electroschematics.com
            */
           
            #include <SPI.h>
            #include <RFID.h>
           
            #define SS_PIN 53
            #define RST_PIN 49
           
            RFID rfid(SS_PIN,RST_PIN);
           
            int startAlarm = false;
            int resetAlarm = 42;
            int relay = 47;
            int alarm = 48;
            int serNum[5];
            int x;
            bool access = false;
           
            int cards[][5] = {
                        { 0, 0, 0, 0, 0 },
                        { 0, 0, 0, 0, 0 },
                        { 0, 0, 0, 0, 0 },
                        { 0, 0, 0, 0, 0 },
                        { 0, 0, 0, 0, 0 },
            };
           
            char personne[][20] = // 1er parametre = nb de pers autorisees
                                               // second = longueur maximale du nom
                       {"Alain", "Bernard", "Chantal", "Denis", "Eric", "Félix", "Gisèle", "Hervé", "Irène"};
            char lenom[20];
           
            void setup(){
                    Serial.begin(9600);
                    SPI.begin();
                    rfid.init();
                    pinMode(resetAlarm, INPUT);
                    pinMode(relay, OUTPUT);
                    pinMode(alarm, OUTPUT);
                    digitalWrite(relay, LOW);
                    attachInterrupt(0, reset_alarm, LOW);
            }
           
            void loop(){
                    if(rfid.isCard()){
                            Serial.println (" ");
                            Serial.println ("Le badge ");
                            if(rfid.readCardSerial()){
                                    Serial.print(rfid.serNum[0]);
                                    Serial.print(" ");
                                    Serial.print(rfid.serNum[1]);
                                    Serial.print(" ");
                                    Serial.print(rfid.serNum[2]);
                                    Serial.print(" ");
                                    Serial.print(rfid.serNum[3]);
                                    Serial.print(" ");
                                    Serial.print(rfid.serNum[4]);
                                    Serial.println(" est present.");
           
                                    for( x = 0; x < sizeof(cards); x++){
                                            for(int i = 0; i < sizeof(rfid.serNum); i++ ){
                                                    if(rfid.serNum[i] != cards[x][i]) {
                                                            access = false;
                                                            break;
                                                    } else {
                                                            access = true;
                                                    }
                                            }
                                            if(access) break;
                                   }
                            }
           
                            if(access){
                                    Serial.print("Bienvenue " );
                                    Serial.print(personne[x]);
                                    Serial.println(".");
                                    startAlarm = false;
                                    digitalWrite(alarm, LOW);
                                    digitalWrite(relay, HIGH);
                            } else {
                                    Serial.println("Fous le camp, ducon !");
                                    startAlarm = true;
                                    digitalWrite(alarm, HIGH);
                                    digitalWrite(relay, LOW);
                            }
                            delay(2000);
                    }
                    rfid.halt();
            }
           
            void reset_alarm()                 // fonction d'interruption
            {
                    startAlarm = false;
            }

On n'utilise pas l'interruption, mais on la laisse pour ne pas avoir de conflit avec la bibliothèque.
On pourrait s'en servir pour "acquitter" l'alarme.

mode d'emploi

Lancez le programme, ouvrez le moniteur série, et approchez un badge du module (ou plusieurs successivement).
Un message de refus apparaît et contient l'identificateur ( 5 nombres ). Notez les sur un papier.
Modifiez ce programme en entrant ces ID à la place de zéros dans le tableau.
Recompilez.
Maintenant, vos badges doivent être acceptés.

Second programme

Le premier programme utilise le moniteur série et ne fonctionne qu'en liaison avec le PC.
Pour rendre le montage mobile, on remplace le moniteur série par un afficheur à cristaux liquides (ou on l'ajoute simplement).
Je vous laisse faire seuls.

troisème programme

montage

On ajoute au montage précédent des leds avec des résistances et éventuellement un buzzer.
Rouge en 48, verte en 47, bleue en 42, buzzer en 43.

programme

Parmi les badges connus, le premier sert à valider/invalider le buzzer.
On allume la led verte quand on accepte l'entrée, la rouge quand on refuse.
Au bout de 3 secondes, on éteint la led rouge ou verte et le buzzer et on allume la bleue.
Au bout de 30 secondes, on remplace le message de l'afficheur par "Presentez votre badge" (sans accent à cause des limitations d'Arduino).


            /* RFID_Mega_et_LCD.ino
           
            * Lit un badge RFID avec le lecteur RC522 connecté en SPI
            * Schéma des pins sur Arduino :
            * Relai ou diode verte : 47
            * alarme ou led rouge : 48
            * RST: Pin 49
            * MISO: Pin 50
            * MOSI: Pin 51
            * SCK: Pin 52
            * SS ou SDA: Pin 53
            * led bleue : 42
            * buzzezr : 43
            * adaptation par Michel Colmard d'un programme de electroschematics.com
            */
           
            #include <SPI.h>
            #include <RFID.h>
            #include <LiquidCrystal.h>
           
            #define SS_PIN 53
            #define RST_PIN 49
           
            int bleue = 42;
            int alarm = 43;
            int relay = 47;
            int alarm = 48;
            int serNum[5];
            int x;
            bool access = false;
            boolean buzzer = false;
            boolean efface = false;
            long heureReprise = 0 ;
            long heureEffacer = 0 ;
           
            int cards[][5] = {
                        { 0, 0, 0, 0, 0 },
                        { 0, 0, 0, 0, 0 },
                        { 0, 0, 0, 0, 0 },
                        { 0, 0, 0, 0, 0 },
                        { 0, 0, 0, 0, 0 },
            };
           
            char personne[][12] = // 1er parametre = nb de pers autorisees
                                               // second = longueur maximale du nom
                       {"Alain", "Bernard", "Chantal", "Denis", "Eric", "Félix", "Gisèle", "Hervé", "Irène"};
            char lenom[12];
            LiquidCrystal afficheur(8, 9, 4, 5, 6, 7);
            RFID rfid(SS_PIN,RST_PIN);

            void setup(){
                    Serial.begin(9600);
                    Serial.println("Bonjour");
                    SPI.begin();
                    afficheur.begin(16, 2);
                    rfid.init();
                    delay(10);
                    pinMode(relay, OUTPUT);
                    pinMode(alarm, OUTPUT);
                    digitalWrite(relay, LOW);
                    digitalWrite(rouge, LOW);
                    delay(100);
                    afficheur.print("Bonjour");
            }
           
            void loop(){
                    while ( millis() < heureReprise ) {
                    // on attend
                    }
                    digitalWrite(relay, LOW);
                    digitalWrite(rouge, LOW);
                    digitalWrite(alarm, LOW);
                    digitalWrite(bleue, HIGH);
                    if(rfid.isCard()){
                            efface = false;
                            access = false;
                            Serial.println("carte presente");
                            heureReprise = millis() + 3000 ;
                            heureEffacer = heureReprise + 30000 ;
                            if(rfid.readCardSerial()){
                                    afficheur.setCursor(0, 0);
                                    for( x = 0; x < sizeof(cards); x++){
                                            for(int i = 0; i < sizeof(rfid.serNum); i++ ){
                                                    if(rfid.serNum[i] != cards[x][i]) {
                                                            access = false;
                                                            break;
                                                    } else {
                                                            access = true;
                                                    }
                                            }
                                            if(access) break;
                                   }
                            }
                            afficheur.print(".");
                            afficheur.setCursor(0, 0);
                            if(access){
                                    afficheur.clear();
                                    afficheur.print("Bienvenue ");
                                    afficheur.print(personne[x]);
                                    afficheur.print(".");
                                    digitalWrite(bleue, LOW);
                                    digitalWrite(relay, HIGH);
                                    if (x==0 ) {
                                            buzzer = 1 - buzzer;
                                            afficheur.clear();
                                            if (buzzer)
                                                    afficheur.print ("buzzer actif");
                                            else
                                                    afficheur.print ("buzzer muet");
                                            Serial.print("buzzer vaut ");
                                            Serial.println(buzzer);
                                    }
                                   
                            } else {
                                    Serial.println("Fous le camp !");
                                    digitalWrite(bleue, LOW);
                                    digitalWrite(alarm, buzzer);
                                    digitalWrite(rouge, HIGH);
                            }
                            delay(2000);
                    }
           
            if ((millis() > heureEffacer ) && ( efface = false ) ) {
                    afficheur.clear();
                    afficheur.print("presentez votre");
                    afficheur.setCursor(0, 1);
                    afficheur.print("badge");
                    efface = true;
            }
    }

Voici le montage qui avait été présenté au 20ème anniversaire de l'AMT. A gauche, notre montage en cours, à droite un afficheur couleur fait défiler des images.

montage pour l'anniversaire



haut de la page
flèche gauche Page Précédente : détecteur à ultrasons           Page Suivante flèche droite

Valid XHTML 1.0 Transitional