Lectura de tarjetas RFID con Arduino y lector MIFARE RC522


arduino-rfid-rc522

¿Qué es el RFID?

El RFID (Identificador por radiofrecuencia) es un conjunto de tecnologías diseñadas para leer etiquetas (tags) a distancia de forma inalámbrica. Los lectores RFID pueden ser conectados a un autómata o procesador como Arduino.

Las etiquetas RFID están disponibles en una gran variedad de formatos, tales como pegatinas adheribles, tarjetas, llaveros, pueden integrarse en un determinado producto o, incluso, insertarse bajo la piel en un animal o humano.

Los RFID son ampliamente empleados, por ejemplo, en sistemas de alarma, aplicaciones comerciales en sustitución de códigos de barras, cerraduras electrónicas, sistemas de pago, tarjetas personales, control de accesos recintos como gimnasios o piscinas, fichaje en empresas, entre otras muchas aplicaciones.

En nuestros proyectos de electrónica con Arduino podemos usar el RFID, por ejemplo, en aplicaciones comerciales para mostrar en una pantalla los datos al acercar un producto, cambiar la luz o iluminación , abrir una puerta con una tarjeta personal, o hacer que un robot se comporte de forma distinta pasándole una tarjeta

Anuncio:

Cuidado en las aplicaciones de seguridad, como cerraduras. Las tarjetas que emplearemos en nuestros proyectos caseros NO SON CONSIDERADAS SEGURAS y no pueden formar parte de un auténtico sistema de seguridad.

Precio

En el mundo de la electrónica doméstica y los proyectos de Arduino es muy común el lector/grabador MFRC522.

Podemos encontrar kits que incluyen el MFRC522, con una tarjeta y un llavero MIFARE CLASSIC S50 por 1.45€, buscando en vendedores internacionales en eBay o AliExpress.

arduino-rfid-rc522-componente

Si lo que queremos son más etiquetas receptoras podemos encontrar tarjetas o llaveros por unos 0.25€ cada una, o etiquetas adhesivas por unos 0.15€.

¿Cómo funciona el RFID?

El RFID es un conjunto de tecnologías inalámbricas diseñadas para obtener una información almacenada en un dispositivo denominado etiqueta (tag)

El lector (transceptor) es en realidad un emisor-receptor que, en primer lugar, emite una señal para iniciar la comunicación con las etiquetas (transpondedores). Esta señal es captada por las etiquetas dentro del alcance, las cuál responden transmitiendo la información que almacenada que, finalmente, es captada y decodificada por el lector RFID.

El RFID puede operar en cuatro bandas de frecuencia, siendo la más frecuente 13.56 Mhz.

  • Baja frecuencia 125-134.2 kHz. Control de animales, llaves de automóviles...
  • Alta frecuencia 13.56 MHz. Control de accesos, control de artículos en tiendas...
  • Ultra alta frecuencia (UHF) 868 - 956 GHZ
  • Microondas, 2,45 GHz

Existen etiquetas RFID de sólo lectura, es decir, en las que la información que contienen es grabada durante su fabricación y no puede modificarse, y etiquetas de lectura y escritura, en las que podemos sobreeescribir la información de la etiqueta.

Respecto a la alimentación, existen etiquetas RFID activas que disponen de su propia fuente de energía (por ejemplo, una batería). El rango de lectura puede ser de 10m a 100m.

Por contra las etiquetas RFID pasivas obtienen su energía por inducción de la onda electromagnética emitida por el lector. Por tanto, no requieren fuente de alimentación. Sin embargo el alcance de lectura se reduce a unos centímetros.

El NFC, un subconjunto del RFID

La tecnología RFID puede tener alcances de 10-100m. Esto tiene importante consideraciones sobre la seguridad y privacidad. Por ejemplo, imaginemos los peligros de poder leer información de personal o de pagos a estas distancias.

El NFC (Near Field Communication) es un subconjunto de la tecnología RFID que por diseño establece métodos para limitar la distancia de transmisión a menos de 10 cm. El NFC está experimentando un gran desarrollo debido a la inclusión en los smartphone, y posible formas de pago.

