Measure how much time an NFC tag stays on RC522

92 Views Asked by At

I'm trying to measure of much time does a specific NFC tag stays on the RC522 reader through an ESP32. I'm using MFRC522.h library to use the RFID module, but I don't know what some functions do as it's not very well documented... I've tried different approaches, but I always end up with the same result. The wires are connected correctly, as dumping the info show the right info.

Code:

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

#define SS_PIN 5    // ESP32 pin GPIO5
#define RST_PIN 27  // ESP32 pin GPIO27

MFRC522 rfid(SS_PIN, RST_PIN);

unsigned long timeStart = 0;
unsigned long timeEnd = 0;
bool tagPresent = false;


void setup() {
  Serial.begin(9600);
  SPI.begin();      // init SPI bus
  rfid.PCD_Init();  // init MFRC522
  Serial.println("Use an RFID tag");
}

void loop() {
  if (rfid.PICC_IsNewCardPresent() && rfid.PICC_ReadCardSerial()) {
    if (!tagPresent) {  // if tagPresent = false, then the tag has just "arrived"
      tagPresent = true;
      timeStart = millis();
    }

    // Removing the next 2 function calls doesn't solve the problem but 
    // it seems to halve the time read in the duration variable

    rfid.PICC_HaltA();  
    rfid.PCD_StopCrypto1();

  } else {
    if (tagPresent) {  //at some point there was a tag, but it's gone now
      Serial.print("\n");
      timeEnd = millis();
      unsigned long duration = timeEnd - timeStart;
      Serial.print("Tag NFC stayed for ");
      Serial.print(duration);
      Serial.println(" ms");
      // noted the last tag's time, reset
      tagPresent = false;
    }
  }
}

Output:

    Tag NFC stayed for 51 ms
    Tag NFC stayed for 51 ms    
    Tag NFC stayed for 51 ms    
    Tag NFC stayed for 51 ms    
    ...

If I put the tag on the reader it immediatly pops out a line of the output and nothing else for as much as I leave the tag there. If I repeatedly lift and lower the tag towards the reader I get multiple prints like in the output above.

Instead I need that if I leave the tag for 10 seconds, and then remove it, to print "Tag NFC stayed for 10000 ms".

2

There are 2 best solutions below

0
Arzo On BEST ANSWER

After studying more accurately the ISO documentation and the library files I managed to solve this by using a WakeUp Call which brings the PICC to the state READY*, which allows to be seen as a "new" tag again.

I placed MFRC522::StatusCode status = rfid.PICC_WakeupA(bufferATQA, &bufferSize); at the beginning of loop(), and called the function again after passing the IsNewCardPresent() and ReadCardSerial() check, and also a the end of loop(). Not sure why, but if I try to remove even one of the three calls, it doesn't work.

void loop() {
  MFRC522::StatusCode status = rfid.PICC_WakeupA(bufferATQA, &bufferSize);
  //Serial.print("Before check, status - ");
  //Serial.println(status, DEC);


  if (rfid.PICC_IsNewCardPresent() && rfid.PICC_ReadCardSerial()) {
    status = rfid.PICC_WakeupA(bufferATQA, &bufferSize);
    //Serial.print("Inside IF, status - ");
    //Serial.println(status, DEC);
        
    if (!tagPresent) {  // if tagPresent = false, then the tag has just "arrived"
      tagPresent = true;
      timeStart = millis();
      Serial.println("Tag NFC RILEVATO!");
    }

  } else {
    if (tagPresent) {  //at some point there was a tag, but it's gone now
      Serial.print("\n");
      timeEnd = millis();
      unsigned long duration = timeEnd - timeStart;
      Serial.print("Tag NFC stayed for ");
      Serial.print(duration);
      Serial.println(" ms");
     //  noted the last tag's time, reset
      tagPresent = false;
    }
  }
  status = rfid.PICC_WakeupA(bufferATQA, &bufferSize);
  //Serial.print("End, status - ");
  //Serial.println(status, DEC);
}
3
Andrew On

Your logic seems wrong and this might be the cause of the problem.

In your loop you check PICC_IsNewCardPresent as the name suggests this issues a ISO 14443-3 command and changes the state of the Tag.

On the first iteration of the loop it will return true then when you call this again in the second iteration of the loop this will return false. This is because the Tag is still present is not a new Tag and is not in the state of a new Tag.

Thus your loop will only every iterate once before giving you a time.

I don't program with the RC522 but for NFC interactions the following re-write of your code logic might work

void loop() {
  if (!tagPresent) {
    // Check if a new Tag is presented
    if (rfid.PICC_IsNewCardPresent()) {
      tagPresent == true;
      timeStart = millis();
    }
  } else {
    // Check the Tag is still present
    if (!rfid.PICC_ReadCardSerial()) {
      // A ready Tag is longer present as UID read has failed
      Serial.print("\n");
      timeEnd = millis();
      unsigned long duration = timeEnd - timeStart;
      Serial.print("Tag NFC stayed for ");
      Serial.print(duration);
      Serial.println(" ms");
      // noted the last tag's time, reset
      tagPresent = false;
    }
  }
}