En este tutorial te mostraré cómo leer tarjetas o etiquetas RFID usando un lector RFID-RC522 (MFRC522) y una placa NodeMCU ESP8266.
También te mostraré el diagrama de conexión para que sepas cómo conectar el RFID-RC522 con la ESP8266 para leer tarjetas RFID.
Debido a que este es un tutorial de introducción, solo te mostraré cómo leer el ID de la tarjeta (en hexadecimal) e imprimirlo por serial.
Diagrama de conexión de lector RFID con ESP8266
Comencemos viendo el diagrama. Recuerda que tú puedes soldar los componentes, ponerlos en una protoboard, etcétera. Yo lo he hecho en fritzing y queda así:
La asignación de pines es:
NodeMCU ESP8266,RFID-RC522
D3,RST
D4,SDA
D5,SCK
D6,MISO
D7,MOSI
GND,GND
3V,3.3V
By,parzibyte
Presta especial atención al pin D3 y al pin D4, pues vamos a usarlos dentro del código. También asegúrate de que las conexiones sean confiables, pues en ocasiones por alguna mala conexión el lector no funciona.
Instalar librería
Ya sea que uses el IDE de Arduino o PlatformIO en Visual Studio Code, debes instalar la librería llamada MFRC522 escrita por miguelbalboa (André Balboa).
Yo te recomiendo que uses Visual Studio Code. Aquí te dejo un enlace para que veas cómo comenzar: https://parzibyte.me/blog/2020/02/11/programar-esp8266-vscode/ y otro para mostrarte cómo instalar una librería (en este caso es de otro sensor, pero te servirá como ejemplo para instalar la MFRC522).
Una vez que la hayas instalado, comencemos.
Código fuente para leer RFID con ESP8266
Veamos ahora el código. Primero vemos el setup
y la inicialización de las variables, además es en donde iniciamos la comunicación Serial:
#include <SPI.h>
#include <MFRC522.h>
/*
In the ESP8266, D3 pin is RST_PIN and
D4 pin is SS_PIN
*/
#define RST_PIN D3
#define SS_PIN D4
MFRC522 reader(SS_PIN, RST_PIN);
MFRC522::MIFARE_Key key;
void setup()
{
Serial.begin(9600); // Initialize serial communications and wait until it is ready
while (!Serial)
{
// Nothing here. Just wait for serial to be present
}
SPI.begin();
reader.PCD_Init();
// Just wait some seconds...
delay(4);
// Prepare the security key for the read and write functions.
// Normally it is 0xFFFFFFFFFFFF
// Note: 6 comes from MF_KEY_SIZE in MFRC522.h
for (byte i = 0; i < 6; i++)
{
key.keyByte[i] = 0xFF; //keyByte is defined in the "MIFARE_Key" 'struct' definition in the .h file of the library
}
Serial.println("Ready!");
}
En la línea 11 declaramos el lector de tarjetas RFID y le pasamos el RST_PIN
y el SS_PIN
que son respectivamente el D3 y el D4 de la ESP8266.
Más tarde, en la línea 15 esperamos la comunicación serial e iniciamos el bus SPI, así como el lector.
Después en la línea 29 iniciamos la clave, pues la vamos a necesitar para leer las tarjetas o etiquetas RFID usando este ESP8266. En este caso la clave por defecto es FFFFFFFFFFFF
, si tú cambiaste la clave simplemente cámbiala aquí.
Ahora veamos el loop
que es en donde vamos a leer realmente:
void loop()
{
// Reset the loop if no new card present on the sensor/reader. This saves the entire process when idle.
if (!reader.PICC_IsNewCardPresent())
{
return;
}
// Select one of the cards. This returns false if read is not successful; and if that happens, we stop the code
if (!reader.PICC_ReadCardSerial())
{
return;
}
// At this point, the serial can be read. We transform from byte to hex
String serial = "";
for (int x = 0; x < reader.uid.size; x++)
{
// If it is less than 10, we add zero
if (reader.uid.uidByte[x] < 0x10)
{
serial += "0";
}
// Transform the byte to hex
serial += String(reader.uid.uidByte[x], HEX);
// Add a hypen
if (x + 1 != reader.uid.size)
{
serial += "-";
}
}
// Transform to uppercase
serial.toUpperCase();
Serial.println("Read serial is: " + serial);
// Halt PICC
reader.PICC_HaltA();
// Stop encryption on PCD
reader.PCD_StopCrypto1();
}
La lectura la hacemos en la línea 10. En caso de que haya errores, regresamos de la función. Pero si todo va bien, tendremos el ID o uid en reader.uid.uidByte
.
Por ello es que en la línea 18 recorremos el uid
y vamos convirtiendo ese byte a hexadecimal para tener el ID como una cadena entendible. Además, se agrega un guion. Y finalmente imprimimos el serial en la línea 36.
En mi caso tengo dos etiquetas, la primera tiene el ID 79-EC-34-23
y la segunda tiene el id EC-4A-AB-89
.
Obviamente en lugar de imprimirlo se podría enviar por Bluetooth, enviar a un servidor HTTP, etcétera.
Poniendo todo junto
El código completo queda de la siguiente manera:
/*
____ _____ _ _ _
| _ \ | __ \ (_) | | |
| |_) |_ _ | |__) |_ _ _ __ _____| |__ _ _| |_ ___
| _ <| | | | | ___/ _` | '__|_ / | '_ \| | | | __/ _ \
| |_) | |_| | | | | (_| | | / /| | |_) | |_| | || __/
|____/ \__, | |_| \__,_|_| /___|_|_.__/ \__, |\__\___|
__/ | __/ |
|___/ |___/
____________________________________
/ Si necesitas ayuda, contáctame en \
\ https://parzibyte.me /
------------------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
Creado por Parzibyte (https://parzibyte.me).
------------------------------------------------------------------------------------------------
Si el código es útil para ti, puedes agradecerme siguiéndome: https://parzibyte.me/blog/sigueme/
Y compartiendo mi blog con tus amigos
También tengo canal de YouTube: https://www.youtube.com/channel/UCroP4BTWjfM0CkGB6AFUoBg?sub_confirmation=1
------------------------------------------------------------------------------------------------
*/
#include <SPI.h>
#include <MFRC522.h>
/*
In the ESP8266, D3 pin is RST_PIN and
D4 pin is SS_PIN
*/
#define RST_PIN D3
#define SS_PIN D4
MFRC522 reader(SS_PIN, RST_PIN);
MFRC522::MIFARE_Key key;
void setup()
{
Serial.begin(9600); // Initialize serial communications and wait until it is ready
while (!Serial)
{
// Nothing here. Just wait for serial to be present
}
SPI.begin();
reader.PCD_Init();
// Just wait some seconds...
delay(4);
// Prepare the security key for the read and write functions.
// Normally it is 0xFFFFFFFFFFFF
// Note: 6 comes from MF_KEY_SIZE in MFRC522.h
for (byte i = 0; i < 6; i++)
{
key.keyByte[i] = 0xFF; //keyByte is defined in the "MIFARE_Key" 'struct' definition in the .h file of the library
}
Serial.println("Ready!");
}
void loop()
{
// Reset the loop if no new card present on the sensor/reader. This saves the entire process when idle.
if (!reader.PICC_IsNewCardPresent())
{
return;
}
// Select one of the cards. This returns false if read is not successful; and if that happens, we stop the code
if (!reader.PICC_ReadCardSerial())
{
return;
}
// At this point, the serial can be read. We transform from byte to hex
String serial = "";
for (int x = 0; x < reader.uid.size; x++)
{
// If it is less than 10, we add zero
if (reader.uid.uidByte[x] < 0x10)
{
serial += "0";
}
// Transform the byte to hex
serial += String(reader.uid.uidByte[x], HEX);
// Add a hypen
if (x + 1 != reader.uid.size)
{
serial += "-";
}
}
// Transform to uppercase
serial.toUpperCase();
Serial.println("Read serial is: " + serial);
// Halt PICC
reader.PICC_HaltA();
// Stop encryption on PCD
reader.PCD_StopCrypto1();
}
En este caso lo he ejecutado en mi NodeMCU ESP8266 y efectivamente lee ambas tags RFID:
Por cierto, las etiquetas se ven como en la imagen a continuación. Tengo una tarjeta y una cosa azul que he usado como llavero de mi memoria USB (Son las que vienen incluidas con el lector).
Obviamente a partir de esto podemos hacer varias cosas, pues ya tenemos el ID y podemos enviarlo por HTTP, mostrarlo en una LCD, etcétera. Las aplicaciones son infinitas, se me ocurre (aunque cada cosa llevaría sus requisitos y no sería tan simple como parece):
- Control de acceso
- Pase de asistencia
- Monedero electrónico
En este caso solo estamos leyendo el ID de la tarjeta. Se pueden guardar datos dentro de ella, pero yo no lo recomiendo, prefiero que todo sea manejado del lado del servidor o del lado del lector.
Por mencionar un ejemplo, si hacemos un monedero electrónico y guardamos el dinero en la tarjeta, si alguien puede modificar los valores podrá aumentarse la cantidad. Así que para otro tipo de aplicaciones sería recomendable cambiar la contraseña, solicitar un pin además de la tarjeta, etcétera.
Igualmente en el repositorio oficial encuentras más ejemplos. Finalmente te dejo con un enlace para aprender más sobre la ESP8266.
Buenas.
Lo primero felicidades por tu blog. Me parece de muy buen interés.
He ejecutado tu código en un Arduino Uno. La línea 34 y 35 la he cambiado por
#define RST_PIN D9
#define SS_PIN D10
En la conexión con arduino uno el RST es el pin 9 y el SDA es el pin 10
El caso es que tenga el arduino o no lo tenga conectado al ordenador me da el siguiente error en el código:
exit status 1
‘D10’ was not declared in this scope
¿Sabes a qué se puede deber?