Sin embargo, aunque íntimamente relacionados, no hay que confundir RFID y NFC. En particular, no todos los sistemas RFID y NFC serán compatibles, es decir, que no siempre vamos a poder leer una tarjeta RFID con el lector NFC de un smartphone.

El lector MIFARE MFRC522

MIFARE es una tecnología de tarjetas inalámbricas propiedad de NXP Semiconductores. Es uno de los estándares más implantados como tarjetas inteligentes sin contacto (TSIC).

El Mifare MFRC522 es un lector de tarjetas RFID que incorpora comunicación por bus SPI, bus I2C y UART, por lo que es sencillo de conectar con Arduino. El MFRC522 soporta las tarjetas Mifate S50, Mifare S70, Mifare UltraLight, Mifare Pro y Mifare Desfire.

El lector MFRC522 opera en la frecuencia de 13.56Mhz y tiene una distancia de lectura de 0 a 60. El MFRC522 tiene un consumo de 13-26 mA durante la escritura, 10-13mA en stanby e inferior a 80uA en modo sleep. La tensión de alimentación es de 3.3V.

El MFRC522 suele suministrarse con tarjetas o llaveros MIFARE Classic 1K. Este tipo de tarjetas son, esencialmente, un sistema de almacenamiento donde la memoria está dividida en bloques, con mecanismos simple para el acceso a la información.

El MIFARE Classic 1K dispone de 1024 bytes de memoria divididos en 16 sectores de 64 bytes, cada uno protegido por dos claves llamadas A y B. Cada una puede ser programada individualmente para permitir o bloquear operaciones lectura o escritura.

Cada sector reserva una cierta memoria para las claves A y B, por lo que este espacio normalmente no puede ser empleado para guardar datos, lo que reduce la cantidad de memoria disponible en una MIFARE Classic 1K a 752 bytes.

La memoria EEPROM de las tarjetas MIFARE Classic puede soportar más de 100.000 ciclos de escritura, y pueden mantener la memoria durante más de 10 años sin recibir alimentación.

Lamentablemente, las tarjetas MIFARE Classic emplean el estándar ISO/IEC 14443 Type A, que el foro NFC decidió dejar de soportar en 2014. Por ese motivo, los móviles más modernos no serán capaces de leer este tipo de tarjetas.
Las tarjetas MIFARE Classic emplean un sistema de cifrado propio de NXP que, en la actualidad, no es considerado seguro.

Esquema de montaje

La conexión es sencilla. Simplemente alimentamos el módulo desde Arduino mediante 3.3V y Gnd. Por otro lado, conectamos los pines del bus SPI a los correspondientes de Arduino.

arduino-rfid-rc522-esquema

Mientras que la conexión vista desde el lado de Arduino quedaría así.

arduino-rfid-rc522-conexion

Los pines SPI indicados son válidos para los modelos de Arduino Uno, Nano y Mini Pro. Para otros modelos de Arduino consultar el esquema patillaje correspondiente.
Verificar que vuestra placa es tolerante a un bus de 5V antes de conectarla a Arduino. Si no, tendréis que usar un adaptador de nivel lógico.

Ejemplos de código

Para realizar la lectura del RC522 usaremos la librería desarrollada por Miguel Balboa, disponible en este enlace. La librería proporciona ejemplos de código, que resulta aconsejable revisar. Los siguientes ejemplos son modificaciones a partir de los disponibles en la librería.

Mostrar el ID de la tarjeta

El siguiente ejemplo detecta una tarjeta RFID, y muestra su identificador por puerto serie.

//RST	        D9
//SDA(SS)      D10
//MOSI         D11
//MISO         D12
//SCK          D13

#include <SPI.h>
#include <MFRC522.h>

const int RST_PIN = 9;				// Pin 9 para el reset del RC522
const int SS_PIN = 10;				// Pin 10 para el SS (SDA) del RC522
MFRC522 mfrc522(SS_PIN, RST_PIN);   // Crear instancia del MFRC522

void printArray(byte *buffer, byte bufferSize) {
	for (byte i = 0; i < bufferSize; i++) {
		Serial.print(buffer[i] < 0x10 ? " 0" : " ");
		Serial.print(buffer[i], HEX);
	}
}

void setup()
{
	Serial.begin(9600);		//Inicializa la velocidad de Serial
	SPI.begin();			//Función que inicializa SPI
	mfrc522.PCD_Init();     //Función  que inicializa RFID
}

void loop()
{
	// Detectar tarjeta
	if (mfrc522.PICC_IsNewCardPresent())
	{
		if (mfrc522.PICC_ReadCardSerial())
		{
			Serial.print(F("Card UID:"));
			printArray(mfrc522.uid.uidByte, mfrc522.uid.size);
			Serial.println();

			// Finalizar lectura actual
			mfrc522.PICC_HaltA();
		}
	}
	delay(250);
}

Validad el ID de la tarjeta

El siguiente ejemplo lee una tarjeta y comprueba el ID para determinar si la tarjeta es aceptada o no.

//RST          D9
//SDA(SS)      D10
//MOSI         D11
//MISO         D12
//SCK          D13

#include <SPI.h>
#include <MFRC522.h>

const int RST_PIN = 9;        // Pin 9 para el reset del RC522
const int SS_PIN = 10;        // Pin 10 para el SS (SDA) del RC522
MFRC522 mfrc522(SS_PIN, RST_PIN);   // Crear instancia del MFRC522

byte validKey1[4] = { 0xA0, 0xB1, 0xC2, 0xD3 };  // Ejemplo de clave valida

//Función para comparar dos vectores
bool isEqualArray(byte* arrayA, byte* arrayB, int length)
{
  for (int index = 0; index < length; index++)
  {
    if (arrayA[index] != arrayB[index]) return false;
  }
  return true;
}

void setup() {
  Serial.begin(9600); // Iniciar serial
  SPI.begin();        // Iniciar SPI
  mfrc522.PCD_Init(); // Iniciar MFRC522
}

void loop() {
  // Detectar tarjeta
  if (mfrc522.PICC_IsNewCardPresent())
  {
    //Seleccionamos una tarjeta
    if (mfrc522.PICC_ReadCardSerial())
    {
      // Comparar ID con las claves válidas
      if (isEqualArray(mfrc522.uid.uidByte, validKey1, 4))
        Serial.println("Tarjeta valida");
      else
        Serial.println("Tarjeta invalida");

      // Finalizar lectura actual
      mfrc522.PICC_HaltA();
    }
  }
  delay(250);

}

Escritura de datos

En el último ejemplo empleamos las funciones de escritura y lectura para grabar una cadena de texto en la memoria de la tarjeta Mifare.

//RST	        D9
//SDA(SS)      D10
//MOSI         D11
//MISO         D12
//SCK          D13

#include <SPI.h>
#include <MFRC522.h>

const int RST_PIN = 9;
const int SS_PIN = 10;

//Declaracion de cadena de caracteres
unsigned char data[16] = { 'T','E','S','T',' ','R','F','I','D',' ','M','F','R', '5','5','2'}; 
unsigned char *writeData = data; 
unsigned char *str;

MFRC522 mfrc522(SS_PIN, RST_PIN);

MFRC522::MIFARE_Key key;

void printArray(byte *buffer, byte bufferSize) {
	for (byte i = 0; i < bufferSize; i++) {
		Serial.print(buffer[i] < 0x10 ? " 0" : " ");
		Serial.print(buffer[i], HEX);
	}
}

void setup()
{
	Serial.begin(9600);
	SPI.begin();
	mfrc522.PCD_Init();

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

void loop()
{
	if (!mfrc522.PICC_IsNewCardPresent())
		return;

	if (!mfrc522.PICC_ReadCardSerial())
		return;

	MFRC522::StatusCode status;
	byte trailerBlock = 7;
	byte sector = 1;
	byte blockAddr = 4;

	status = (MFRC522::StatusCode) mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, trailerBlock, &key, &(mfrc522.uid));
	if (status != MFRC522::STATUS_OK) {
		Serial.print(F("PCD_Authenticate() failed: "));
		Serial.println(mfrc522.GetStatusCodeName(status));
		return;
	}

	// Write data to the block
	Serial.print(F("Escribir datos en sector "));
	Serial.print(blockAddr);
	Serial.println(F(" ..."));
	printArray((byte*)data, 16); Serial.println();
	status = (MFRC522::StatusCode) mfrc522.MIFARE_Write(blockAddr, (byte*)data, 16);
	if (status != MFRC522::STATUS_OK) {
		Serial.print(F("MIFARE_Write() failed: "));
		Serial.println(mfrc522.GetStatusCodeName(status));
	}
	Serial.println();

	byte buffer[18];
	byte size = sizeof(buffer);

	// Read data from the block (again, should now be what we have written)
	Serial.print(F("Leer datos del sector ")); Serial.print(blockAddr);
	Serial.println(F(" ..."));
	status = (MFRC522::StatusCode) 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(":"));
	printArray(buffer, 16); Serial.println();

	// Halt PICC
	mfrc522.PICC_HaltA();
	// Stop encryption on PCD
	mfrc522.PCD_StopCrypto1();
}
Si te ha gustado esta entrada y quieres leer más sobre Arduino puedes consultar la sección tutoriales de Arduino
3.9 7 votes
Article Rating

Anuncio:

Previous Más memoria para Arduino con la EEPROM externa AT24C256
Next Leer y escribir en una tarjeta SD o micro SD con Arduino
21 Comments
oldest
newest
Inline Feedbacks
View all comments
luisllamas
4 years ago

MISO y MOSI son por hardware, y por tanto no son configurables.
Lo que se hace es que varios dispositivos comparten el bus SPI, y se selecciona el slave con el SS.
Te recomiendo echarle un ojo a la entrada sobre bus SPI https://www.luisllamas.es/arduino-spi/

luisllamas
3 years ago

Porque el tipo de tarjetas que usan estos lectores (Mifare Classic) fueron descrifradas entre 2007 y 2008, y declaradas como inseguras. Emplean una clave de 48 bits, y el sistema de encriptación empleado ha sido publicado como Open Source. Una búsqueda rápida por Internet y puedes encontrar muchos exploits para duplicar este tipo de tarjetas. Incluso un ataque por fuerza bruta contra el lector puede realizarse con un simple móvil en cuestión de segundos.
En serio... no uséis este tipo de tarjetas para proteger algo que realmente queráis proteger.

luisllamas
3 years ago

Bueno, yo para empezar no protegería mi casa con nada que no sea un buen cerrojo, para que imagines el nivel de fe que tengo en las soluciones electrónicas. La seguridad de una RFID, aunque con estos módulos baratos, mejora bastante si: 1) No dejas que te copien la tarjeta (obvio eh? pues los hoteles no lo tienen tan claro XD) 2) Le metes un limitador de intentos, osea, que si intentas loggearte tres veces con una tarjeta incorrecta dejas el sistema 5 minutos parado (por ejemplo) Lo que comentas del Bluetooth, debería ser bastante más seguro. Por un lado,… Read more »

luisllamas
3 years ago

No lo he notado. Aunque tampoco es que sea de mis módulos favoritos/más usados.

luisllamas
3 years ago

Tu primera pregunta da un debate muuuy largo. En resumen, es mucho más que un juguete. El procesador Atmel AVR que monta es un aparato que no tiene nada que envidiar a algo "profesional". Otra cosa es que me fiara de firmar un proyecto que emplea una placa Arduino clónica de 2€ para controlar un equipamiento comercial. Aunque muchos otros lo hacen, y no les pasa nada (yo no lo haría). Pero, aun así, es mucho más que un juguete para aprender electrónica. De hecho, ha empezado una auténtica revolución, poniendo al alcance de cualquiera un dispositivo que, anteriormente, costaba… Read more »

Daniel
3 years ago

Como se modifica la clave? es la FF? Esta misma corresponde a la llave A o a la B?

eduardo
3 years ago

Buenas tardes, he seguido el tutorial y creo que va perfecto, pero tengo un problema, cuando quiero almacenar mas de 16 caracteres en mi buffer para que los guarde y luego los lea, no me funciona.

He probado a incrementar el buffer y otras 80 pruebas y no hay manera.
¿Me podrias echar una mano?
Muchas gracias

Jordi
2 years ago

Con este lector puedo leer targetas de credito comerciales?

Alvaro
2 years ago

Y si deseo leer el contenido de la tarjeta?

Gaspar
2 years ago

Necesito ideas para lo siguiente: me gustaría tener un acceso que requiere que dos (o más) tarjetas diferentes sean colocadas simultáneamente en su lector (cada tarjeta en su lector único, no cambiadas de posición) para entrar. Creo que con un solo Arduino no podría hacerlo. Si pongo dos (o más) ¿Cómo hago para que solo se abra el acceso cuando estén todas colocadas y cada una en su sitio?

Carlos Le Mare
2 years ago
Reply to  Gaspar

Se me ocurre que comuniques ambos arduinos por uno de los pines. De esa manera defines un Arduino como maestro. Cuando el otro Arduino lee correctamente el código de la tarjeta puede activar por 1 segundo la salida. Durante el proceso del Arduino maestro, si el código es correcto, verifica su pin de entrada; si está en 1 entonces permite el acceso, caso contrario no.

Carlos
2 years ago

Hola buenos días,
Estaba haciendo una búsqueda para hacer un control de acceso rfid y en todo momento expresáis que las mifare classic han quedado obsoletas ya que se rompió su seguridad hace años.
Cuales creéis que son las mas seguras? se pueden implementar con arduino?

Miguel
2 years ago

Hola buenas, existe la posibilidad de programar una tarjeta rfid para distintos accesos, (puerta del garaje, portal, trasteros...) en una misma tarjeta rfid.
Soy novato
Un saludo y gracias.

John
2 years ago
Reply to  Miguel

si. pero es mas facil programar los accesos para la misma tarjeta.

Javi
2 years ago

Buenas tardes Luis. Estoy intentando escribir dos bloques, he modificado un poco tu código para que leyera la tarjeta que quiero, pero he probado varías cosas y no tengo ni idea.
Aquí dejo un post en arduino.cc sobre el mismo tema, donde lo explico mejor: *** link removed **

Diego Martínez Martija
2 years ago

Buenos días, Estoy intentando hacer una aplicación que lea el contenido de una pegatina nfc. Todos los ejemplos que veo lo que hacen es leer el código de la pegatina y el número de serie pero lo que necesito es leer el contenido. Si he grabado el mensaje "Hola don pepito" que la aplicación de escritorio me lea ese "Hola don pepito" y no el número de serie de la tarjeta. Los ejemplos que hay en internet se limitan a leer el serial de la pegatina. He usado programas de ejemplo de internet que se supone que graban información en… Read more »

Ivan Alvarez
1 year ago

buenos dias Luis, tengo una duda, para leer las tarjetas mifare Q5 este lector no vale, no?. Hay alguna solucion para esas tarjetas???
Gracias

Lucas
1 year ago

hola, monté el esquema con un arduino mega 2560 y un lector RFID RC522. Funciona perfecto cuando uso la tarjeta y el llavero que me vino con el módulo. Pero cuando quiero usar otros llaveros idénticos al que vino con el modulo, no reconoce la lectura. por qué puede suceder esto?

Jose Garcia
9 months ago

Buen dia, tengo una duda veo que con este dispositivo puedo leer la informacion de las tarjetas mifare ultralight por ejemplo, y supongo tambien escribir sobre las mismas, ahora mi duda en realidad es un problema ya que tenemos una maquina donde laboro que requiere un deposito de solvente para funcionar el cual tiene esta etiqueta una mifare ultralight, en la cual al parecer toma el id y guarda la capacidad que le ingresa la maquina hasta que llega a 0% y ya no opera esta maquina aunque fisicamente tenga solvente para la maquina esta vacio, alguien me pudiera ayudar… Read more »

carlos
16 days ago

Gracias por el tutorial, tengo una duda si quisiera contar por ejemplo 10 objetos dentro de una caja cada uno con un tag rfid arduino podria hacerlo a la vez sin confundirse (contar mas de una vez cada objeto) o deberia contar uno luego moverlo y contar otro.Gracias