Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Detect card removal. #188

Closed
Rademanc opened this issue Feb 5, 2016 · 24 comments
Closed

Detect card removal. #188

Rademanc opened this issue Feb 5, 2016 · 24 comments

Comments

@Rademanc
Copy link

Rademanc commented Feb 5, 2016

Hi there.
I want to continuously read a tag and check when it's been removed from the reader.
Is this possible?
The mfrc522.PICC_IsNewCardPresent() method seems to ping poing between true and false.
Can you give me some advice?
Thanks.

@lmmeng
Copy link

lmmeng commented Feb 5, 2016

Hello @Rademanc,
If the card is present, the PICC_ReadCardSerial() method is also ping-poing between true and false, but when the card is absent, the PICC_ReadCardSerial() is returning always false.
I use this info to detect the removed card by counting the number of successive false: if == 2, than the card was removed.

@Rademanc
Copy link
Author

Rademanc commented Feb 6, 2016

Thanks guys.
I will check it out.

@mdxs
Copy link
Contributor

mdxs commented May 15, 2016

Can be closed, assuming that hint of @Rademanc helped solve the issue.

@jk987
Copy link

jk987 commented Jan 15, 2017

And what about something like this:

... 
while (true) {
  status = PICC_WakeupA(...);
  if (status != ...) break;  // Card not present.
  PICC_HaltA(...);
}

@pixelecho
Copy link

@Rademanc
would be great if you can give some code snipped for detection of presence and non presence. i give them a try with count of false returning from PICC_ReadCardSerial but without any solution

thanks for help

@mrozo
Copy link

mrozo commented Oct 20, 2017

I have no idea why, but this works:

/*
 * Initial Author: ryand1011 (https://github.com/ryand1011)
 *
 * Reads data written by a program such as "rfid_write_personal_data.ino"
 *
 * See: https://github.com/miguelbalboa/rfid/tree/master/examples/rfid_write_personal_data
 *
 * Uses MIFARE RFID card using RFID-RC522 reader
 * Uses MFRC522 - Library
 * -----------------------------------------------------------------------------------------
 *             MFRC522      Arduino       Arduino   Arduino    Arduino          Arduino
 *             Reader/PCD   Uno/101       Mega      Nano v3    Leonardo/Micro   Pro Micro
 * Signal      Pin          Pin           Pin       Pin        Pin              Pin
 * -----------------------------------------------------------------------------------------
 * RST/Reset   RST          9             5         D9         RESET/ICSP-5     RST
 * SPI SS      SDA(SS)      10            53        D10        10               10
 * SPI MOSI    MOSI         11 / ICSP-4   51        D11        ICSP-4           16
 * SPI MISO    MISO         12 / ICSP-1   50        D12        ICSP-1           14
 * SPI SCK     SCK          13 / ICSP-3   52        D13        ICSP-3           15
*/

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

#define RST_PIN         9           // Configurable, see typical pin layout above
#define SS_PIN          10          // Configurable, see typical pin layout above

MFRC522 mfrc522(SS_PIN, RST_PIN);   // Create MFRC522 instance

//*****************************************************************************************//
void setup() {
  Serial.begin(9600);                                           // Initialize serial communications with the PC
  SPI.begin();                                                  // Init SPI bus
  mfrc522.PCD_Init();                                              // Init MFRC522 card
}
void PrintHex(uint8_t *data, uint8_t length) // prints 8-bit data in hex with leading zeroes
{
     char tmp[16];
       for (int i=0; i<length; i++) { 
         sprintf(tmp, "0x%.2X",data[i]); 
         Serial.print(tmp); Serial.print(" ");
       }
}
uint8_t buf[10]= {};
MFRC522::Uid id;
MFRC522::Uid id2;
bool is_card_present = false;
//*****************************************************************************************//

void cpid(MFRC522::Uid *id){
  memset(id, 0, sizeof(MFRC522::Uid));
  memcpy(id->uidByte, mfrc522.uid.uidByte, mfrc522.uid.size);
  id->size = mfrc522.uid.size;
  id->sak = mfrc522.uid.sak;
}

bool cmpid(MFRC522::Uid *id1, MFRC522::Uid *id2){
  return memcmp(id1, id2, sizeof(MFRC522::Uid));
}

void deregister_card(){
  is_card_present = false;
  memset(&id,0, sizeof(id));
}
uint8_t control = 0x00;
void loop() {

  MFRC522::MIFARE_Key key;
  for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF;
  MFRC522::StatusCode status;

  //-------------------------------------------

  // Look for new cards
  if ( !mfrc522.PICC_IsNewCardPresent()) {
    return;
  }
  if ( !mfrc522.PICC_ReadCardSerial()) {
    return;
  }
  //PrintHex(id.uidByte, id.size);
  //Serial.println("hello");
  bool result = true;
  uint8_t buf_len=4;
  cpid(&id);
  Serial.print("NewCard ");
  qPrintHex(id.uidByte, id.size);
  Serial.println("");
  while(true){
    control=0;
    for(int i=0; i<3; i++){
      if(!mfrc522.PICC_IsNewCardPresent()){
        if(mfrc522.PICC_ReadCardSerial()){
          //Serial.print('a');
          control |= 0x16;
        }
        if(mfrc522.PICC_ReadCardSerial()){
          //Serial.print('b');
          control |= 0x16;
        }
        //Serial.print('c');
          control += 0x1;
      }
      //Serial.print('d');
      control += 0x4;
    }
    
    //Serial.println(control);
    if(control == 13 || control == 14){
      //card is still there
    } else {
      break;
    }
  }
  Serial.println("CardRemoved");
  delay(500); //change value if you want to read cards faster

  mfrc522.PICC_HaltA();
  mfrc522.PCD_StopCrypto1();
}
//*****************************************************************************************//a
`

@chefslot
Copy link

chefslot commented Apr 11, 2018

@mrozo
So i have been looking through your code, i'm no good with code, but i'm trying to have a detect when removed but with multiple cards, works for one at a time. As soon as i but card a down, it doesn't registrar card b, until card a has been removed.

`#include <SPI.h>
#include <MFRC522.h>
constexpr uint8_t RST_PIN = 9; // Configurable, see typical pin layout above
constexpr uint8_t SS_1_PIN = 10; // Configurable, take a unused pin, only HIGH/LOW required, must be diffrent to SS 2
constexpr uint8_t SS_2_PIN = 8; // Configurable, take a unused pin, only HIGH/LOW required, must be diffrent to SS 1
constexpr uint8_t NR_OF_READERS = 2;
byte ssPins[] = {SS_1_PIN, SS_2_PIN};
MFRC522 mfrc522[NR_OF_READERS]; // Create MFRC522 instance.
//*****************************************************************************************//
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

for (uint8_t reader = 0; reader < NR_OF_READERS; reader++) {
mfrc522[reader].PCD_Init(ssPins[reader], RST_PIN); // Init each MFRC522 card
Serial.print(F("Reader "));
Serial.print(reader);
Serial.print(F(": "));
mfrc522[reader].PCD_DumpVersionToSerial();

}
}
uint8_t control = 0x00;
//*****************************************************************************************//

