Utilizando el lector NFC RC522 en la Raspberry Pi

La tecnología de Near Field Communications (NFC) se ha vuelto muy popular desde hace un par de años, al incluirse en teléfonos móviles, tarjetas de crédito e incluso pasaportes.

Hace unos días, adquirí algunos lectores NFC para intentar conectarlos a la Raspberry Pi para un par de proyectos que tengo en mente. Esta será una extremadamente-corta entrada, donde les explicaré los avances en su uso y funcionamiento y les compartiré el código que he utilizado para hacer funcionar el módulo lector.





El módulo RFID


Las tecnologías de identificación por radio-frecuencia (RFID) cubren una amplia gama de estándares. Los dispositivos con NFC son aquellos que funcionan utilizando inducción magnética y trabajan a una frecuencia de 13.56MHz.

Usualmente las etiquetas RFID funcionan como simples códigos de barra, es decir, simplemente reportan un número que es identificado por el lector. El estándar NFC tiene la característica particular que permite el envío y recepción de datos, de manera adicional existen estándares que ofrecen cifrado en la comunicación lo que permite almacenar información "sensible" y protegerla en la transmisión. Piensen en las tarjetas de crédito y los pasaportes.

El módulo que elegí es el MF522-AN, este "kit" me gustó mucho porque incluye un pequeño llavero NFC, una tarjeta "S50",, una tableta de pruebas con antena incluida y los pines necesarios que facilitan la conexión.

Este módulo se comunica por medio de la interfaz I2C o SPI. Esta entrada no vamos a detenernos mucho en explicar como funciona esta interfaz ya que lo que más nos interesa saber, es que es una forma muy fácil de conectar sensores a tabletas controladores, en nuestro caso, a la Raspberry Pi.

Configurando nuestra Raspberry Pi


El puerto GPIO posee soporte tanto para I2C como para SPI. Antes de conectar el módulo debemos habilitar el soporte de la siguiente manera:

Editamos el siguiente archivo:

/etc/modprobe.d/raspi-blacklist.conf

Una vez abierto debemos comentar la línea:

blacklist spi-bcm2708

El archivo nos deberá quedar como se muestra aquí:

# blacklist spi and i2c by default (many users don't need them)

#blacklist spi-bcm2708
blacklist i2c-bcm2708

Reiniciamos nuestra Raspberry Pi y verificamos que existan los dispositivos con el comando "ls":

pi@raspberrypi ~ $ ls /dev/spidev0.*
/dev/spidev0.0  /dev/spidev0.1

Conectando el Módulo


La conexión del módulo es sumamente sencilla como se mostró en la imagen al inicio:


Solo tengan cuidado de no invertir las líneas MOSI y MISO y conectarlas justo como se muestra en el diagráma.

Antes de continuar... Una brevísima explicación de la interfaz SPI


En proyectos anteriores hemos utilizado el puerto serial para Leer/Escribir datos. Dicho puerto tiene la ventaja de que resulta muy fácil de utilizarse y podemos fácilmente procesar los datos que recibimos.

Tanto I2C como SPI son interfaces para comunicación entre circuitos. Este tipo de interfaz utiliza un "bus" para comunicarse es decir un solo cable sirve para enviar o recibir datos desde distintos dispositivos.. Para el caso de SPI tenemos escencialmente 4 líneas:
  • MOSI: Master Out Slave In, por esta línea se envían datos en forma serial desde el dispositivo "maestro" a los dispositivos esclavos.
  • MISO: Master In Slave Out, por esta línea los dispositivos esclavos envían datos al dispositivo maestro.
  • SCK/SCLK: Línea de reloj, aquí se envía un tren de pulsos que se encarga sincronizar las comunicaciones entre los dispositivos.
  • CE: Cada dispositivo tiene una línea de "habilitado", en el dispositivo maestro deberían de haber tantas líneas de habilitado como dispositivos esclavos existan. Los dispositivos esclavo en cambio solo tienen una línea CE que les indica cuando tienen que enviar/recibir datos. En este ejemplo la linea SDA hace las veces de "CE" en nuestro lector NFC.
La interfaz SPI si bien "utiliza" más líneas que I2C tiene la ventaja de que alcanza altas velocidades de transferencia (1Mbps), además su implementación usualmente resulta más sencilla ya que utiliza simples línea serie.



El código fuente...


Primero, necesitamos descargar una pequeña biblioteca que nos permitirá acceder al puerto SPI en la Raspberry Pi en python GitHub con el siguiente comando:

git clone https://github.com/lthiery/SPI-Py

Nos cambiamos a la carpeta SPI-Py y ejecutamos:

sudo python setup.py install


Una ves haya terminado descargamos el código fuente de la clase que controla el lector NFC:

git clone https://github.com/mxgxw/MFRC522-python


