|     Inicio    |   |         |  |   FOROS      |  |      |      
   Elastix - VoIP B4A (Basic4Android) App inventor 2 PHP - MySQL
  Estación meteorológica B4J (Basic4Java) ADB Shell - Android Arduino
  AutoIt (Programación) Visual Basic Script (VBS) FireBase (BD autoactualizable) NodeMCU como Arduino
  Teleco - Emisora de A.M. Visual Basic Cosas de Windows Webs interesantes
T Búsqueda en este sitio:


.

Arduino en español
Circuitos con Arduino - Juan Antonio Villalpando

-- Tutorial de iniciación a Arduino --

Volver al índice del tutorial

____________________________

48.- Módulo Lector inductivo RFID-RC522 RF con Arduino.

- Esto es un lector de tarjeta magnética, parecida a las tarjetas bancarias que introducimos en los comercios para realizar las compras.

- Puede servir, por ejemplo, para abrir una puerta. Cada tarjeta viene de fábrica con un código, cuando la aproximamos al lector, leerá el código, si el código coincide con el que tenemos asignado, se activará un relé que accionará la apertura de la puerta.

- Además del código la tarjeta tambien puede tener grabada información, nombre, edad, cargo...

- RFID = Radio Frequency IDentification.

- Hoja de datos.

- Trabaja por aproximación, es decir entre el lector y la tarjeta debe haber una distancia de menos de 5 cm aprox. Este dispositivo detecta el cambio de impedancia en su antena que produce la tarjeta.

 

RFID Reader:

  • Input voltage: 3.3v
  • Chip: MFRC-522 RC522
  • Operation Current : 13~26mA
  • Idle Current :10~13mA
  • Sleep Current : <80µA
  • Peak Current : <30mA
  • Operation Frequency :13.56MHz
  • Read Range 0~60mm (mifare1)
  • Interface SPI Data Transition Rate : Up to 10Mbit/s
  • Supported card types : mifare1 S50, mifare1 S70, mifare UltraLight, mifare Pro, mifare Desfire

IC Card:

  • Capacity: 8KB EEPROM
  • Divided into 16 sectors, each sector is 4 blocks, each block is 16 bytes, each block as 1 unit
  • Each sector has a separate set of passwords and access control
  • Each card has a unique 32-bit serial number
  • Have anti-collision mechanism, support for multi-card operations
  • No power, with an antenna, embedded encryption control logic and communication logic circuit
  • Data retention period of 10 years, can be rewritten 100,000 times, reading limitless
  • Operating frequency is 13.56MHz
  • RF protocol : ISO14443A
  • Communication speed : 106KBPS
  • Read and write distance : = 10cm (regardless of reader)

NFC TAG Keychain:

  • Main Chip: Philips Mifare 1 S50;
  • Storage capacity: 8Kbit, 16 partitions, each partition with 2 grounp passwords;
  • Operating Frequency: 13.56 MHz;
  • Communication speed: 106K Baud Rate
  • Read and write distance: 2.5 ~ 10cm
  • Read and write time: 1 ~ 2ms
  • Endurance:> 100,000 times;

_________________________________________________

- Librería y ejemplos.

Librería y ejemplos de miguelbalboa: https://github.com/miguelbalboa/rfid

rfid-master.zip

_________________________________________________

- Conexión.

- En el Arduino Uno utilizamos los terminales 9, 10, 11, 12 y 13 como indica la tabla superior, además de alimentación de 3,3 V y Gnd.

- Pero observa que en vez de utilizar la 11, 12 y 13 se puede utilizar la ICSP-4, ICSP-1 y ICSP-3 del conector ICSP.

- ¿Cuáles son esos terminales?

- Lo voy a conectar en el conector ICSP para dejar libre algunos terminales Digitales:

______________________
- DumpInfo.

- El primer stekch que debemos cargar es el DumpInfo que viene en la carpeta examples.

- Aproximamos la tarjeta al lector y nos dará información que podremos leer en el Serial Monitor.

--------------------------

- En la tarjeta se puede guardar hasta 8KBytes de datos. 64 x 16 = 1024 datos de un Byte.

- Cada tarjeta tiene una clave general Card UID de fábrica, en este caso: 03 02 12 03

- Hay tarjetas en las cuales se puede cambiar la UID, pero en muchos casos no las podemos cambiar. No la cambiaremos.

