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 ! 😉
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 minJe commande tout mes composants chez ces différents revendeurs :
Pour ce qui est matos arduino : http://www.watterott.com/index.php?page=index
Pour les plateformes de dév et autre modules spéciaux : http://www.lextronic.fr/
Pour mes composants low-cost : http://dx.com/new-arrivals?cate=499
Pour mes composants « de qualité » : http://fr.farnell.com/
Pour le lecteur RFID je l’ai eu par l’intermédiaire d’un amis, je crois qu’il est en vente sur le site de parallax.
Sinon chez watterott tu en as un pas trop chère (10€ mais +fdp de 10€ vers la france) :
http://www.watterott.com/en/125Khz-RFID-module-UART
Perso je fait une liste de matos à commander et quand elle est suffisamment grosse pour couvrir les fdp je passe commande.
Publié par skywodd | 4 août 2012, 20 h 00 minbonjour je viens de découvrir arduino
je viens de découvrir ta programmation pour lecteur rfid
et c’est exactement ce que j’ai besoin
mais je ne connais rien dans la programmation
j’aimerai savoir si je peux copier collée ton code ?
c’est acceptable ou pas ?
si oui comment je fait ? je copie a partir de la premieres ligne ?
merci pour ton aide
Publié par bodrail | 2 mars 2019, 14 h 19 minBonjour,
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 minSyntax error at line 3 : et sur sur projet nous aimerions réaliser un rfid avec une carte arduino uno et une adafruit.
Fatal exception : You wrote bullshit.
Publié par Jean THOMAS (@TiBounise) | 24 janvier 2013, 15 h 21 minBonjour,
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 minLe principe d’un projet de BAC s’est de montrer TES compétences donc tu te doutes de ma réponse : non.
Publié par skywodd | 19 janvier 2014, 16 h 02 minJe 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… pour donner une solution il faudrait que je sache quel est le problème …
Avec le texte de l’erreur par exemple se serait plus pratique.
Publié par skywodd | 24 mars 2014, 14 h 19 minVoici 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Ça sent le copié collé foireux …
Publié par skywodd | 29 mars 2014, 18 h 25 minJe 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… Si tu copies uniquement setup() et loop() ça ne risque pas de marcher.
Regarde à partir de la ligne 103, les deux fonctions à copier sont là.
Publié par skywodd | 9 avril 2014, 11 h 26 minComment 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 minBonjour 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 minVotre 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 minMon 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 minSalut, 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 minLe code est conçu pour être bloquant, le rendre non bloquant c’est revoir tout le code.
Le plus simple serait de reprendre l’idée et de refaire un code de zéro en non bloquant.
Publié par Skywodd | 27 mars 2015, 10 h 35 minsalut j’aime vraiment ce que vous faite
Publié par djeuck | 13 juillet 2016, 1 h 39 min