Para ejecutarlo, simplemente nos cambiamos a la carpeta MFRC522-python y ejecutamos:

sudo python MFRC522.py


Esta vez no voy a explicar en detalle el funcionamiento ya que es bastante más complicado que una comunicación serial simple.  Pero intentando resumir un poco el código se encarga de inicializar el lector NFC y mantenerse leyendo continuamente para detectar una tarjeta y leer el ID correspondiente.


MIFAREReader = MFRC522()

while continue_reading:
  (status,TagType) = MIFAREReader.MFRC522_Request(MIFAREReader.PICC_REQIDL)
 
  if status == MIFAREReader.MI_OK:
    print "Card detected"

  (status,backData) = MIFAREReader.MFRC522_Anticoll()
  if status == MIFAREReader.MI_OK:
    print "Numero de la tarjeta: "+str(backData[0])+","+str(backData[1])+","+str(backData[2])+","+str(backData[3])+","+str(backData[4])


Importante:  Esta es una re-escritura en Python del código de ejemplo para Arduino, aún no está completo, por el momento solo permite detectar el tipo de tarjeta y leer el número de identificación. Conforme pase el tiempo actualizaré el resto de funciones.

Sin embargo, con esta funcionalidad muy "sencilla" de lectura del ID podrían generar una secilla aplicación de llave electrónica.


Unas cuantas fotos



Por último les comparto unas cuantas fotos del lector conectado funcionando y del programa en ejecución desde la Raspberry Pi.







No habiendo nada más que decir... ¡Hasta la pŕoxima!


Más información y fuentes


Comentarios

Unknown ha dicho que…
Este comentario ha sido eliminado por el autor.
Surfparadise ha dicho que…
Hola Mario, acabo de leer tu post y es muy interesante. Justo ahora me comprè uno de esos cacharro. :-D

Pero eventualmente por escribir las informaciones en una tarjeta...como se puede hacer? Tiene ya un codigo preparado? Hay un instruccion especial?

Gracias,
gex ha dicho que…
Este comentario ha sido eliminado por el autor.
gex ha dicho que…
hola estoy tratando de utilizar este código de ejemplo, pero hasta ahora no lo he conseguido por el hecho de que la biblioteca no está instalado o reconocido ltieri, utilizo python3.2 y por casualidad me refiero a ¿cómo podría solucionar este problema?
chemitaxis ha dicho que…
Hola, qué tal= Una pregunta, donde has conseguido los plastiquitos negros que unen los cables con la tarjeta RC522?

Mil millones de gracias por el artículo...

Saludos!!
Unknown ha dicho que…
Thanks for this great tutorial!! Even if I do not speak Spanish, I passed all hurdles.
One thing appears during the test. The program started correctly. While scanning my tags following message appeared:

AUTH ERROR
Card detected
Card read UID: 74,181,103,10,146
Size: 8
AUTH ERROR!!
AUTH ERROR(status2reg & 0x08) != 0

What happend here? I am pretty new to python and I tried to understand what happend in the code, but I really did not understand this message. Can you help me?
Unknown ha dicho que…
Muchas Gracias me sirvio mucho tu ayuda, muy bien explicado.
Unknown ha dicho que…
I could use some help if you dont mind. I have everything done properly but, when I run the python file nothing happens. it goes straight back to the 'user@Examplename~$'
if you could email me back at smeck1999@gmail.com it would be much appriciated. Thanks again! - Seth Moeckel

***********************************
Me vendría bien un poco de ayuda si no te importa . He hecho todo correctamente , pero cuando ejecuto el archivo python no pasa nada. que va directamente de vuelta al "usuario @ Examplename ~ $ '
si usted me podría enviar de vuelta a smeck1999@gmail.com sería muy appriciated . Gracias de nuevo ! Esto se tradujo con traductor Google ... espero su no difícil de entender .
JotaDePicas ha dicho que…
Muy buen articulo!
Solo un comentario, donde dice de ejecutar "sudo python MFRC522.py", en realidad si no entiendo mal debiera decir "sudo python Read.py" (o Write.py). Es decir MFRC522.py es la libreria, y Read.py y Write.py son los programas de ejemplo que sí tiene sentido ejecutar, verdad?
saludos!
Unknown ha dicho que…
Este comentario ha sido eliminado por el autor.
redsuitheart ha dicho que…
Este comentario ha sido eliminado por el autor.
redsuitheart ha dicho que…
MFRC522.py que hace referencia a dos archivos "/dev/spidev0.0" y "/dev/spidev0.1" que no existen... y tampoco existe el archivo "/etc/modprobe.d/raspi-blacklist.conf"

El error que mostraba era el siguiente... "Can't open device: No such file or directory"

Busque por todos lados y aquí como lo solucione:

ejecutas el comando "sudo raspi-config" después seleccionas "Advanced Options" seleccionas "SPI" Y lo habilitas poniendo todo "YES" repites el proceso "Advanced Options" y esta ves seleccionas I2C y de nuevo le das todo "YES" reinicias y funciona ;
Padre ha dicho que…
Hola, gracias por el post pero algo me falla.

El lector no me lee ninguna tarjeta y no sé si puede ser por los warnings que me lanza SPI-Py cuando lo instalo. Dudo de si estos warnings son parte de los mensajes normales o pueden ser los causantes de que el lector no me lea ninguna tarjeta.

La salida por pantalla cuando ejecuto sudo python setup.py install es:

running install
running build
running build_ext
building 'spi' extension
creating build
creating build/temp.linux-armv7l-2.7
gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -I/usr/include/python2.7 -c spi.c -o build/temp.linux-armv7l-2.7/spi.o
spi.c:197:2: warning: initialization from incompatible pointer type [enabled by default]
spi.c:197:2: warning: (near initialization for ‘SpiMethods[0].ml_meth’) [enabled by default]
creating build/lib.linux-armv7l-2.7
gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Wl,-z,relro build/temp.linux-armv7l-2.7/spi.o -o build/lib.linux-armv7l-2.7/spi.so
running install_lib
copying build/lib.linux-armv7l-2.7/spi.so -> /usr/local/lib/python2.7/dist-packages
running install_egg_info
Removing /usr/local/lib/python2.7/dist-packages/SPI_Py-1.0.egg-info
Writing /usr/local/lib/python2.7/dist-packages/SPI_Py-1.0.egg-info

¿Eso son los mensajes que se deberían ver o los warning no deberían estar? ¿Me podrías copiar aquí tu salida por pantalla?

Muchas gracias.
Ricardor ha dicho que…
UNA CONSULTA ESTIMADO SEGUI TU TUTORIAL Y ME FUNCIONA TODO OK, MUCHAS GRACIAS PERO NO HE LOGRADO UNA COSA , DESPUES DE RECIBIR UN ID DE TARJETA RDFI NO LOGRO ENCENDER UN LED, Y COMO CREO QUE YA ENTENDERAS SI NO LOGRO ENCENDER UN LED TAMPOCO PODRE DAR PASO A UN RELE, SABRAS COMO HACERLO?
redsuitheart ha dicho que…
Que tal Ricardo a ver si esto te ayuda... esta en python

Conecta el negativo del led en a una tierra del raspberry y el positivo va a la posicion 7 de los pines del rapberry... "el cuarto pin de la primera fila"

https://unpocodejava.files.wordpress.com/2013/08/image033.png


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

import RPi.GPIO as GPIO
import spi
import signal
from time import sleep


pinNum=7 # BOARD
GPIO.setmode(GPIO.BOARD)

GPIO.setup(pinNum,GPIO.OUT)
sleep(1)
GPIO.output(pinNum,True)
sleep(0.3)
GPIO.output(pinNum,False)
Ricardor ha dicho que…
Muchas gracias Estimado Julian, pero no es lo que busco, el codigo que me indicas claro prende y apaga el led por un intervalo. Eso ya lo he visto y lo he practicado. Pero al intentar hacer lo mismo de prender el led usando la libreria RPi.GIO dentro de la aplicacion MFRC522.py que me ha sido gran ayuda para aprender mas sobre el tema, esta aplicacion da problema al intentar cargar la libreria RPi.GIO.

Por el minuto estoy tratando de recuperar la SD ya que se estropeo al insertar un usb de un teclado inalambrico (eso creo), si no accedo a la sd no puedo cambiar el codigo creo que tendre que hacer el trabajo nuevamente.

Pero mas que nada el problema se produce al intentar usar RPi.GIO dentro de MFRC522.py


Muchas gracias !!!!!
Unknown ha dicho que…
Estimado Ricardo, Creo que estás importando mal la librería
Tienes que escribir esto al principio de tu código
import RPi.GPIO as GPIO
Fíjate bien en como está escrito ya que en tu comentario dices que la librería es RPi.GIO
El tipo de pin se llama GPIO, General Purpose Input/Output, por esto la librería se llama RPi.GPIO.
Salvador PP ha dicho que…
Buenas noches compañeros:

a ver si me podeis ayudar, ya que mis conocimientos en esta materia son escasos:

Cuando introduzco en la consola, el siguiente comando:

git clone https://github.com/lthiery/SPI-Py

me dice: fatal: destination path 'SPI-Py' already exists and is not an empty directory....¿a alguién se le ocurre que puede estar ocurriendo?...porque el directorio existe.....

Mil gracias de antemano.

Entradas populares de este blog

Reactivando el Blog

Emulando el Raspberry Pi OS con QEMU en Linux

Escribiendo Mensajes al Blockchain de Bitcoin