Skyduino:~#
Articles
arduino, programmation, projet

[Arduino] Systéme d’ouverture de porte RFID (version série)

Bonjour tout le monde !

Il y a de cela quelques temps, j’avais fait un tutoriel de mise en application du lecteur RFID de parallax (la version bleu).

On m’avait demandé par mail comment faire une version qui utiliserai le port série hardware (+ usb) en lieu et place d’un écran lcd.
Du coup j’ai codé (vite fait) un programme qui a pour but d’actionner un gâche électrique suivant si le tag RFID présentait est enregistré en mémoire ou non.

Cette nouvelle version apporte deux « gros » changements, tout d’abord les ID RFID sont codé « en dur » dans le code. Il est aussi possible d’en avoir plusieurs actionnant la gâche.
En bonus, à chaque ID « valide » correspond un nom qui sera affiché sur le port série lors d’un passage du TAG.

Niveau hardware :
Tx du lecteur RFID sur D3,
Broche de controle de la gâche (LOW = porte fermé, HIGH = porte ouverte) sur D13.

Sans plus attendre voici le code, commenté comme d’habitude :

/*
 * Exemple d'utilisation du lecteur Rfid de parallax
 * Application: Systéme d'ouverture de porte avec gâche électrique
 */

/* Include pour le port série software */
#include <SoftwareSerial.h>

/* Définition des broches */
#define PIN_ENABLE 2
#define PIN_RX 3
#define PIN_TX 4 // Non utilisé
#define PIN_GACHE 13

/* Constantes Parallax RFID */
#define CODE_LEN 10      // Taille d'un ID rfid
#define START_BYTE 0x0A  // Byte de start
#define STOP_BYTE 0x0D   // Byte de stop

/* Définition des constantes d'usage */
#define UNLOCK_TIME 2 // en secondes
#define RETRY_DELAY 2 // en secondes

/* Macro de gestion hardware */
#define enableRfid() digitalWrite(PIN_ENABLE, LOW)
#define disableRfid() digitalWrite(PIN_ENABLE, HIGH)
#define flushRfid() while(rfid.available() > 0) rfid.read()

#define enableGache() digitalWrite(PIN_GACHE, HIGH)
#define disableGache() digitalWrite(PIN_GACHE, LOW)
#define unlock() enableGache(); delay(UNLOCK_TIME * 1000); disableGache()

/* Base de donnée des ID de tag valide */
char* tagId[] = {
  "0000C153EC", // tag 1
  "0000CAAAAA", // tag 2
  "0001111A1A", // tag 3
};

/* Base de donnée des nom de tag valide */
char* tagNom[] = {
  "Eleve 1",    // tag 1
  "Eleve 2",    // tag 2
  "Eleve 3",    // tag 3
};

/* Nombre de tag dans la bdd */
const byte nbTag = 3;

/* Buffer contenant le tag en cours de lecture */
char tag[CODE_LEN];

/* Déclaration d'une instance de SoftwareSerial pour communiquer avec le lecteur rfid */
SoftwareSerial rfid(PIN_RX, PIN_TX);

/* Fonction setup() */
void setup() {

  /* Initialisation du port série hardware */
  Serial.begin(9600);

  /* Initialisation du port série software */
  rfid.begin(2400);

  /* Mise en OUTPUT de la broche ENABLE du lecteur RFID */
  pinMode(PIN_ENABLE,OUTPUT);
  disableRfid();

  /* Mise en OUTPUT de la broche câblé sur la gachette électrique */
  pinMode(PIN_GACHE,OUTPUT);
  disableGache(); 
}

/* Fonction loop() */
void loop() { 

  /* Récupération d'un ID valide ou non (fonction bloquante) */
  getRfidTag();

  /* index: résultat de la fonction isCodeValid() */
  int index;

  /* Si le tag est présent dans la bdd */
  if((index = isCodeValid()) >= 0) {

    /* Affichage du msg d'accès, et du nom de la personne */
    Serial.println("Acces autorise");
    Serial.println(tagNom[index]);
    unlock();
  } 
  else {
    /* Sinon affichage  */
    Serial.println("Acces non autorise");

    /* Attente avant de pouvoir repasser une carte */
    delay(RETRY_DELAY * 1000);
  }
  
  /* Vide le buffer série du lecteur rfid (évite de lire des données parasites) */
  flushRfid();
} 

/*
 * Fonction lisant un ID rfid depuis le port série software, et ne rendant la main qu'une fois un code rfid correctement recu
 */
void getRfidTag() {
  /* Activation du lecteur RFID */
  enableRfid();

waitTag: /* Etiquette de rappel */

  do {
    /* Attente d'au moins un octet sur le port série */
    while(rfid.available() < 1);

    /* Attente du byte de start */
  } 
  while(rfid.read() != START_BYTE);

  /* i: variable d'itération */
  byte i;

  /* Lecture du tag */
  for(i = 0; i < CODE_LEN; i++) {

    /* Attente d'au moins un octet sur le port série */
    while(rfid.available() < 1);

    /* Si jamais une erreur de lecture ce produit, et que le lecteur rfid retourne STOP_BYTE */
    if((tag[i] = rfid.read()) == STOP_BYTE) 
      /* On quitte la boucle */
      break;
  }

  /* Si i est différent de CODE_LEN c'est qu'il y a eu une erreur de lecture */
  if(i != CODE_LEN)
    /* On reprend donc depuis le début */
    goto waitTag; 

  /* Attente d'au moins un octet sur le port série */
  while(rfid.available() < 1);

  /* Si l'octet suivant n'est pas le byte de stop c'est qu'il y a un probléme de syncro */
  if(rfid.read() != STOP_BYTE)
    /* On reprend donc depuis le début */
    goto waitTag;

  /* Désactivation du lecteur rfid */
  disableRfid();
}

/*
 * Retourne l'indice du tableau tagNom correspondant au tag rfid si celui ci est présent dans le tableau tagId, sinon -1
 */
int isCodeValid() {
  /* Passe en revu chaque tag en bdd */
  for(byte i = 0; i < nbTag; i++)
    /* Si un tag correspond */
    if(memcmp(tag, tagId[i], CODE_LEN) == 0)
      /* on retourne son indice */
      return i;

  /* Si aucun tag ne correspond, on retourne -1 */
  return -1;
}

Enjoy ! 😉

Advertisements

Discussion

