Closed metamorphious closed 6 years ago
Good point. In theory we have a wiki. It would be good if we can collect such code snippets there. I would prefer the wiki over a new example because your code do not have serial output where you can interactively "see" the code "working". And we already have a lot of examples ;).
I created a new page for useful code snippets: https://github.com/miguelbalboa/rfid/wiki/Useful-code-snippets
I moved your code here: https://github.com/miguelbalboa/rfid/wiki/Useful-code-snippets#detection-of-tag-removal
@metamorphious Ok for you or should I revert it?
Thats fine. Just wanted to share my solution if others have the same problem.
Great solution! Exactly what I need! But I have a short question: I am new to Arduino programming and testing with a nodeMCU. I would like to build some kind of switch. If a NFC/RFID tag or phone (with NFC) is on the sensor, it should send an "on" signal in MQTT. When the tag/phone is removed, it should send an "off" signal via MQTT. Do I need to put the code in the original code from omersiar? And which parts do I need to exchange? It would be great to have some kind of setting in the web interface, what and when a signal will be send. I want to realize a "switch" at the bed. If the phone is placed near the bed, my smart home will be set in sleep/night mode.
I tried to post a complete example. So the code above should be enough. Just add your MQTT code inside the corresponding if-statements where the presence of a tag is printed.
Thank you for the example. I am really new to Arduino programing but figured out a solution and it's already working. Right now it works with RFID tags and NFC in smartphones. The smartphone I tested with changes it's code every minute, so I get a off/on every minute when the smartphone is still placed on the reader. I try to find a solution for that. When everything is ready and working I can share the complete set here (no user logging etc.).
Update: made it work. It is possible to use the RFID reader in switch and touch mode. Switch: sends "ON" over MQTT when tag is placed on the reader and "OFF" when it is removed Touch: sends "ON" when a tag is placed and removed for the first time and "OFF" at the second time. I will try to share the code as official branch, but I'm very new to Github. So I need some assistance, how to correctly place the code here. Thank you for the snippet, it helped me solve my problem.
Hi everybody, from several days I try to find a solution to detect if a card is present or not, and when is detected I need to read a block after the authentication. With your sample i see that when a card is present the if(result == mfrc522.STATUS_OK) is 0 and 3 alternatively. but when i add my istructions to read the sector only the firdt time i have 0 after the read sector i have always 3 so the card result gone. Really I do not understand how to solve below my Sketch. Thank You very much Best Regards Marco
#include <SPI.h>
#include <MFRC522.h>
#define RST_PIN 22 // Configurable, see typical pin layout above
#define SS_PIN 5 // Configurable, see typical pin layout above
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance
MFRC522::MIFARE_Key key;
bool rfid_tag_present_prev = false;
bool rfid_tag_present = false;
int _rfid_error_counter = 0;
bool _tag_found = false;
void setup() {
Serial.begin(9600); // Initialize serial communications with the PC
while (!Serial); // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
SPI.begin(); // Init SPI bus
mfrc522.PCD_Init(); // Init MFRC522
// Prepare the key (used both as key A and as key B)
// using FFFFFFFFFFFFh which is the default at chip delivery from the factory
for (byte i = 0; i < 6; i++) {
key.keyByte[i] = 0xFF;
}
}
void loop() {
delay(1000);
rfid_tag_present_prev = rfid_tag_present;
_rfid_error_counter += 1;
if(_rfid_error_counter > 2){
_tag_found = false;
}
// Detect Tag without looking for collisions
byte bufferATQA[2];
byte bufferSize = sizeof(bufferATQA);
// Reset baud rates
mfrc522.PCD_WriteRegister(mfrc522.TxModeReg, 0x00);
mfrc522.PCD_WriteRegister(mfrc522.RxModeReg, 0x00);
// Reset ModWidthReg
mfrc522.PCD_WriteRegister(mfrc522.ModWidthReg, 0x26);
MFRC522::StatusCode result = mfrc522.PICC_RequestA(bufferATQA, &bufferSize);
Serial.print("result: ");
Serial.println(result);
if(result == mfrc522.STATUS_OK){
if ( ! mfrc522.PICC_ReadCardSerial()) { //Since a PICC placed get Serial and continue
return;
}
_rfid_error_counter = 0;
_tag_found = true;
}
rfid_tag_present = _tag_found;
// rising edge
if (rfid_tag_present && !rfid_tag_present_prev){
Serial.println("Tag found");
Serial.print(F("Card UID:"));
dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size);
Serial.println();
/*
Serial.print(F("PICC type: "));
MFRC522::PICC_Type piccType = mfrc522.PICC_GetType(mfrc522.uid.sak);
Serial.println(mfrc522.PICC_GetTypeName(piccType));
// Check for compatibility
if ( piccType != MFRC522::PICC_TYPE_MIFARE_MINI
&& piccType != MFRC522::PICC_TYPE_MIFARE_1K
&& piccType != MFRC522::PICC_TYPE_MIFARE_4K) {
Serial.println(F("This sample only works with MIFARE Classic cards."));
return;
}
*/
byte sector = 1;
byte blockAddr = 4;
byte dataBlock[] = {
0x01, 0x02, 0x03, 0x04, // 1, 2, 3, 4,
0x05, 0x06, 0x07, 0x08, // 5, 6, 7, 8,
0x09, 0x0a, 0xff, 0x0b, // 9, 10, 255, 11,
0x0c, 0x0d, 0x0e, 0x0f // 12, 13, 14, 15
};
byte trailerBlock = 7;
byte buffer[18];
byte size = sizeof(buffer);
// Authenticate using key A
Serial.println(F("Authenticating using key A..."));
result = (MFRC522::StatusCode) mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, trailerBlock, &key, &(mfrc522.uid));
if (result != MFRC522::STATUS_OK)
{
Serial.print(F("PCD_Authenticate() failed: "));
Serial.println(mfrc522.GetStatusCodeName(result));
}
result = (MFRC522::StatusCode) mfrc522.MIFARE_Read(blockAddr, buffer, &size);
if (result != MFRC522::STATUS_OK) {
Serial.print(F("MIFARE_Read() failed: "));
Serial.println(mfrc522.GetStatusCodeName(result));
}
Serial.print(F("Data in block ")); Serial.print(blockAddr); Serial.println(F(":"));
dump_byte_array(buffer, 16); Serial.println();
Serial.println();
// Halt PICC
mfrc522.PICC_HaltA();
// Stop encryption on PCD
mfrc522.PCD_StopCrypto1();
}
// falling edge
if (!rfid_tag_present && rfid_tag_present_prev){
Serial.println("Tag gone");
}
}
/**
* 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);
}
}
Well, I have found a workaround for now, I don't like it but it works! After the istruction mfrc522.PCD_StopCrypto1(); mfrc522.PCD_Reset(); delay(100); mfrc522.PCD_Init(); // Init MFRC522
I hope somebody find a better solution without a reset.
Good workaround, the reader hangs no more after a CRC Error.
Hey your code almost works perfectly for me, the only issue i'm having now is the following: When i'm reading the first NFC tag it reads this tag and serial prints hydro, after I remove it it prints Tag gone but when I place the second NFC tag on top of the reader it still prints "hydro" only after I remove the second tag and place it on top of the reader again it serial prints "bio". It's the same problem other way around.
Do you have a clue whats going on here and why it's not serial printing the sentence associated with that specific tag at the first "read out"
#include <SPI.h>
#include <MFRC522.h>
#define RST_PIN 5 // Configurable, see typical pin layout above
#define SS_PIN 4 // Configurable, see typical pin layout above
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance
bool rfid_tag_present_prev = false;
bool rfid_tag_present = false;
int _rfid_error_counter = 0;
bool _tag_found = false;
void setup() {
Serial.begin(9600); // Initialize serial communications with the PC
while (!Serial); // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
SPI.begin(); // Init SPI bus
mfrc522.PCD_Init(); // Init MFRC522
}
void loop() {
String content = "";
byte letter;
for (byte i = 0; i < mfrc522.uid.size; i++)
{
content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
content.concat(String(mfrc522.uid.uidByte[i], HEX));
}
content.toUpperCase();
rfid_tag_present_prev = rfid_tag_present;
_rfid_error_counter += 1;
if (_rfid_error_counter > 2) {
_tag_found = false;
}
// Detect Tag without looking for collisions
byte bufferATQA[2];
byte bufferSize = sizeof(bufferATQA);
// Reset baud rates
mfrc522.PCD_WriteRegister(mfrc522.TxModeReg, 0x00);
mfrc522.PCD_WriteRegister(mfrc522.RxModeReg, 0x00);
// Reset ModWidthReg
mfrc522.PCD_WriteRegister(mfrc522.ModWidthReg, 0x26);
MFRC522::StatusCode result = mfrc522.PICC_RequestA(bufferATQA, &bufferSize);
if (result == mfrc522.STATUS_OK) {
if ( ! mfrc522.PICC_ReadCardSerial()) { //Since a PICC placed get Serial and continue
return;
}
_rfid_error_counter = 0;
_tag_found = true;
}
rfid_tag_present = _tag_found;
// rising edge
if (rfid_tag_present && !rfid_tag_present_prev) {
Serial.println("Tag found");
if (content.substring(1) == "04 BA 94 C2 A8 64 80") {
Serial.println("hydro");
}
if (content.substring(1) == "04 C2 94 C2 A8 64 80") {
Serial.println("bio");
}
}
// falling edge
if (!rfid_tag_present && rfid_tag_present_prev) {
Serial.println("Tag gone");
}
}
@oliviereising move vour content.concat some lines down
void loop() {
rfid_tag_present_prev = rfid_tag_present;
_rfid_error_counter += 1;
if (_rfid_error_counter > 2) {
_tag_found = false;
}
// Detect Tag without looking for collisions
byte bufferATQA[2];
byte bufferSize = sizeof(bufferATQA);
// Reset baud rates
mfrc522.PCD_WriteRegister(mfrc522.TxModeReg, 0x00);
mfrc522.PCD_WriteRegister(mfrc522.RxModeReg, 0x00);
// Reset ModWidthReg
mfrc522.PCD_WriteRegister(mfrc522.ModWidthReg, 0x26);
MFRC522::StatusCode result = mfrc522.PICC_RequestA(bufferATQA, &bufferSize);
String content = "";
if (result == mfrc522.STATUS_OK) {
if ( ! mfrc522.PICC_ReadCardSerial()) { //Since a PICC placed get Serial and continue
return;
}
_rfid_error_counter = 0;
_tag_found = true;
for (byte i = 0; i < mfrc522.uid.size; i++) {
content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
content.concat(String(mfrc522.uid.uidByte[i], HEX));
}
content.toUpperCase();
}
.
.
.
mfrc522.PICC_HaltA();
mfrc522.PCD_StopCrypto1();
}
Thanks that fixed the issue!
Thank you for the contributions in this thread. Inspired in them, and after reviewing the standard, I put together an example that seems to work reliably. You can find it here: https://github.com/Martin-Laclaustra/MFRC522-examples
Not sure where to post.. but here is my solution for detection of a removed RFID tag. May not be the optimal solution but works for me. Maybe it helps someone or can be added to the library somehow.
Step 1: Describe your environment
Relevant Code: