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