20 réflexions sur “[Arduino] Systéme d’ouverture de porte RFID (version série)

  1. Salut salut, encore une fois c’est un super tuto que tu nous a fais là 😛

    Je voudrais juste savoir où tu as commande le lecteur car sur internet les frais de ports font peur ( Chine ou USA) …

    Merci bien 🙂

    Publié par Trigger | 4 août 2012, 16 h 01 min
  2. Bonjour,

    Je suis èleve de terminale SI et nous avons un projet a réaliser, et sur ce projet nous aimerions réaliser un rfid avec une carte arduino uno et une adafruit. Ce système nous permetterait de lire une carte enregistré, afin d’accepter le passage, et si la carte n’est pas enregistré, refusé ce passage.

    Mais nous n’avons pas réussi à adapter ce programme sur notre système.
    Le fait de posséder une carte adadruit peut être le problème ?
    Que nous conseillez vous ?

    Merci, bonne journée.

    Publié par emimo | 24 janvier 2013, 11 h 29 min
  3. Bonjour,

    Je suis élève en Tle STI2D et on a un projet à réaliser pour notre BAC: une chatière électronique. Je dois m’occuper de ce qui est réception et transmission de la RFID. Serait-ce possible d’avoir un exemple sur arduino ? Merci d’avance 🙂

    Publié par Arii | 13 janvier 2014, 22 h 34 min
  4. Je viens de tenter d’utiliser votre code dans un projet personnel mais je me heurte à une erreur avec la mention « isCodeValid() »
    Avez vous une solution ?

    Merci

    Publié par xavier26700 | 20 mars 2014, 12 h 32 min
  5. Voici les 2 erreurs :

    lire_carte_rfid_a_adapter:78: error: ‘getRfidTag’ was not declared in this scope
    lire_carte_rfid_a_adapter:84: error: ‘isCodeValid’ was not declared in this scope

    Merci pour votre aide.

    Publié par xavier26700 | 25 mars 2014, 17 h 00 min
  6. Je suis d’accord, il manque au moins 2 lignes mais avec mes connaissances je ne sais pas quoi rajouter pour faire reconnaitre ces 2 mentions.

    Publié par xavier26700 | 1 avril 2014, 13 h 13 min
  7. Comment faire pour affiché les donnée dans le moniteur série
    Quand je fait passer une carte RFID devant l’antenne il y a seulement a LED verte qui s’allume
    Merci d’avance

    Publié par Skander | 29 avril 2014, 14 h 02 min
  8. Bonjour SKYWODD,
    Je cherche à piloter un lecteur RFID grâce à un PIC24FJ64. J’ai la SDK fourni avec le lecteur seulement les sources de code donné pour le module NUR05WL2 API sur le lecteur est assez complexe. C’est à dire que j’ai une multitude de fonction prédéfini pour utiliser le lecteur mais je ne sais pas comment faire…

    Exemple concret où je ne vois pas comment dire au lecteur que je veux utiliser le port n°4 pour l’antenne:

    /*
    /*
    /** @fn int NurApiTuneAntenna(HANDLE hApi, int antenna, BOOL wideTune, BOOL bSaveResults, int *dBmResults)
    * Executes an antenna tune.
    *
    * @param hApi Handle to valid NurApi object instance
    * @param antenna Antenna to use. Value is 0…3.
    * @param wideTune If set to TRUE the tuning is done in wider range opposing to FALSE which ‘fast tune’
    * @param bSaveResults If set to TRUE then the tuning results will be stored into the module’s non-volatile memory.
    * @param dBmResults Pointer to 6 integer values. The reflected power will be stored into these values in format dBm * 1000.
    * This parameter may be NULL.
    *
    * @return Zero when succeeded, on error non-zero error code is returned.
    */
    */
    */
    NUR_API
    int NURAPICONV NurApiTuneAntenna(HANDLE hApi, int antenna, BOOL wideTune, BOOL bSaveResults, int *dBmResults);

    Publié par gadjo | 19 mai 2014, 17 h 11 min
  9. Votre programme n’utilise pas Tx vers le lecteur, pourquoi? cela signifierai que le lecteur n’a pas besoin d’être piloter et envoie en continue l’identifiant qu’il lit??
    Cordialement,

    Publié par gadjo | 19 mai 2014, 17 h 16 min
    • Mon module n’as pas d’entrée série, c’est de la lecture module->arduino uniquement.
      Dés qu’un tag est lisible il renvoi l’ID du tag est attend un nouveau tag.
      Il ne répète pas le même tag en boucle, sauf si on l’éloigne le tag et qu’on attend avant de le remettre sur le lecteur.

      Publié par Skywodd | 26 mai 2014, 20 h 49 min
  10. Salut, j’aimerai adapter ton programme pour qu’il rende la main avant d’avoir détecté un Tag.
    En clair qu’il fasse tourner void loop() sans rester bloquer dans void getRfidTag() .
    Penses tu qu’avec ta méthode c’est réalisable ?

    Publié par Ghr | 26 mars 2015, 17 h 05 min
  11. salut j’aime vraiment ce que vous faite

    Publié par djeuck | 13 juillet 2016, 1 h 39 min

Rétroliens/Pings

  1. Pingback: TPE Domotique | Pearltrees - 5 janvier 2017

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s

Skyduino devient Carnet du Maker

Le site Carnet du Maker remplace désormais le blog Skyduino pour tout ce qui touche à l'Arduino, l'informatique et au DIY.