2
votes

I just got hold of the RC522 RFID card for arduino and am working with the supplied sketch. MiFare RFID-RC522

What I am stuck on is understanding how pause the sketch while the card is being read so it is only read once. At the moment while the card is connected to the RDIF reader the sketch will keep looping and read the card each time.

There is a delay that can be set but will eventually read the card again if it is connected longer than the delay.

What I would like is to be able to say while there is a card connection, read the card ID only once then continue the sketch when the card connection is broken.

This is the main sketch segment:

    void loop()
{

    uchar status;
    uchar str[MAX_LEN];


    // Search card, return card types
    status = MFRC522_Request(PICC_REQIDL, str);
    if (status != MI_OK)
    {
        return;
    }


    // Show card type
    ShowCardType(str);

    //Prevent conflict, return the 4 bytes Serial number of the card
    status = MFRC522_Anticoll(str);

    // str[0..3]: serial number of the card
    // str[4]: XOR checksum of the SN.
    if (status == MI_OK)
    {
        Serial.print("The card's number is: ");
        memcpy(serNum, str, 5);
        ShowCardID(serNum);

        // Check people associated with card ID
        uchar* id = serNum;
        if (id[0] == 0x4B && id[1] == 0xE6 && id[2] == 0xD1 && id[3] == 0x3B) {
            Serial.println("Hello Mary!");
        }
        else if (id[0] == 0x3B && id[1] == 0xE6 && id[2] == 0xD1 && id[3] == 0x3B) {
            Serial.println("Hello Greg!");
        }
        else{
            Serial.println("Hello unkown guy!");
        }
    }


    MFRC522_Halt(); //command the card into sleep mode 

    delay(2000);
}

Thanks Guys.

2

2 Answers

1
votes

I was able to work this one out by looking at the return values from MFRC522_Request(PICC_REQIDL, str).

I created RFID_status as an int and also created RFID_read as an int and set to 0.

I then used RFID_status to test to see if there was an active card connection. If yes and RFID_read was still 0 then read the card and set RFID_read to 1. That way in the next loop the card will not be read.

Once the the card is taken away RFID_status will read as 0 (No connection) and RFID_read will be set back to 0.

    int RFID_status;
    int RFID_read = 0;    

    void loop()
{

    uchar status;
    uchar str[MAX_LEN];


    // Search card, return card types
    RFID_status = MFRC522_Request(PICC_REQIDL, str);
    if (RFID_status != 1)
    {

         RFID_read 0;

    }


    // Show card type
    ShowCardType(str);

    //Prevent conflict, return the 4 bytes Serial number of the card
    status = MFRC522_Anticoll(str);

    // str[0..3]: serial number of the card
    // str[4]: XOR checksum of the SN.
    if (RFID_status == 1 && RFID_read == 0)
    {
        Serial.print("The card's number is: ");
        memcpy(serNum, str, 5);
        ShowCardID(serNum);
        RFID_read = 1;

        // Check people associated with card ID
        uchar* id = serNum;
        if (id[0] == 0x4B && id[1] == 0xE6 && id[2] == 0xD1 && id[3] == 0x3B) {
            Serial.println("Hello Mary!");
            RFID_read = 1;
        }
        else if (id[0] == 0x3B && id[1] == 0xE6 && id[2] == 0xD1 && id[3] == 0x3B) {
            Serial.println("Hello Greg!");
            RFID_read = 1;
        }
        else{
            Serial.println("Hello unkown guy!");
            RFID_read = 1;
        }
    }


    MFRC522_Halt(); //command the card into sleep mode 

    delay(2000);
}

NB: There is a lot of code in this sketch that I have taken out. I have only included the void loop and the two global variables that I created. The original sketch can be found here: MiFare RFID-RC522 Sketch

1
votes

I did it like this:

// RFID Includes
#include <SPI.h>
#include <MFRC522.h>

// RFID Defines
#define RST_PIN    9
#define SS_PIN    10

const int NO_CARD_DETECTIONS_BEFORE_NEW_READ = 40;

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

int noCardCount = 0;

void setup() {
  // This is for Trinket 5V 16MHz
  #if defined (__AVR_ATtiny85__)
    if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
  #endif
  // End of trinket special code

  Serial.begin(9600); // Initialize serial communications with the PC
  while (!Serial); // Do nothing if no serial port is opened (needed for Arduinos based on ATMEGA32U4)
  SPI.begin(); // Init SPI bus
  mfrc522.PCD_Init(); // Init MFRC522
  Serial.println("Waiting for RFID-chip...");
}

void loop() {
  Serial.println(noCardCount);
  if (mfrc522.PICC_IsNewCardPresent()) {
    if(noCardCount > NO_CARD_DETECTIONS_BEFORE_NEW_READ){
      Serial.println("Card present!");
      //mfrc522.PICC_ReadCardSerial();
      //mfrc522.PICC_HaltA();
    }
    noCardCount = 0;
  }else{ // not present
    noCardCount++;
  }
}

Basically I’m just counting how often there is no card in a row, when the card lies on the reader, noCardCount will stay low. Only if a lot of times in a row no card has been detected, it will read again.