Das vierzehnte Türchen

Aujourd'hui, nous parlons de RFID, ou identification par radiofréquence. Cela permet d'identifier les transpondeurs correspondants, ou tags, sans contact. Le transpondeur est doté d'une micropuce, mais n'a pas d'alimentation électrique propre. Il est conçu comme une carte ou un porte-clés. Le lecteur accumule un champ électromagnétique à haute fréquence. Lorsqu'un transpondeur entre dans ce champ, il en tire de l'énergie pour sa propre alimentation. Une fois que la puce a suffisamment de tension, elle lance un programme et transmet son numéro d'identification codé en dur.  Pour la transmission de données, le transpondeur ne crée pas son propre champ électromagnétique, mais influence le champ du lecteur. Le lecteur reconnaît cette influence et peut recevoir les données.

Le système proposé aujourd'hui fonctionne à 13,56 MHz. La micropuce des cartes et des porte-clés ne peut pas seulement envoyer son numéro d'identification sur 4 byte. Il dispose également d'une mémoire pouvant stocker 1024 bytes. Ces données peuvent être envoyées du lecteur à la carte et lues à partir de là. Le contrôle du lecteur utilise le bus SPI (Serial Peripheral Interface) pour communiquer avec le microcontrôleur.

À la base de ce projet, nous voulons réaliser un système d'accès simple. En plus du lecteur RFID de l'offre actuelle, nous avons besoin d'un microcontrôleur pour le contrôle. Nous utilisons le Nano V3. De plus, nous avons besoin d'une LED RGB ou de trois LED avec une résistance en série pour l'affichage, d'un relais pour actionner un ouvre-porte par exemple et d'un bouton pour effacer complètement les données stockées si nécessaire.

Le câblage de ce projet est un peu plus étendu, puisque quatre lignes sont nécessaires pour le seul bus SPI.

 


Les connecteurs SPI sur le NANO sont D12 pour MOSI (Master Out, Slave In), D11 pour MISO (Master In, Slave Out), D10 pour ChipSelect SDA (Select Data Access) et D13 pour l'horloge SCK (Serial Clock). Le connecteur D9 est connecté au RST (Reset) pour réinitialiser le lecteur. Le GND et le 3.3V sont toujours manquants. Le lecteur ne peut être utilisé qu'avec 3.3V !

Le module LED-RGB dispose d'une LED RGB avec des résistances en série, de sorte que les anodes peuvent être connectées directement aux sorties du NANO. Le LED RGB a une cathode commune qui est connectée au GND. Comme le LED verte, en particulier, est beaucoup plus lumineux que l'autre, les LED doivent être contrôlées par PWM (Pulse Width Modulation).  Toutes les connexions du NANO ne sont pas compatibles avec le PWM. Nous connectons le LED rouge à D3, leLED vert à D5 et le LED bleu à D6. Le D4 n'est pas utilisable pour le PWM.

Le relais a besoin d'une tension d'alimentation de 5V. Nous connectons GND avec GND et Vcc avec 5V à la carte NANO. Pour contrôler le relais, nous utilisons le D7 sur le NANO et avec le bouton poussoir, nous connectons le D8 au GND. Le programme est conçu de telle manière que si le D8 est connecté au GND au démarrage, l'EEPROM interne du NANO sera effacée. Cette procédure doit être effectuée une seule fois, au premier démarrage, pour obtenir des conditions claires.

Pour le programme, nous avons besoin de la bibliothèque pour le lecteur MFRC522. Nous pouvons l'installer via la gestion de la bibliothèque. Nous tapons MRFC522 comme terme de recherche.

 


Les autres bibliothèques pour le bus SPI (SPI.h) et pour le contrôle de l'EEPROM (EEPROM.h) sont déjà installées dans l'IDE Arduino. Nous pouvons donc entrer le plan et le compiler.

Croquis:

#include // bibliothèque pour le bus SPI
#include // Bibliothèque pour puce RFID MFRC522
#include // Bibliothèque pour l'EEPROM interne

#define SS_PIN 10 // Broche Chipselect
#define RST_PIN 9 // Réinitialiser la broche

#define LED_RED 3 // LED rouge anode
#define LED_GREEN 5 // LED verte anode
#define LED_BLUE 6 // LED bleue anode

#define RELAIS 7 // Relais de contrôle

#define ERASE 8 // bouton pour supprimer

// États d'état
#define ST_WAIT 0 // Etat d'attente toutes les LED éteintes
#define ST_MASTER 1 // Attendre la nouvelle LED principale bleue
#define ST_ADD 2 // Ajout d'un voyant de carte inconnu jaune
#define ST_DEL 3 // supprimer la LED de la carte connue cyan
#define ST_ALLOW 4 // accès autorisé LED verte
#define ST_DENY 5 // Accès refusé LED rouge
#define ST_MASTERDEL 6 // supprimer la LED principale rose

// Instance pour l'interface du lecteur
MFRC522 rfid (SS_PIN, RST_PIN); // Instance de la classe

uint32_t cardId; // ID de la dernière carte lu
int16_t cardIndex; // index de la carte en mémoire
uint32_t masterId; // ID de la master card
uint32_t lastAction; // Horodatage de la dernière action
état uint8_t; //statut actuel

// Afficher les détails du lecteur RFID pour information
void ShowReaderDetails () {
// Obtenir la version du logiciel MFRC522
octet v = rfid.PCD_ReadRegister (rfid.VersionReg);
Serial.print (F ("MFRC522 Software Version: 0x"));
Serial.print (v, HEX);
si (v == 0x91)
Serial.print (F ("= v1.0"));
sinon si (v == 0x92)
Serial.print (F ("= v2.0"));
autre
Serial.print (F ("(inconnu), probablement un clone chinois?"));
Serial.println ("");
// Lorsque 0x00 ou 0xFF est renvoyé, la communication a probablement échoué
si ((v == 0x00) || (v == 0xFF)) {
Serial.println (F ("AVERTISSEMENT: échec de communication, le MFRC522 est-il correctement connecté?"));
Serial.println (F ("SYSTEM HALTED: Check connections."));
while (vrai); // n'allez pas plus loin
  }
}

// la fonction lit les quatre octets d'un ID de carte et retourne
// les renvoie sous forme d'entiers 32 bits
uint32_t getId () {
uint32_t res = 0;
uint8_t tmp [4];
// Une nouvelle carte a-t-elle été lue?
if (! rfid.PICC_IsNewCardPresent ()) {
return 0; // pas de retour 0
  }
// lire l'identifiant de la carte
if (! rfid.PICC_ReadCardSerial ()) {
return 0; // non réussi retour 0
  }
Serial.println (F ("UID du PICC scanné:"));
pour (uint8_t i = 0; i <4; i ++) {//
// ordre d'octet inversé pour un entier 32 bits
tmp [3-i] = rfid.uid.uidByte [i];
  }
rfid.PICC_HaltA (); // arrêter la lecture
res = * ((unsigned long *) tmp);
Serial.print ("Résultat:");
Serial.println (res);
return res;
}

// Faire clignoter une certaine LED
// led = numéro de broche, cnt = à quelle fréquence, val = luminosité
void blinkLED (uint8_t led, uint8_t cnt, uint8_t val) {
pour (uint8_t i = 0; i <cnt; i ++) {
analogWrite (led, val);
retard (200);
digitalWrite (led, 0);
retard (200);
  }
}

// Éteint toutes les LED
void allOff () {
analogWrite (LED_RED, 0);
analogWrite (LED_GREEN, 0);
analogWrite (LED_BLUE, 0);
}

// Recherche un ID spécifique dans l'EEPROM et retourne l'index
// retour ou -1 si l'ID n'a pas été trouvé
int16_t findId (id uint32_t) {
uint16_t max = (EEPROM.length () - 6) / 4;
uint16_t i = 0;
booléen trouvé = faux;
données uint32_t;
while ((i <max) &&! trouvé) {
EEPROM.get (i * 4 + 6, données);
trouvé = (données == id);
if (! trouvé) i ++;
  }
Serial.println (trouvé);
if (trouvé) retourne i * 4 + 6; else return -1;
}

// Recherche l'espace libre suivant dans l'EEPROM et retourne l'index
// retour ou -1 s'il n'y a plus d'espace
int16_t findEmpty () {
uint16_t max = (EEPROM.length () - 6) / 4;
uint16_t i = 0;
booléen trouvé = faux;
données uint32_t;
while ((i <max) &&! trouvé) {
EEPROM.get (i * 4 + 6, données);
trouvé = (données == 0);
if (! trouvé) i ++;
  }
if (trouvé) retourne i * 4 + 6; else return -1;
}

// Active ou désactive le relais
relais void (booléen activé) {
digitalWrite (RELAIS,! activé); // un autre relais est utilisé,
// le NOT (!) peut devoir être omis
}

// Affiche les couleurs de l'état actuel sur les LED
void statusColorOn () {
Serial.print ("Statut");
Serial.println (état);
allOff ();
commutateur (état) {
// seulement bleu
case ST_MASTER: analogWrite (LED_BLUE, 255); Pause;
// vert et rouge = jaune
case ST_ADD: analogWrite (LED_GREEN, 30); analogWrite (LED_RED, 255); Pause;
// bleu et vert = cyan
case ST_DEL: analogWrite (LED_BLUE, 255); analogWrite (LED_GREEN, 70); Pause;
// seulement vert
case ST_ALLOW: analogWrite (LED_GREEN, 50); Pause;
// seulement rouge
case ST_DENY: analogWrite (LED_RED, 255); Pause;
// bleu et rouge = magenta
case ST_MASTERDEL: analogWrite (LED_BLUE, 255); analogWrite (LED_RED, 255); Pause;
  }
}

// Une carte a été lue et doit être évaluée
void gotCard (uint32_t id) {
commutateur (état) {
// La carte maîtresse d'état d'attente ouvre la porte immédiatement
// Si une autre carte a été trouvée dans la mémoire, elle peut être supprimée avec la carte maîtresse
// Si une autre carte n'a pas été trouvée dans la mémoire, elle peut être ajoutée avec la carte maîtresse
case ST_WAIT: if (id == masterId) {
état = ST_ALLOW;
relais (vrai);
} autre {
cardIndex = findId (id);
cardId = id;
if (cardIndex> = 0) {
Serial.print ("ID trouvé = index");
Serial.println (cardIndex);
état = ST_DEL;
} autre {
Serial.println ("ID non trouvé");
état = ST_ADD;
                    }
                  }
Pause;
// L'état attend une nouvelle carte maîtresse. lire ID = MasterID
case ST_MASTER: masterId = id;
EEPROM.write (1,197);
EEPROM.put (2, masterId);
Serial.print ("ID maître =");
Serial.println (masterId);
état = ST_WAIT;
Pause;
// Si le MasterId a été lu, une carte qui n'était pas en mémoire est sauvegardée
// puis la porte est ouverte
case ST_ADD: if (id == masterId) {
int16_t ix = findEmpty ();
si (ix> = 0) {
Serial.print ("Ajouter un ID");
Serial.print (cardId);
Serial.print ("Index =");
Serial.println (ix);
EEPROM.put (ix, cardId);
état = ST_ALLOW;
relais (vrai);
                   }
} autre {
état = ST_DENY;
relais (faux);
                 }
Pause;
// Si le MasterId a été lu, une carte qui était en mémoire est supprimée
// alors l'accès sera refusé
case ST_DEL: if ((id == masterId) && (cardIndex> = 0)) {
Serial.print ("Delete ID");
Serial.println (cardIndex);
EEPROM.put (cardIndex, long (0));
état = ST_DENY;
relais (faux);
} autre {
état = ST_ALLOW;
relais (vrai);
                 }
Pause;
// si le MaterID a été lu, le MasterID est supprimé
// une autre carte peut être enregistrée comme maître
case ST_MASTERDEL: si (id == masterId) {
EEPROM.put (2, long (0));
EEPROM.write (1.0);
Serial.println ("Supprimer le maître");
état = ST_MASTER;
relais (faux);
                 }
Pause;
    }
statusColorOn ();
lastAction = millis ();
}

// 3 secondes se sont écoulées depuis la dernière action
void handleTimeout () {
commutateur (état) {
// carte invalide, refuser l'accès
case ST_ADD: état = ST_DENY;
relais (faux);
Pause;
// carte valide, autoriser l'accès
case ST_DEL: état = ST_ALLOW;
relais (vrai);
Pause;
// sinon toujours refuser l'entrée
par défaut: status = ST_WAIT;
relais (faux);
  }
statusColorOn ();
lastAction = millis ();
}

//Installer
void setup () {
Serial.begin (9600);
// Définit les broches comme sortie ou entrée
pinMode (LED_RED, OUTPUT);
pinMode (LED_GREEN, OUTPUT);
pinMode (LED_BLUE, OUTPUT);
pinMode (RELAIS, SORTIE);
pinMode (ERASE, INPUT_PULLUP);
// désactiver le relais
relais (faux);
// Laisser les LED clignoter en séquence pour le test
blinkLED (LED_RED, 3.255);
clignotant (LED_GREEN, 3,50);
blinkLED (LED_BLUE, 3.255);
// Démarre le lecteur SPI et RFID
SPI.begin ();
rfid.PCD_Init ();
// Sortie du message de démarrage et des informations sur le lecteur
Serial.println ("Adventblog 13.12.2020");
ShowReaderDetails ();
// Si le bouton a été enfoncé, effacez l'EEPROM
if (digitalRead (ERASE) == 0) {
Serial.print ("Effacer l'EEPROM");
Serial.print (EEPROM.length ());
Serial.println ("Octets");
pour (int i = 0; i EEPROM.write (i, 0);
    }
  }
// affiche les 16 premières cartes enregistrées
pour (uint16_t i = 0; i <16; i ++) {
EEPROM.get (i * 4 + 6, cardId);
Serial.print (i * 4 + 6);
Serial.print ("=");
Serial.println (cardId);
  }

// avons-nous une carte maîtresse?
si (EEPROM.read (1) == 197) {
Serial.println ("Nous avons un identifiant maître");
EEPROM.get (2, masterId);
état = ST_MASTERDEL; // activer la suppression de la carte maîtresse
statusColorOn ();
} autre {
Serial.println ("Nous n'avons pas d'identifiant maître");
masterId = 0;
état = ST_MASTER; // attend l'ID d'une carte et
// enregistre ceci en tant que master
statusColorOn ();
  }
// réinitialiser l'horodatage
lastAction = millis ();
}

boucle void () {
uint32_t tmpId;
tmpId = getId (); // ID de la carte de requête
// Si une carte a été lue, le nombre est évalué
if (tmpId> 0) gotCard (tmpId);
// Si 3 secondes se sont écoulées, votre timeout sera traité
// Sauf pour l'état d'attente et en attente d'une carte maîtresse
// Il n'y a pas de timeout pour ces états
if ((status! = ST_WAIT) && (status! = ST_MASTER) && ((millis () - lastAction)> 3000)) handleTimeout ();
}

Télécharger le croquis

Fonctionnalité:

Au premier démarrage, il faut appuyer sur la touche de suppression pour effacer l'EEPROM. Lors du démarrage, les trois LED clignotent trois fois chacune pour vérifier. Si aucune carte maîtresse n'a encore été stockée, le LED est bleue. Une carte maîtresse peut maintenant être établie en tenant cette carte devant le lecteur. Si la carte a été lue, la LED passe au vert et le relais se met en marche. L'ID lu est stocké en tant que maître. Au bout de trois secondes, le LED s'éteint et le relais s'arrête.

Si une carte maîtresse était déjà stockée au démarrage, elle sera utilisée. Le LED indique le magenta. Dans cet état, la carte maîtresse peut être effacée en la tenant devant le lecteur. Si la suppression a réussi, le LED passe au bleu et une nouvelle carte maîtresse peut être lue.

En état d'attente, le LED est éteinte. Si une carte qui n'a pas encore été enregistrée est lue, le LED devient jaune. Vous avez maintenant trois secondes pour valider la carte inconnue avec la carte principale. Si cette action est réussie, le LED passe au vert et le relais se déclenche. Si la carte inconnue n'est pas validée avec la carte maîtresse, la LED passe au rouge et le relais ne décroche pas.

Si une carte déjà stockée est lue, le LED passe au cyan. Vous avez maintenant trois secondes pour effacer la carte stockée avec la carte maîtresse. Si cette action est réussie, le LED passe au rouge et le relais ne répond pas. Si la carte stockée n'est pas effacée avec la carte maîtresse, le LED passe au vert et le relais se met en marche.

Au bout de trois secondes, le LED vert s'éteint à nouveau et le relais tombe. Il en va de même pour le LED rouge.

Amusez-vous bien avec la reconstruction.

Specials

2 commentaires

Andreas Wolter

Andreas Wolter

@Roberto Pinto: please check the datasheet: https://cdn.shopify.com/s/files/1/1509/1638/files/RFID_RC522_Set_mit_Reader_Chip_und_Card_13_56MHz_Datenblatt.pdf?2098853292011892896

I think it doesn’t support it.

roberto pinto

roberto pinto

does it work with DESFIRE cards?

Laisser un commentaire

Tous les commentaires sont modérés avant d'être publiés

Messages de blogs recommandés

  1. Installez maintenant ESP32 via l'administrateur de la carte
  2. Lüftersteuerung Raspberry Pi
  3. Arduino IDE - Programmieren für Einsteiger - Teil 1
  4. ESP32 - das Multitalent
  5. OTA-Over the Air-ESP Programmation par WiFi