- En los examples hay uno llamado ChangeUID que probablemente te dará el siguente aviso si tu tarjeta no es de UID cambiable.

Card did not respond to 0x40 after HALT command. Are you sure it is a UID changeable one?

- Se pueden comprar tarjetas para asignarle una a cada usuario.

-----------------------------

- Cada línea es un bloque. Hay 64 bloques.

- El conjunto de 4 bloques se llama sector o registro.

- Existen 16 sectores o registros. Cada registro tiene dos claves de 6 bytes cada una.

- Cada sector tiene dos claves.

- En fábrica se le asigna estas claves a cada sector.

A: 00 00 00 00 00 00 La clave B: FF FF FF FF FF FF

- Puedes entrar en ese sector con cualquiera de las dos.

- Las claves de los registros sí se pueden cambiar. Pero es mejor dejarlas como están, porque si cometes un error al escribirlas no podrás volver a entrar en su sector.

- Cada registro tiene 4 bloques de 16 bytes cada uno.

- Nunca escribas en los bloques multiplos de 4 menos 1, es decir en:

0, 3, 7, 11, 15, 19, 23, 27,... ya que puedes sobre escribr las claves de forma errónea y luego no podrás entrar en los sectores correspondientes.

- El bloque 0 es el más importante, se encuentra la identificación de la tarjeta.

- Por ahora NO INTENTES CAMBIAR NI EL CÓDIGO DE LA TARJETA UID, NI LAS CLAVES DE NINGÚN SECTOR.
- DÉJALOS TODOS: 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF

En los bloques de las claves, existe además 4 bytes destinados a los permisos de ese registro (Bits de acceso), es decir indica si se puede leer o escribir ese registro.

Los datos se guardan en hexadecimal.

______________________________
- ReadandWrite.

- Este steck escribe 16 números en la fila o bloque 4

1.- Establece la clave FF FF FF FF FF FF para poder entrar en ese sector:

for (byte i = 0; i < 6; i++) {
key.keyByte[i] = 0xFF;
}

Si tuviera otra clave pondríamos, por ejemplo:

key.keyByte[0] = 0x8A; key.keyByte[1] = 0x00; key.keyByte[2] = 0x36;
key.keyByte[3] = 0x01; key.keyByte[4] = 0xCB; key.keyByte[5] = 0x15;

Pero no cambiaremos la clave en este tutorial.

2.- Escribirá en el bloque 4

byte sector = 1;
byte blockAddr = 4;

byte dataBlock[] = {
0x01, 0x02, 0x03, 0x04, // 1, 2, 3, 4,
0x05, 0x06, 0x07, 0x08, // 5, 6, 7, 8,
0x08, 0x09, 0xff, 0x0b, // 9, 10, 255, 12,
0x0c, 0x0d, 0x0e, 0x0f // 13, 14, 15, 16
};

3.- Escribe en el bloque 4

