{HELP} How to stop RFID tags from reading multiple times

Hi All,

I am new to arduino, I am creating a visitor counter using arduino Uno, mfrc522 reader and some rfid keychain tags that I got from amazon.

My question is how do I stop an rfid tag from reading multiple times, for eg. whenever a visitor scans his/her card the reader will increase the visitor count, but when the same visitor scans the card by mistake it again increases the count, so how I do stop the rfid reader from counting the same tag multiple times.

here is the code that I got online and using for my project, can you guys help me with it please;

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

//creating mfrc522 instance

#define RSTPIN 9
#define SSPIN 10
#define BUTTON 7
MFRC522 mfrc(SSPIN, RSTPIN);
LiquidCrystal lcd(A0, A1, A2, A3, A4, A5);

int readsuccess;
/* the following are the UIDs of the card which are authorised
to know the UID of your card/tag use the example code ‘DumpInfo’
from the library mfrc522 it give the UID of the card as well as
other information in the card on the serial monitor of the arduino*/

//byte defcard[4]={0x32,0xD7,0x0F,0x2B}; // if you only want one card
byte defcard[4]={{0x66,0x59,0x77,0x76},{0x75,0x93,0x81,0x63}}; //for multiple cards
int N=2; //change this to the number of cards/tags you will use
byte readcard[4]; //stores the UID of current tag which is read
int count = 0; // counter set to 0

void setup() {
Serial.begin(9600);
lcd.begin(16, 2);
lcd.setCursor(0, 0);
lcd.print(" VISITOR COUNTER");
SPI.begin();
mfrc.PCD_Init(); // Init MFRC522
mfrc.PCD_SetAntennaGain(mfrc.RxGain_max);
mfrc.PCD_DumpVersionToSerial(); //show details of card reader module
delay(2000);
lcd.clear();
lcd.print(“Start Scanning”);
pinMode(6,OUTPUT); //led for authorised
pinMode(5,OUTPUT); //led for not authorised
pinMode(7,OUTPUT); //push button for rest counter
/*
Serial.println(F(“the authorised cards are”)); //display authorised cards just to demonstrate you may comment this section out
for(int i=0;i<N;i++){
Serial.print(i+1);
Serial.print(" ");
for(int j=0;j<4;j++){
Serial.print(defcard*[j],HEX);*

  • }*
  • Serial.println("");*
  • }*
    Serial.println("");
    */
    Serial.println(F(“Scan Access Card to see Details”));
    /* { //check this section…it gets displayed first…should be displayed only when button is pressed
  • if (digitalRead(BUTTON) == LOW)*
  • count=0;*
  • lcd.setCursor(0, 0);*
  • lcd.print(" COUNTER HAS ");*
  • lcd.setCursor(0, 1);*
  • lcd.print(“BEEN RESET”);*
    _ }*/_
    }
    void loop() {

readsuccess = getid();
if(readsuccess){

  • int match=0;*
    //this is the part where compare the current tag with pre defined tags
  • for(int i=0;i<N;i++){*
  • Serial.print("Testing Against Authorised card no: ");*
  • Serial.println(i+1);*
    _ if(!memcmp(readcard,defcard*,4)){_
    _
    match++;_
    _
    }*_

* }*
* int card_status = 0; //0:readable; 1:not-readable*
if ( (Serial.available() > 0) && (card_status == 0) ) {
* card_status = 1; //disable to read card after exit this loop*
* //your code, a card is near to the antenna, try to read it.*
* readVal = Serial.read();*
* if (readVal == 2) {*
* counter = 0; // start reading*
* } else if (readVal == 3) {*
* processTag();*
* clearSerial();*
* counter = -1;*
* } else if (counter >= 0) {*
* readData[counter] = readVal;*
* ++counter;*
* }*
}

* if(match)*
* {Serial.println(“CARD AUTHORISED”);*
* digitalWrite(6,HIGH);*
* delay(500);*
* digitalWrite(6,LOW);*
* count++; //inrease the count*
* lcd.setCursor(0, 0);*
* lcd.print(" NUMBER OF VISITORS ");*
* lcd.setCursor(0, 1);*
* lcd.print(count);*
* delay(200);*

* }*
* else {*
* Serial.println(“CARD NOT Authorised”);*
* digitalWrite(5,HIGH);*
* lcd.setCursor(0, 0);*
* lcd.print(“VISITOR NOT LISTED”);*
* delay(2000);*
* digitalWrite(5,LOW);*
* lcd.clear();*
* delay(500);*

* }*

* }*
}
//function to get the UID of the card
*int getid(){ *
* if(!mfrc.PICC_IsNewCardPresent()){
_
return 0;_
_
}_
if(!mfrc.PICC_ReadCardSerial()){
_
return 0;_
_
}*_

* Serial.println(“THE UID OF THE SCANNED CARD IS:”);*

* for(int i=0;i<4;i++){*
readcard_=mfrc.uid.uidByte*; //storing the UID of the tag in readcard*
Serial.print(readcard*,HEX);*_

* }*
* Serial.println("");*
* Serial.println(“Now Comparing with Authorised cards”);*
* mfrc.PICC_HaltA();*

* return 1;*
}

whenever a visitor scans his/her card the reader will increase the visitor count

but when the same visitor scans the card by mistake it again increases the count,

You can't really have one without the other.

What you can do, however, is to save the time from millis() when the card was scanned and the count incremented and ignore the same card for a period which you will need to decide.

With respect, I don’t think that solves the problem that many folk rediscover with the simple RDM6300 tag reader, which spouts a continuous stream of data while a card is present. So in case this helps anyone, even though this thread is a year old…

Serial.read() accepts one byte at a time. My solution was to look for the start byte of the ID, collect the expected 13 bytes and check the end byte, then go into a pause loop in which I’m draining the serial buffer continuously (i.e. reading bytes without putting the data anywhere). The pause loop looks like this:

unsigned long timeNow = 0; // Stores time on entering pause, initialised at 0
.
.
.
// Pause before reading again, to avoid too many records of same tag.  Keep draining serial buffer.
               timeNow = millis();
               while (millis() - timeNow < 1500) 
                  {
                    if (Serial.available()) 
                      {
                      Serial.read();
                      }
                  }

Works for me, and much simpler than other solutions I’ve seen. You could increase the time spent in the loop if you are getting huge numbers of duplicate reads, but I find this ample.

With respect, I don't think that solves the problem

Why does it not solve the problem ? It prevents multiple reads of the same card for as long as you like whilst retaining the ability to read a different card if it is presented

then go into a pause loop

In other words do absolutely nothing but read from serial for a while. You may have solved a problem but created another one in its place

In a real-world situation of presenting RFID cards to a reader, doing nothing for 1.5 seconds can rarely be a problem. Barriers at UK railway stations, for example, seem to have a very similar 'blind' period, and yet crowds of commuters pass through them every rush-hour.

The OP didn't want multiple reads to increase his visitor count, so multiple reads were a significant problem for him. These RFID readers can make a dozen or more reads quicker than you can snatch the card away.

In my context (animal tags) the animal isn't even trying to make a single clean record, and duplicate reads within 1.5 seconds occupy logger memory space with no benefit.

In a real-world situation of presenting RFID cards to a reader, doing nothing for 1.5 seconds can rarely be a problem.

Unless, of course, the Arduino is doing something else like monitoring more than one RFID reader or other inputs. Better to use a robust solution rather than a clumsy one.

The OP didn't want multiple reads to increase his visitor count, so multiple reads were a significant problem for him.

Which is why I proposed the solution that I did

Unless, of course, the Arduino is doing something else like monitoring more than one RFID reader or other inputs. Better to use a robust solution rather than a clumsy one.

The OP didn't say that he was monitoring multiple inputs. Which is why I proposed the solution that I did. C'est brutal, mais ce marche.

Actually, in the context given, it's not crude (or clumsy), and it is robust. Why process data you don't actually need?

BTW, I didn't see any need for your arrogant tone.

I didn't see any need for your arrogant tone

So you don't think that your incorrect statement

I don't think that solves the problem that many folk rediscover with the simple RDM6300 tag reader,

was arrogant ?

My opening words 'With respect...' acknowledged that I am a mere novice - but I thought you had mis-read the problem that many of us have encountered with that reader. It's not an issue of disallowing re-presentation of the same ID, but of thinning down too much data from each presentation. There are many threads on this - this was the most recent I could find.

I simply wanted to help future newbs by posting a simple solution that works for me, would have worked for the OP, and arguably many other contexts too. If it had ever been suggested to me it would have saved me a lot of time. It may not be sophisticated, but it dodges the need for a directory of recently-read IDs, which for someone of limited programming ability (e.g. me) requires appreciably more time.

Those reading this thread later can choose either solution, and I'm quite relaxed if they choose to ignore mine. :slight_smile:

Those reading this thread later can choose either solution, and I'm quite relaxed if they choose to ignore mine

Those reading this thread later can choose either solution, and I'm quite relaxed if they choose to ignore mine :slight_smile: