Help With MFRC522 code - Trying to supress duplicate entries

Thanks to so many people @peekay123, @wgbartley, @kennethlimcp I’ve been able to get my Electron to do wonderful things with a MFRC522 module.

I wanted to add a bit of code to suppress duplicate reads being sent to the cloud, since a simple swipe can generate numerous entries, but now nothing is sent to the cloud. :frowning:

Here’s the current code: I took out big comment/attribution block only for this post.


#include "MFRC522/MFRC522.h"

#define SS_PIN A2
#define RST_PIN D2

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

String lastCardID = "";
String cardID = "";

void setup() {
    Serial.begin(57600);    // Initialize serial communications with the PC
    mfrc522.setSPIConfig();
    mfrc522.PCD_Init();    // Init MFRC522 card
    Serial.println("Scan PICC to see UID and type...");
    Particle.variable("cardID", cardID);
}

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

    // Select one of the cards
    if ( ! mfrc522.PICC_ReadCardSerial()) {
        return;
    }
    
    // Dump ID
    String cardID = "";
    for (byte i = 0; i < mfrc522.uid.size; i++)

    {
        cardID += mfrc522.uid.uidByte[i] < 0x10 ? "0" : " ";
        cardID += String(mfrc522.uid.uidByte[i], HEX);
    }
    
    // Prevent Multiple Scans
    if(cardID==lastCardID);
        return;

    lastCardID = cardID;    

    Serial.println(cardID);
    Particle.publish("Tag No.", cardID + " scanned", 60, PRIVATE);
    mfrc522.PICC_HaltA();
}
1 Like

I actually built an RFID door access system for a customer last week and was getting frustrated with multiple reads in a very short amount of time. I started doing it to compare the last card with the current card, but unless you set a timer to expire the last card, someone may not be able to gain access if they swiped their card again 5 minutes later. Instead, I set a 1-second lockout. You can hold your card there for as long as you want, but it will only take action on that card once per second. I had another reason for the timed lockout that was necessary in their particular scenario, but I don’t remember what it was now.

1 Like

I suggest you take a look at the publish limits as well.
https://docs.particle.io/reference/firmware/photon/#particle-publish-

1 Like

Thank you for the quick response!

I see what you mean. I think that’s what is happening with this edit. Is my thinking of just adding a delay(1000); totally dumb?

That’d most likely work for both things. For the publish limit though, you could choose to publish only if you’ve got a new card.

1 Like

There are limits? :open_mouth:

Be warned I am totally unqualified to engineer pancakes let alone code.

So, is this the TTL or am I clueless to what you mean?

Wow. The more I get into this stuff the more awesome I think all you, and the Particle, folks are. It totally makes sense it should only publish unique data. Here I was thinking making arrays in the eeprom (ot that I know what that is) to compare unique cardIDs. As usual totally overthinking the issue.

1 Like

Yup:

NOTE: Currently, a device can publish at rate of about 1 event/sec, with bursts of up to 4 allowed in 1 second. Back to back burst of 4 messages will take 4 seconds to recover.

With the loop running incredibly fast, you’re blowing through that instantly, thus getting slowed down until you get below the threshold, which never happens. Check the dashboard for the publishes, and you’ll most likely see 4 quickly after another, followed by ‘silence’(?)

1 Like

Depending on your reader, there may be an issue with a delay(1000);. For the reader I used, if I didn’t read the data it had available, it would lock up the reader and/or Photon due to some serial buffer backing up or something. Putting a long delay like that would prevent any available data from being drained out of the buffers and cause strange and wonderful things to happen.

As for the publish limits (from https://docs.particle.io/reference/firmware/photon/#particle-publish-):

NOTE: Currently, a device can publish at rate of about 1 event/sec, with bursts of up to 4 allowed in 1 second. Back to back burst of 4 messages will take 4 seconds to recover.

The way your code is above, I don’t think you’ll have to worry about delays and publish limits unless you can swipe a lot of cards really fast. If you want to reset the lastCardID after time has passed, just set it to an empty string. Then your line could read:

if(cardID==lastCardID && lastCardID.length()>0)
    return;

In your code posted above, there is a semi-colon after if(cardID==lastCardID). You’ll want to remove that so it will actually return. As it is right there, the if statement won’t actually do anything and will exit the loop preventing any code below it to ever be executed.

3 Likes

Story of my life! :smile:

I was going to mention this earlier (before I learned the true joys of Publish!) But the goal of my projects is to build a type of attendance kiosk to be used in an elementary school. If you can imagine 300 of these little monkey all swiping a tag within a 5-10 minute window it can get out of hand pretty quickly. I was thinking of adding some LEDs and sound prompts to confirm scans and slow them down a bit. But I fear they’ll be 10 kids trying to scan at one moment and bringing this thing to its knees.

I know. I can’t catch my own stray semi-colons (or lack thereof).

The LEDs and/or sound feedback will definitely slow them down. If anything, the timed lockout might be best. 1 per second, and it shouldn’t break anything.

I’m trying to see if I can open up parts of the code I wrote earlier this week, but I’m checking with the guy who actually paid for it to see if he’ll allow it.

2 Likes

This might be interesting as well:

Woop Woop! Thank you!

1 Like

Thanks! I saw that! And was awe inspired. Its going to take me a while to absorb whats all involved.

1 Like