// Write data to the block
Serial.print(F("Writing data into block ")); Serial.print(blockAddr);
Serial.println(F(" ..."));
dump_byte_array(dataBlock, 16); Serial.println();
status = mfrc522.MIFARE_Write(blockAddr, dataBlock, 16);
if (status != MFRC522::STATUS_OK) {
Serial.print(F("MIFARE_Write() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
}

4.- Lee el bloque 4

// Read data from the block (again, should now be what we have written)
Serial.print(F("Reading data from block ")); Serial.print(blockAddr);
Serial.println(F(" ..."));
status = mfrc522.MIFARE_Read(blockAddr, buffer, &size);
if (status != MFRC522::STATUS_OK) {
Serial.print(F("MIFARE_Read() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
}
Serial.print(F("Data in block ")); Serial.print(blockAddr); Serial.println(F(":"));
dump_byte_array(buffer, 16); Serial.println();

Recuerda, si vas a hacer pruebas...

Nunca escribas en los bloques multiplos de 4 menos 1, es decir en:

0, 3, 7, 11, 15, 19, 23, 27,... ya que puedes sobre escribir las claves de forma errónea y luego no podrás entrar en los sectores correspondientes.

- Para ver cómo ha quedado, podemos volver a cargar el primer programa DumpInfo.

________________________________
- rfid_write_personal_data

- En este ejemplo, escribimos algo en el Serial Monitor, pulsamos Enviar y se escribirá en varios bloques de la tarjeta.
- Cuando escribamos algo, debe terminar en #, por ejemplo: Juan#

Primero pide que introduzcamos nuestro apellido, lo guardará en los bloques 1 y 2.

Serial.println(F("Type Family name, ending with #"));
block = 1;
block = 2;

Luego pide que introduzcamos nuestro nombre, lo guardará en los bloques 4 y 5.

Serial.println(F("Type First name, ending with #"));
block = 4;
block = 5;

Para ver cómo ha quedado, podemos volver a cargar el primer programa DumpInfo.

______________________________
- MifareClassicValueBlock.

No es preciso que realices este ejemplo.

Cambia los permisos del sector #1 (blocks #4 to #7), manteniendo las claves A y B

255 255 255 255 255 255 0 0 0 0 255 255 255 255 255 255

Enmascara las claves. Es mejor no realizar pruebas de cambio de claves ni permisos.

_________________________

- Mis ejemplos:

____________________
1.- Aplicación. Autorizados.

- Supongamos que tenemos un garaje donde la apertura de la puerta es mediante autentificación por tarjeta RFID.

- Cuando un usuario acerque su tarjeta al lector, si su tarjeta está "autorizada", se activará un relé que abrirá la puerta, si no está "autorizada", no se activará el relé.

- Compramos 4 tarjetas RFID. Mediante el primer programa DumpInfo, leemos la UID de cada una de ellas, que evidentemente serán diferentes.

(NOTA: podemos realizar este ejemplo aunque solo tengamos una tarjeta)
(Cambia el número 03021203 por el número de tu tarjeta). Lo demás lo dejas igual.

- Anotamos el UID de cada tarjeta.

- En el siguiente código introducimos el total de tarjetas, en este caso 4 y su código.

- Los códigos son 8 caracteres juntos, mayúsculas, separados por coma, sin espacio.

String autorizados = "04345334,03021203,34567876,A0460B7F";

- Cuando acerquemos una tarjeta, el lector leerá su código UID.

- Escribirá su UID en el Serial Monitor.

- Comparará mediante un bucle if si la UID introducida se encuentra en el String de "autorizados".

- En caso que se encuentre, en el Serial Monitor, debajo de la búsqueda aparecerá:

Serial.println("La tarjeta introducida esta en el grupo de AUTORIZADO");

Código: Autorizados

// Juan Antonio Villalpando
// kio4.com
// juana1991@yahoo.com
#include <SPI.h>
#include <MFRC522.h>

#define SS_PIN 10 //Arduino Uno
#define RST_PIN 9
MFRC522 mfrc522(SS_PIN, RST_PIN);

// Escribimos los códigos de las tarjetas autorizadas.
// Son 8 caracteres separados por coma, sin espacio. Todos juntos.

int total=4; // Total de tarjetas autorizadas
String autorizados = "04345334,03021203,34567876,A0460B7F";

String UID;
String dosbytes;
void setup() {
Serial.begin(9600); // Initialize serial communications with the PC
SPI.begin(); // Init SPI bus
mfrc522.PCD_Init(); // Init MFRC522 card
}

void loop() {
UID="";
// Prepare key - all keys are set to FFFFFFFFFFFFh at chip delivery from the factory.
MFRC522::MIFARE_Key key;
for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF;

// Look for new cards
if ( ! mfrc522.PICC_IsNewCardPresent()) {
return;
}

// Select one of the cards
if ( ! mfrc522.PICC_ReadCardSerial()) return;

// Código de la tarjeta introducida UID
for (byte i = 0; i < mfrc522.uid.size; i++) {
dosbytes = String(mfrc522.uid.uidByte[i],HEX);
if (dosbytes.length() == 1){dosbytes = "0" + dosbytes; };
UID = UID + dosbytes; 
} 
Serial.println("UID = " + UID);
Serial.println();

// Consulta si la tarjeta introducida se encuentra en
// el grupo de autorizados.
for(int i = 0; i < total; i++){
Serial.println(autorizados.substring(9*i,9*i+8));
if (UID == autorizados.substring(9*i,9*i+8)){
Serial.println("La tarjeta introducida esta en el grupo de AUTORIZADO");
}
}

mfrc522.PICC_HaltA(); // Halt PICC
mfrc522.PCD_StopCrypto1(); // Stop encryption on PCD 
}

- He intentado hacer el código fácil de entender.

- Puedes poner un par de LED de tal manera que si está autorizado se encienda un LED verde y si no lo está se encienda uno rojo.

__________________________________
2.- Autorización e identificación del usuario.

- Ahora cada tarjeta llevará grabado el nombre de su usuario propietario.

- Si la tarjeta está autorizada saldrá el mensaje "La tarjeta introducida esta en el grupo de AUTORIZADO" y el nombre del propietario de esa tarjeta.

- Podemos grabar el nombre del usuario mediante los steck anteriores ReadandWrite o el rfid_write_personal_data.

- Vamos grabarlomediante una adaptación del rfid_write_personal_data.

- Solo se guardará el nombre del usuario en el bloque 8

Código
rfid_write_personal_data
simplificado y adaptado al bloque 8

#include <SPI.h>
#include <MFRC522.h>
#define SS_PIN 10 //Arduino Uno
#define RST_PIN 9
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance.

void setup() {
Serial.begin(9600); // Initialize serial communications with the PC
SPI.begin(); // Init SPI bus
mfrc522.PCD_Init(); // Init MFRC522 card
Serial.println(F("Write personal data on a MIFARE PICC "));
}

void loop() {

// Prepare key - all keys are set to FFFFFFFFFFFFh at chip delivery from the factory.
MFRC522::MIFARE_Key key;
for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF;

// Look for new cards
if ( ! mfrc522.PICC_IsNewCardPresent()) {
return;
}

// Select one of the cards
if ( ! mfrc522.PICC_ReadCardSerial()) return;

Serial.print(F("Card UID:")); //Dump UID
for (byte i = 0; i < mfrc522.uid.size; i++) {
Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
Serial.print(mfrc522.uid.uidByte[i], HEX);
} 
Serial.print(F(" PICC type: ")); // Dump PICC type
byte piccType = mfrc522.PICC_GetType(mfrc522.uid.sak);
Serial.println(mfrc522.PICC_GetTypeName(piccType));

byte buffer[34]; 
byte block;
byte status, len;

Serial.setTimeout(60000L) ; // wait until 60 seconds for input from serial
// Ask personal data: Family name
Serial.println(F("Nombre terminado en #"));
len=Serial.readBytesUntil('#', (char *) buffer, 30) ; // read family name from serial
for (byte i = len; i < 30; i++) buffer[i] = ' '; // pad with spaces

block = 8;
//Serial.println(F("Authenticating using key A..."));
status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, block, &key, &(mfrc522.uid));
if (status != MFRC522::STATUS_OK) {
Serial.print(F("PCD_Authenticate() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
else Serial.println(F("PCD_Authenticate() success: "));

// Write block
status = mfrc522.MIFARE_Write(block, buffer, 16);
if (status != MFRC522::STATUS_OK) {
Serial.print(F("MIFARE_Write() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
else Serial.println(F("MIFARE_Write() success: "));

Serial.println(" ");
mfrc522.PICC_HaltA(); // Halt PICC
mfrc522.PCD_StopCrypto1(); // Stop encryption on PCD

}

- Para ver cómo ha quedado, volvemos a cargar el DumpInfo. En el bloque 8 aparecerá los códigos de "Juan Antonio".

- Una vez que tenemos esa tarjeta cargada con el nombre del usuario. Debemos leerla, comprobar si está autorizada y mostrar el nombre que está en el bloque 8.

- Adaptamos el codigo anterior: Autorizados.

- La parte de la lectura del bloque 8 es una adaptación del sketch ReadandWrite.

Código
Autorizados con lectura del bloque 8
				
// Juan Antonio Villalpando
// kio4.com
// juana1991@yahoo.com
#include <SPI.h>
#include <MFRC522.h>

#define SS_PIN 10 //Arduino Uno
#define RST_PIN 9
MFRC522 mfrc522(SS_PIN, RST_PIN);

// Escribimos los códigos de las tarjetas autorizadas.
// Son 8 caracteres separados por coma, sin espacio. Todos juntos.

int total=4; // Total de tarjetas autorizadas
String autorizados = "04345334,03021203,34567876,A0460B7F";

String UID;
String dosbytes;
String entra;
void setup() {
Serial.begin(9600); // Initialize serial communications with the PC
SPI.begin(); // Init SPI bus
mfrc522.PCD_Init(); // Init MFRC522 card
}

void loop() {

// Prepare key - all keys are set to FFFFFFFFFFFFh at chip delivery from the factory.
MFRC522::MIFARE_Key key;
for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF;

// Look for new cards
if ( ! mfrc522.PICC_IsNewCardPresent()) {
return;
}

// Select one of the cards
if ( ! mfrc522.PICC_ReadCardSerial()) return;

// Código de la tarjeta introducida UID
UID = "";
for (byte i = 0; i < mfrc522.uid.size; i++) {
dosbytes = String(mfrc522.uid.uidByte[i],HEX);
if (dosbytes.length() == 1){dosbytes = "0" + dosbytes; };
UID = UID + dosbytes; 
} 
Serial.println("UID = " + UID);
Serial.println();

// Consulta si la tarjeta introducida se encuentra en
// el grupo de autorizados.
entra = "no";
for(int i = 0; i < total; i++){
Serial.println(autorizados.substring(9*i,9*i+8));
if (UID == autorizados.substring(9*i,9*i+8)){
Serial.println("La tarjeta introducida esta en el grupo de AUTORIZADO");
entra = "si";
}
}

Serial.println("----------------------");
if (entra == "si") {
byte trailerBlock = 7;
byte status;
byte buffer[18];
byte size = sizeof(buffer);
byte sector = 2;
int block = 8;
// Authenticate using key B
Serial.println(F("Autentificacion con clave B..."));
status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_B, trailerBlock, &key, &(mfrc522.uid));
if (status != MFRC522::STATUS_OK) {
Serial.print(F("PCD_Authenticate() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}

// Show the whole sector as it currently is
Serial.println(F("Datos en el sector 2:"));
mfrc522.PICC_DumpMifareClassicSectorToSerial(&(mfrc522.uid), &key, sector);
Serial.println();

// Read data from the block
status = mfrc522.MIFARE_Read(block, buffer, &size);
if (status != MFRC522::STATUS_OK) {
Serial.print(F("MIFARE_Read() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
}
Serial.print(F("Datos en el bloque ")); Serial.print(block); Serial.println(F(":"));
dump_byte_array(buffer, 16); Serial.println();
Serial.println();

}

mfrc522.PICC_HaltA(); // Halt PICC
mfrc522.PCD_StopCrypto1(); // Stop encryption on PCD 
}

/**
* Helper routine to dump a byte array as hex values to Serial.
*/
void dump_byte_array(byte *buffer, byte bufferSize) {
for (byte i = 0; i < bufferSize; i++) {
Serial.print(buffer[i] < 0x10 ? " 0" : " ");
Serial.print(buffer[i], HEX);
char hexa;
hexa = buffer[i];
Serial.print (" = ");
Serial.print (hexa);
}
}

 

Para que salga solo el nombre comentar estas líneas:

// Serial.print(buffer[i] < 0x10 ? " 0" : " ");
// Serial.print(buffer[i], HEX);

char hexa;
hexa = buffer[i];
// Serial.print (" = ");
Serial.print (hexa);

______________________________________________
- Propuestas.

- En caso de autorizado el Arduino mediante Bluetooth envía información a otro lugar.

- Suena un sonido cuando está autorizado y otro cuando no está.


_______________________________________
- Cambio de claves de sectores.

Como he mencionado varias veces en este tutorial, el cambio de clave es crítico, si se comete algún error no podremos volver a entrar en ese sector.

Cada sector tiene dos claves. Para actuar con una clave u otra cambiamos esta línea.

status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, trailerBlock, &key, &(mfrc522.uid));


status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_B, trailerBlock, &key, &(mfrc522.uid));

https://www.reddit.com/r/arduino/comments/2g9luj/need_help_with_rfid_cryptography/

En las tarjetas se podría imprimir datos personales, un logo de la empresa,...

- Se pueden comprar tarjetas independientes, 10 tarjetas pueden valer 2 €. Cada una viene con su código UID y con las claves de cada registro.

________________________________

- Mi correo:
juana1991@yahoo.com
- KIO4.COM - Política de cookies. Textos e imágenes propiedad del autor:
© Juan A. Villalpando
No se permite la copia de información ni imágenes.
Usamos cookies propias y de terceros que entre otras cosas recogen datos sobre sus hábitos de navegación y realizan análisis de uso de nuestro sitio.
Si continúa navegando consideramos que acepta su uso. Acepto    Más información