void loop() {

for (uint8_t reader = 0; reader < NR_OF_READERS; reader++) {
// Look for new cards
if (mfrc522[reader].PICC_IsNewCardPresent() && mfrc522[reader].PICC_ReadCardSerial()) {
Serial.println(reader); {

    if (reader == 0) {

      Serial.println("NewCard ");

      while (1) {
        control = 0;
        for (int i = 0; i < 3; i++) {
          if (!mfrc522[reader].PICC_IsNewCardPresent()) {
            if (mfrc522[reader].PICC_ReadCardSerial()) {
              //Serial.print('a');
              control |= 0x16;
            }
            if (mfrc522[reader].PICC_ReadCardSerial()) {
              //Serial.print('b');
              control |= 0x16;
            }
            //Serial.print('c');
            control += 0x1;
          }
          //Serial.print('d');
          control += 0x4;
        }

        //Serial.println(control);
        if (control == 13 || control == 14) {
          //card is still there
        } else {
          break;
        }

      }
      Serial.println("CardRemoved");
      delay(500); //change value if you want to read cards faster

    }
    else if (reader == 1) {


      Serial.println("NewCard ");

      while (1) {
        control = 0;
        for (int i = 0; i < 3; i++) {
          if (!mfrc522[reader].PICC_IsNewCardPresent()) {
            if (mfrc522[reader].PICC_ReadCardSerial()) {
              //Serial.print('a');
              control |= 0x16;
            }
            if (mfrc522[reader].PICC_ReadCardSerial()) {
              //Serial.print('b');
              control |= 0x16;
            }
            //Serial.print('c');
            control += 0x1;
          }
          //Serial.print('d');
          control += 0x4;
        }

        //Serial.println(control);
        if (control == 13 || control == 14) {
          //card is still there
        } else {
          break;
        }
      }
      Serial.println("CardRemoved");
      delay(500); //change value if you want to read cards faster


    }

    mfrc522[reader].PICC_HaltA();
    mfrc522[reader].PCD_StopCrypto1();
  }
}

}
}

