Siguiendo con los tutoriales de Arduino, les presento ahora cómo puedes trabajar con un módulo de radio frecuencia para leer tarjetas. Voy a trabajar con el módulo RFID RC522 y exploraremos muchas inquietudes que se tienen con este módulo principalmente porque no hay mucha documentación en español para la interacción con Arduino. Podemos obtenerla en Ebay o en Amazon, con la misma compañía que adquirí el LCD HD44780 a poco más de 8.66 USD.
MIFARE es un conjunto de chips ampliamente utilizados en aplicaciones que implican tarjetas inteligentes sin contacto, es decir tarjetas de proximidad y es propiedad de la reconocida NXP Semiconductores. El módulo de RFID que estaré utilizando posee el chip MIFARE RC522, un circuito integrado de lectura/escritura utilizado para la comunicación sin contacto operado bajo una frecuencia de 13.56 MHz a 3.3 V. También posee un cristal de cuarzo de 27.12 MHz.
Las tarjetas que trae este módulo son la estándar S50 de color blanco que puede ser personalizada a través de una impresora de sublimación y la S50 en formato llavero. Ambas tarjetas proveen un número único de identificación de 32 bits y funcionan en base a tecnología NFC (Neard Field Communication) o bien en español, comunicación de campo cercano que permite la comunicación entre dispositivos que estén próximos uno del otro utilizando inducción magnética.
A pesar que este módulo opera a 3.3 V, el chip RC522 también puede operar a 2.5 V. Puede trabajar con distintos protocolos de bajo nivel seriales tipo SPI, UART, o I2C. Sin embargo, este módulo está diseñado para trabajar únicamente con SPI. Si aún no sabes cómo funciona este protocolo te invito a que visites el artículo ¿Cómo funciona el protocolo SPI? en donde comento los conceptos básicos del funcionamiento de este protocolo.
Materiales:
- 1x Arduino UNO
- 1x Módulo RFID – Mifare RC522
- 1x Jumpers cable
- 1x Breadboard
Paso 1: Creando el circuito
Conocer el mapeado de este módulo con la placa Arduino UNO fue difícil de conseguir ya que hay pocos lugares en internet que suministran la información correcta. Con un poco de investigación se puede llegar hasta el mapeado correcto.
MFRC522 | ARDUINO |
SDA | 10 |
SCK | 13 |
MOSI | 11 |
MISO | 12 |
GND | GND |
RST | 9 |
3.3 V | 3.3 V |
Este mapeado se utiliza con la librería RFID MFRC522 que ofrece Miguel Balboa, que bien es una de las mejores librerías que encontré, sin embargo no hace mucho énfasis en la conexión de hardware. Es importante notar que la corriente de operación esperada para operar el módulo está entre el rango de 13-25 mA, la salida de 3.3 V del Arduino UNO drena una corriente máxima de 50 mA, pero en condiciones de operación la corriente no supera más de los 8 mA, siendo estos datos obtenidos a través de un multímetro mientras me encontraba haciendo las pruebas.
Paso 2: Creando el programa
Para utilizar el siguiente código, asumiendo que estas trabajando en un sistema Linux/GNU primero debes tener a disposición la librería de Miguel, esto lo puedes hacer clonando el repositorio:
1 |
git clone http://github.com/miguelbalboa/rfid |
Y luego mover la librería hacia la carpeta libraries dentro de la carpeta Arduino ubicada en tu directorio de usuario
1 |
mv rfid ~/Arduino/libraries |
Una vez que tengas la librería a disposición copia el siguiente código:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
/* Kiara Navarro sophiekovalevsky arroba fedoraproject.org www.panamahitek.com */ /* Pinaje (MFRC522 hacia Arduino) MFRC522 pin SDA hacia el pin 10 MFRC522 pin SCK hacia el pin 13 MFRC522 pin MOSI hacia el pin 11 MFRC522 pin MISO hacia el pin 12 MFRC522 pin GND a tierra MFRC522 pin RST hacia el pin 9 MFRC522 pin 3.3V A 3.3. V */ // Librerías necesarias #include <SPI.h> #include <MFRC522.h> #define SS_PIN 10 // pin SDA hacia el pin 10 #define RST_PIN 9 // pin RST hacia el pin 9 MFRC522 rfid(SS_PIN, RST_PIN); // Creo la instancia de la clase MFRC522 MFRC522::MIFARE_Key key; // Crea una estructura de tipo llave // Inicializo vector que almacenará el NUID del PICC byte nuidPICC[3]; void setup() { Serial.begin(9600); SPI.begin(); // Inicia el bus de SPI rfid.PCD_Init(); // Inicia el lector // Carga los valores que vienen por defecto para las llaves A y B for (byte i = 0; i < 6; i++) { key.keyByte[i] = 0xFF; } Serial.println(F("Este código escanea el número de identificación de una tarjeta MIFARE Classic.")); Serial.print(F("Utilizando la siguiente llave:")); printHex(key.keyByte, MFRC522::MF_KEY_SIZE); } void loop() { // Buscando nuevas tarjetas if ( ! rfid.PICC_IsNewCardPresent()) return; // Lee tarjeta if ( ! rfid.PICC_ReadCardSerial()) return; Serial.print(F("Tipo de PICC: ")); byte piccType = rfid.PICC_GetType(rfid.uid.sak); Serial.println(rfid.PICC_GetTypeName(piccType)); // Verifica si la tarjeta es de tipo MIFARE Classic if (piccType != MFRC522::PICC_TYPE_MIFARE_MINI && piccType != MFRC522::PICC_TYPE_MIFARE_1K && piccType != MFRC522::PICC_TYPE_MIFARE_4K) { Serial.println(F("Tu tarjeta no es del tipo MIFARE Classic")); return; } if (rfid.uid.uidByte[0] != nuidPICC[0] || rfid.uid.uidByte[1] != nuidPICC[1] || rfid.uid.uidByte[2] != nuidPICC[2] || rfid.uid.uidByte[3] != nuidPICC[3] ) { Serial.println(F("Se ha detectado nueva tarjeta")); // Almacena el NUID en el arreglo nuidPICC for (byte i = 0; i < 4; i++) { nuidPICC[i] = rfid.uid.uidByte[i]; } Serial.println(F("Su número no único de identificación es:")); Serial.print(F("En hexadecimal: ")); printHex(rfid.uid.uidByte, rfid.uid.size); Serial.println(); Serial.print(F("En decimal: ")); printDec(rfid.uid.uidByte, rfid.uid.size); Serial.println(); } else Serial.println("Tarjeta leída anteriormente, ingrese otra."); // Halt PICC rfid.PICC_HaltA(); // Detiene el cifrado en el PCD rfid.PCD_StopCrypto1(); } /** * Función que ayuda a representar valores hex en el monitor serial */ void printHex(byte *buffer, byte bufferSize) { for (byte i = 0; i < bufferSize; i++) { Serial.print(buffer[i] < 0x10 ? " 0" : " "); Serial.print(buffer[i], HEX); } } /** * Función que ayuda a representar valores en dec en el monitor serial */ void printDec(byte *buffer, byte bufferSize) { for (byte i = 0; i < bufferSize; i++) { Serial.print(buffer[i] < 0x10 ? " 0" : " "); Serial.print(buffer[i], DEC); } } |
Las tarjetas utilizadas en este módulo poseen un pequeño circuito integrado que funciona en base a inducción electromagnética, cuando ésta está lo suficientemente cercana a la antena (casi unos 10 mm) el campo electromagnético que produce la antena genera un voltaje inducido que le permite al circuito integrado energizarse y así en un corto tiempo leer su correspondiente número de identificación.
El código consiste en almacenar esa lectura en las variables serNumX y compararlas cada vez que se hace la lectura de tarjeta y define si el número de identificación es distinto o no.
Los pines de RST (reset) y SDA son configurables, así que no es necesario que los tengas en los pines 10 y 9. Al usar SPI con respecto a I2C, se tiene la ventaja que las velocidades de transmisión son mucho más altas que las de I2C. Para el RC522 utilizando SPI se puede tener velocidades de hasta 10 Mbit/s, aunque se utiliza más líneas que el I2C.
Para observar la lectura serial, podemos abrir la consola serial que posee arduino y listo =)
Hola Kiara, muy buen post, explicado de una forma muy clara.
Puede ser que las siguientes dos líneas de imports:
//Agregamos las librerias necesarias
#include
#include
…tengan que ser sustituídas por:
#include
#include
Gastón, muchísimas gracias por comentar.
Tienes toda la razón. Se me olvidó copiar las librerías.
Arreglado. 😀
Hola Kiara, buen post, pero creo que los && (and) del if que comprueba si los valores leídos en una tarjeta (rfid.serNum[0], rfid.serNum[1], etc.) son diferentees de las variables definidas (serNum0, serNum1, etc) deben ser || (or), ya que en caso contrario dos tarjetas con valores 45,190,115,8,232 y 189,56,121,8,244 serían tomadass por la misma, precisamente por el valor 8 en ambas tarjetas en la cuarta posición.
Según el if todos los valores deberían ser diferetnes por culpa de los &&.
Un saludo.
Buenas Francisco. Estuve viendo el código y realmente tienes razón.
Muchísimas gracias por pasarte, leer el artículo y darnos ese feedback.
Arreglado.
hola muy excelente información agradeceria si me informara de como puede escribir en la tarjeta S50 con arduino uno RFID-RC522 este es mi correo [email protected].
Antonio, sería bueno crear un artículo de cómo hacerlo. Voy a ver si para esta semana lo puedo hacer. Un saludo.
Me parece perfecto, esperare el articulo muchas gracias. Saludos.
El jue, 28 de mayo de 2015 19:26, Disqus escribió:
Antonio, aún queda pendiente el artículo. He estado bastante saturada estos últimos meses. Pronto tendremos el artículo.
Como aún no hemos subido un artículo, si te urge puedes usar el método MIFARE_Write.
Y para I2C como seria un ejemplo?, la conexion supongo seria con los pines SDA y MISO, ademas de 3.3v y GND
El chip acepta ya sea SPI, I2C y UART como métodos de comunicación serial, sin embargo lo librería actualmente no implementa ha implementado para I2C, únicamente está disponible mediante SPI. Saludos,
Necesito ayuda, tengo 2 meses que compre un arduino y entre mi kit habia un RFID-RC522 hoy intente hacerlo funcionar y me marca errores, algo de lo que me di cuenta es que aqui en la publicacion manejan el #include y en la libreria de miguel balboa utiliza el MFRC522.h intente cambiando la instancia rfid por MFRC522 y resulta que no reconoce las clases, alguien puede ayudarme, gracias de antemano.
¿Podrías colocar el código que estas ejecutando en un fpaste o algo similar?
Saludos.
He actualizado el código para que funcione correctamente.
Gracias por la observación.
Hola
he copiado el codigo para ver como funciona el modulo RC522 y al compilarlo arduino me da el siguiente error:
modulo_rfid522:59: error: invalid conversion from ‘byte {aka unsigned char}’ to ‘MFRC522::PICC_Type’ [-fpermissive]
Serial.println(rfid.PICC_GetTypeName(piccType));
I:documentosArduinolibrariesrfid-master/MFRC522.h:388:36: error: initializing argument 1 of ‘static const __FlashStringHelper* MFRC522::PICC_GetTypeName(MFRC522::PICC_Type)’ [-fpermissive]
static const __FlashStringHelper *PICC_GetTypeName(PICC_Type type);
^
exit status 1
invalid conversion from ‘byte {aka unsigned char}’ to ‘MFRC522::PICC_Type’ [-fpermissive]
gracias de antemano
oye tengo una inquietud, es que no he podido identificar donde está instalado mi Arduino IDE para poder usar completo el comando ‘mv rfid ~/Arduino/libraries’, sin embargo me aparece instalado en el buscador de ubuntu, podrías darme un indicio de donde podría haber quedado instalado Arduino?
Necesitas crearle una interfaz de software, ya sea en Python o quizás Java
Disculpa y si no tengo un sistema Linux, será que pueden proporcionarme la libreria para un sistema windows?
Que librería?
lee muy bien pero yo necesito activar un relay
Eso es fácil. Con una estructura condicional (if) se resuelve