//*****************************************************************************************//a
`

@mrozo
Copy link

mrozo commented Apr 18, 2018

wow, this is some old code, which i've created using evolutionary method (that means I don't know how it works ;] ), but if I were you, I would start poking somewhere near this code:

if (control == 13 || control == 14) { //card is still there } else {

and replace //card is still there with code checking if the card id has changed.

@joebhullar
Copy link

joebhullar commented Apr 29, 2018

it doesn't work longer than 5 seconds. Ie) holding the RFID Card against RC522 longer than 5 seconds my ESP8266 crashes & then needs to be restarted. -- It does work if the card is there for Less than 5 seconds ie) holding it there for 3 seocnds or 4 seconds it will successfully say in Serial "New Card"/"Card Removed"

@joebhullar
Copy link

joebhullar commented May 1, 2018

This seems to work well :) I just tested it for 5 mins, no issues!

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

#define RST_PIN         D9           // Configurable, see typical pin layout above
#define SS_PIN          D8          // Configurable, see typical pin layout above

MFRC522 mfrc522(SS_PIN, RST_PIN);   // Create MFRC522 instance

//*****************************************************************************************//
void setup() {
  Serial.begin(9600);                                           // Initialize serial communications with the PC
  SPI.begin();                                                  // Init SPI bus
  mfrc522.PCD_Init();                                              // Init MFRC522 card
}
void PrintHex(uint8_t *data, uint8_t length) // prints 8-bit data in hex with leading zeroes
{
     char tmp[16];
       for (int i=0; i<length; i++) { 
         sprintf(tmp, "0x%.2X",data[i]); 
         Serial.print(tmp); Serial.print(" ");
       }
}
uint8_t buf[10]= {};
MFRC522::Uid id;
MFRC522::Uid id2;
bool is_card_present = false;
//*****************************************************************************************//

void cpid(MFRC522::Uid *id){
  memset(id, 0, sizeof(MFRC522::Uid));
  memcpy(id->uidByte, mfrc522.uid.uidByte, mfrc522.uid.size);
  id->size = mfrc522.uid.size;
  id->sak = mfrc522.uid.sak;
}

bool cmpid(MFRC522::Uid *id1, MFRC522::Uid *id2){
  return memcmp(id1, id2, sizeof(MFRC522::Uid));
}

void deregister_card(){
  is_card_present = false;
  memset(&id,0, sizeof(id));
}

void finishfunct(uint8_t stag){
   Serial.println("CardRemoved");
   Serial.println(stag);
  delay(500); //change value if you want to read cards faster

  mfrc522.PICC_HaltA();
  mfrc522.PCD_StopCrypto1();  
}
uint8_t control = 0x00;
void loop() {

  MFRC522::MIFARE_Key key;
  for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF;
  MFRC522::StatusCode status;

  //-------------------------------------------

  // Look for new cards
  if ( !mfrc522.PICC_IsNewCardPresent()) {
    return;
  }
  if ( !mfrc522.PICC_ReadCardSerial()) {
    return;
  }
  //PrintHex(id.uidByte, id.size);
  //Serial.println("hello");
  bool result = true;
  uint8_t buf_len=4;
  cpid(&id);
  mfrc522.PICC_DumpDetailsToSerial(&(mfrc522.uid)); //dump some details about the card
  //START TRY THIS1
  unsigned int hex_num;
          hex_num =  mfrc522.uid.uidByte[0] << 24;
          hex_num += mfrc522.uid.uidByte[1] << 16;
          hex_num += mfrc522.uid.uidByte[2] <<  8;
          hex_num += mfrc522.uid.uidByte[3];

         int  NFC_id=  (int)hex_num;
         String strtwo =  String(NFC_id, HEX);
         strtwo.toUpperCase();
         Serial.println(strtwo);
  
  Serial.print("NewCard ");
  PrintHex(id.uidByte, id.size);
  Serial.println("");
  while(true){
    control=0;
    for(int i=0; i<3; i++){
      if(!mfrc522.PICC_IsNewCardPresent()){
        if(mfrc522.PICC_ReadCardSerial()){
//          Serial.print('a');
          control |= 0x16;
        }
        if(mfrc522.PICC_ReadCardSerial()){
//          Serial.print('b');
          control |= 0x16;
        }
//        Serial.print('c');
          control += 0x1;
      }
//      Serial.print('d');
      control += 0x4;
    }
    if(control == 13 || control == 14){
      delay(500);
      control = 0;
      } else {
      break;
    }
  }
  
finishfunct(control);
}

@chefslot
Copy link

chefslot commented May 1, 2018

Hi, i was trying to use the code with multiple rfid readers,to multiple mp3 players, which then would have used multiple switching rx tx serial depending on which reader was being activated. So it would have went like this, reader 0 or 1, then detect the uid, switch rxtx to CMD to mp3 player, play the mp3, whilst listening for the remove code, then switch back rxtx if the other reader needed to send CMD to the other mp3 etc etc, not impossible, (but was for me),, but in the end it was easier to use two nano's each having it's own reader and mp3 player. Later i had problems of once replacing the tag the mp3 player wouldn't replay, but in the end it was a problem of the mp3 player, needed to send a reset command to it.
I also used a shorter version of the code, not to sure if you needed it all, but it seemed to make no odds,

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

	#define RST_PIN         9           // Configurable, see typical pin layout above
	#define SS_PIN          10          // Configurable, see typical pin layout above
	
	MFRC522 mfrc522(SS_PIN, RST_PIN);   // Create MFRC522 instance
	
	//*****************************************************************************************//
	void setup() {
	  Serial.begin(9600);                                           // Initialize serial communications with the PC
	  SPI.begin();                                                  // Init SPI bus
	  mfrc522.PCD_Init();                                              // Init MFRC522 card
	}
	uint8_t control = 0x00;
	
	//*****************************************************************************************//
	
	
	
	void loop() {
	
	  // Look for new cards
	  if ( !mfrc522.PICC_IsNewCardPresent()) {
	    return;
	  }
	  if ( !mfrc522.PICC_ReadCardSerial()) {
	    return;
	  }

	  bool result = true;
	  uint8_t buf_len = 4;
	
	  Serial.println("NewCard ");
	  
	  while (true) {
	    control = 0;
	    for (int i = 0; i < 3; i++) {
	      if (!mfrc522.PICC_IsNewCardPresent()) {
	        if (mfrc522.PICC_ReadCardSerial()) {
	          //Serial.print('a');
	          control |= 0x16;
	        }
	        if (mfrc522.PICC_ReadCardSerial()) {
	          //Serial.print('b');
	          control |= 0x16;
	        }
	        //Serial.print('c');
	        control += 0x1;
	      }
	      //Serial.print('d');
	      control += 0x4;
	    }
	
	    Serial.println(control);
	    if (control == 13 || control == 14) {
	      //card is still there
	    } else {
	      break;
	    }
	  }
	  Serial.println("CardRemoved");
	  delay(500); //change value if you want to read cards faster
	
	  mfrc522.PICC_HaltA();
	  mfrc522.PCD_StopCrypto1();
	}
	//*****************************************************************************************//a
	 `

@joebhullar
Copy link

@chefslot are you trying to make a music jukebox? Was trying to understand your project.

@chefslot
Copy link

chefslot commented May 2, 2018

@joebhullar All most, a cooker top for my daughter. I embed a tag into one of her wooden saucepans, frying pans and a pot. The hob has the rfid card in it, which then plays the mp3 of water boiling or frying onions sort of sound. All ready have leds in the hob part, that are controlled by a dual pot (cooker hob knob) along with the mp3 vol. Hey just need to get 'essence of fried onion' in a aerosol then i could have hooked up a fabreeze device too!!

@TheNitek
Copy link

TheNitek commented May 4, 2018

Nice idea! You might want to look into my RfidShelf code: https://github.com/TheNitek/RfidShelf/blob/master/RfidShelf/RfidShelf.ino It plays music as long as a Rfid tag is present, so it is basically the same use case

@Martinukai
Copy link

Martinukai commented Jul 11, 2018

Dear @chefslot and @TheNitek. Thanks so much for sharing this code. I see that you both have implemented several (3) rechecks for the presence of a card. I have tried your code, @chefslot and it works great but strangely, for me at least, there is a long delay before "CardRemoved" is printed. Perhaps this is due to those checks? Would there be a workaround to make this a little quicker? I'm not fully aware of what those checks are doing, if I'm honest. So that's why I ask. Lol.

I am basically running a very simple system with no writing of cards, just playing music based on known card codes. Basically I'd like (if possible) for the music to stop very quickly once the card is taken away. Thanks in advance for any tips :)

Perhaps your code has less of a delay, @TheNitek. I have not tried it yet as I'm not sure how to extract the elements I need just yet ;)

@ss1969
Copy link

ss1969 commented Jul 17, 2018

@chefslot Your code logic seems not very understandable but works well. But after I added some authorize and read operations into it, the detection method fails by counter == 15. Any ideas on where to do auth/read/de-auth/halt operations in your sample?

@mpbejo
Copy link

mpbejo commented Oct 17, 2018

Hi everybody,
I have the same problem, the code works when I read only the UID Card. But when i add authentication to read a sector i can read, but it fail to detect if the card is still on the reader.
Somebody tried and find a solution?
Thank You Best Regards
Marco

@chefslot
Copy link

Can you not add a 'void read sector', so if card present, (if control = 13/present goto read sector(), if not do nothing) sort of thing. Been a little while since looking at this and i'm not good at programming any way lol.

@mpbejo
Copy link

mpbejo commented Oct 18, 2018

Hi, thank You chefslot for your answer. Your comment was partially correct.
Infact now I can check if the card i present or removed, but I have:

PCD_Authenticate() failed: Timeout in communication.
MIFARE_Read() failed: Timeout in communication.

With the same card if i use the ReadandWrite sample i don't have the Timeout error.
So I am stuck! with ReadandWrite sample I can read correctly the data in the sector, but if I want to read and to know if the badge is present I have the Timeout in communication.
Thi is my try:

#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 TagPresent = false;
////
void setup() {
Serial.begin(115200); // Initialize serial communications with the PC
SPI.begin(); // Init SPI bus
mfrc522.PCD_Init(); // Init MFRC522 card
// 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 PrintHex(uint8_t *data, uint8_t length) // prints 8-bit data in hex with leading zeroes
{
char tmp[16];
for (int i=0; i<length; i++) {
sprintf(tmp, "0x%.2X",data[i]);
Serial.print(tmp); Serial.print(" ");
}
}
uint8_t buf[10]= {};
MFRC522::Uid id;
MFRC522::Uid id2;
bool is_card_present = false;
//
//

void cpid(MFRC522::Uid *id){
memset(id, 0, sizeof(MFRC522::Uid));
memcpy(id->uidByte, mfrc522.uid.uidByte, mfrc522.uid.size);
id->size = mfrc522.uid.size;
id->sak = mfrc522.uid.sak;
}

bool cmpid(MFRC522::Uid *id1, MFRC522::Uid *id2){
return memcmp(id1, id2, sizeof(MFRC522::Uid));
}

void deregister_card(){
is_card_present = false;
memset(&id,0, sizeof(id));
}

void finishfunct(uint8_t stag){
Serial.println("CardRemoved");
Serial.println(stag);
delay(500); //change value if you want to read cards faster
mfrc522.PICC_HaltA();
mfrc522.PCD_StopCrypto1();
TagPresent = false;
}
uint8_t control = 0x00;
void loop() {
//-------------------------------------------

// Look for new cards
if ( !mfrc522.PICC_IsNewCardPresent()) {
return;
}
if ( !mfrc522.PICC_ReadCardSerial()) {
return;
}

while(true){
control=0;
for(int i=0; i<3; i++){
if(!mfrc522.PICC_IsNewCardPresent()){
if(mfrc522.PICC_ReadCardSerial()){
// Serial.print('a');
control |= 0x16;
}
if(mfrc522.PICC_ReadCardSerial()){
// Serial.print('b');
control |= 0x16;
}
// Serial.print('c');
control += 0x1;
}
// Serial.print('d');
control += 0x4;
}
//control =13;
if (control == 13 && TagPresent == false)
{
TagPresent = true;
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;
  MFRC522::StatusCode status;
  byte buffer[18];
  byte size = sizeof(buffer);

// Authenticate using key A
Serial.println(F("Authenticating using key A..."));

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));
}


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(":"));
dump_byte_array(buffer, 16); Serial.println();
Serial.println();

 // Halt PICC
mfrc522.PICC_HaltA();
// Stop encryption on PCD
mfrc522.PCD_StopCrypto1();
}
if(control == 13 || control == 14){
  delay(500);
  control = 0;
  } else {
  break;
}

}

finishfunct(control);
}
/**

  • 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);
    }
    }

I attached my scketch if You want to try.
If You comment for(int i=0; i<3; i++) cicle You will not have the Timeout error, but You cannot understand if the badge is removed.
Hope somebody can help me to find the problem
Thank You Best Regards
Marco

@chefslot
Copy link

chefslot commented Oct 19, 2018

I haven't got a reader on me at the moment. Can i ask what it is your trying to do?? Just that there might be a easier way around it.
I ran mine at 9600, might help? The timeout bit i believe when i was looking into it was to do with this bit

      mfrc522.PICC_HaltA();
      // Stop encryption on PCD
      mfrc522.PCD_StopCrypto1();

So if something is not in order maybe????

I also had a void checkcard (), so my program ran in sections, so in the loop it went like this

  //checkcard
  MFRC522::MIFARE_Key key;
  for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF;
  MFRC522::StatusCode status;
  //checkcard*/

  if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) {
    delay(30);
    // Show some details of the UID
    dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size);
    delay(30);
    //
    //delay(30);

  }
  else  {
    DO SOMETHING
    delay(30);
  }

then

void dump_byte_array

then


  MFRC522::MIFARE_Key key;
  for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF;
  MFRC522::StatusCode status;


  //PrintHex(id.uidByte, id.size);
  //Serial.println("hello");
  bool result = true;
  uint8_t buf_len = 4;

  Serial.print("NewCard ");

  Serial.println("");
  while (true) {
    control = 0;
    for (int i = 0; i < 3; i++) {
      if (!mfrc522.PICC_IsNewCardPresent()) {
        if (mfrc522.PICC_ReadCardSerial()) {
          //Serial.print('a');
          control |= 0x16;
        }
        if (mfrc522.PICC_ReadCardSerial()) {
          //Serial.print('b');
          control |= 0x16;
        }
        //Serial.print('c');
        control += 0x1;
      }
      //Serial.print('d');
      control += 0x4;
    }

    Serial.println(control);
    if (control == 13 || control == 14) {
      //card is still there

    } else {
      break;
    }
  }
  Serial.println("CardRemoved");
  delay(500); //change value if you want to read cards faster

  // Halt PICC
  mfrc522.PICC_HaltA();
  // Stop encryption on PCD
  mfrc522.PCD_StopCrypto1();

  VOIDSOMETHING();

Hope that makes sense??
Regards

@martinmolema
Copy link

After some tinkering around, I figured that the card is gone after a few consecutive successfull attempts to not see a card. So I use a counter that will only increase if the previous and current value is "I do not see a card".

Hope this helps somebody reading this thread :).

    bool cardRemoved = false;
    int counter = 0;
    bool current, previous;
    previous = !mfrc522.PICC_IsNewCardPresent();
    
    while(!cardRemoved){
      current =!mfrc522.PICC_IsNewCardPresent();

      if (current && previous) counter++;

      previous = current;
      cardRemoved = (counter>2);      
      delay(50);
      Serial.println("Waiting for card to disappear");
      Serial.println(counter);
    }

@uluzox
Copy link

uluzox commented May 23, 2019

I cleaned up the code a little bit and added @martinmolema 's more readable check to what @joebhullar posted earlier. Hope this helps someone:

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

#define RST_PIN 9           // Configurable, see typical pin layout above
#define SS_PIN 10          // Configurable, see typical pin layout above

MFRC522 mfrc522(SS_PIN, RST_PIN);   // Create MFRC522 instance

//*****************************************************************************************//
void setup() {
  Serial.begin(9600);                                           // Initialize serial communications with the PC
  SPI.begin();                                                  // Init SPI bus
  mfrc522.PCD_Init();                                              // Init MFRC522 card
}
/**
 * Helper routine to dump a byte array as hex values to 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);
  }
}

//*****************************************************************************************//

void loop() {

  // Look for new cards
  if ( !mfrc522.PICC_IsNewCardPresent()) {
    return;
  }
  if ( !mfrc522.PICC_ReadCardSerial()) {
    return;
  }
  
  //mfrc522.PICC_DumpDetailsToSerial(&(mfrc522.uid)); //dump some details about the card
  
  Serial.print("NewCard");
  PrintHex(mfrc522.uid.uidByte, mfrc522.uid.size);
  Serial.println("");

  // Check if Card was removed
  bool cardRemoved = false;
  int counter = 0;
  bool current, previous;
  previous = !mfrc522.PICC_IsNewCardPresent();
    
  while(!cardRemoved){
    current =!mfrc522.PICC_IsNewCardPresent();

    if (current && previous) counter++;

    previous = current;
    cardRemoved = (counter>2);      
    delay(50);
  }
  
  Serial.println("Card was removed");
  delay(500); //change value if you want to read cards faster
  mfrc522.PICC_HaltA();
  mfrc522.PCD_StopCrypto1();
}

UPDATE: I recommend using this code to detect card removal: #352 (comment)
If you need to read or write to the card add this to the bottom of your loop:
#352 (comment)

@ghost
Copy link

ghost commented Jan 14, 2021

Not sure, but i think this is what @jk987 was talking about. Works like a charm.

void checkPresent()
{
    MFRC522::StatusCode result;
    byte buffer[2];

    result = mfrc522.PICC_REQA_or_WUPA(mfrc522.PICC_CMD_WUPA, buffer, &buffer[2]);
    Serial.println("Presence state:");
    Serial.println(result, HEX);
    if (result == mfrc522.STATUS_OK)
    {
        Serial.println("Card is present!");
        if (mfrc522.PICC_ReadCardSerial())
        {
            for (byte i = 0; i < mfrc522.uid.size; i++)
            {
                Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
                Serial.print(mfrc522.uid.uidByte[i], HEX);
            }
        } 
    }
    else
    {
        Serial.println("Card is not present!");
    }
    mfrc522.PICC_HaltA();
}

joebhullar referenced this issue in joebhullar/MFRCDetectionOGUsed Oct 28, 2021
@Martin-Laclaustra
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests