RFID Card Reader - Previous card stays in memory?

Hi All

I am working an Arduino based RFID card reader project.

The core of the project is to read two different cards from one reader, return the IDs of the cards and then exit when 2 distinct cards are read. The system will have multiple readers eventually, so I am using a case switch in the main loop that waits for a command to tell it which reader to use (only 1 reader is defined and one instance of the reader created so far). Once that command is received a second function is then called and in this function we record the card IDs and then when 2 are found it exists the function and goes back to waiting for the switch to be triggered again.

The aforementioned second function sits within a loop, looking a variable called "Cardreadcycle". While this variable is less than 2, the function starts looking for a card. When a card is found, a variable called "CurrentCardId" is set too empty, then the card UID is stored into this variable. Once the full UID has been stored in the variable we then check if this UID is the same as the UID in another variable named "PreviousCardId". Provided it isn't we print the "CurrentCardId" to serial, copy it to the "PreviousCardId" variable and we up the "Cardreadcycle" and start the while loop again. Once a second disctinct card is found we print the new "CurrentCardId" to serial, and up the "Cardreadcycle", as a result of this now being 2, we exit the loop, print to serial confirmation of 2 unique cards being found and clear our variables "CurrentCardId" and "PreviousCardId", and go back to waiting for a command as to which reader to use.

The sketch does pretty much does exactly as it should, except for the fact that somewhere, it keeps seeming to store the previous card ID. When I trigger the next read of cards it immediately finds the 2nd card found in the previous scan and records it as the first card in the next loop. I have been over and over this and just cannot see why.

Please help me Arduino forum... you're my only hope!

Code in post below

* -----------------------------------------------------------------------------------------
 *             MFRC522      Arduino       Arduino   Arduino    Arduino          Arduino
 *             Reader/PCD   Uno/101       Mega      Nano v3    Leonardo/Micro   Pro Micro
 * Signal      Pin          Pin           Pin       Pin        Pin              Pin
 * -----------------------------------------------------------------------------------------
 * RST/Reset   RST          9             5         D9         RESET/ICSP-5     RST
 * SPI SS      SDA(SS)      10            53        D10        10               10
 * SPI MOSI    MOSI         11 / ICSP-4   51        D11        ICSP-4           16
 * SPI MISO    MISO         12 / ICSP-1   50        D12        ICSP-1           14
 * SPI SCK     SCK          13 / ICSP-3   52        D13        ICSP-3           15
 * 
 */

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

#define RST_PIN         9          // Configurable, see typical pin layout above
#define SS_PIN          10         // Configurable, see typical pin layout above


  String PreviousCardId;
  String CurrentCardId;
  int ReaderId;
  int MaxNoCards;


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

/**
 * Initialize.
 */
void setup() {
  Serial.begin(9600);   // Initialize serial communications with the PC
  while (!Serial);    // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
  SPI.begin();      // Init SPI bus
  mfrc522.PCD_Init();   // Init MFRC522
  mfrc522.PCD_DumpVersionToSerial();  // Show details of PCD - MFRC522 Card Reader details
  Serial.println("Please choose an option:");
  MaxNoCards = 2;
}

void loop() {
  // read the sensor:
  if (Serial.available() > 0) {
    int inByte = Serial.read();
    // do something different depending on the character received.
    // The switch statement expects single number values for each case;
    // in this exmaple, though, you're using single quotes to tell
    // the controller to get the ASCII value for the character.  For
    // example 'a' = 97, 'b' = 98, and so forth:

    switch (inByte) {
      case '1':
        Serial.println("Scanning Cards on Reader 1... Function will remain open until two unique cards are found!");
        ReaderId = 1;
        CardScan();
      break;
      case '2':
        Serial.println("Scanning Cards on Reader 2... Function will remain open until two unique cards are found!");
        ReaderId = 2;
        CardScan();
      break;
      default:
      Serial.println("No option selected");
      break;
    }
  }
}

void CardScan() {

  int Cardreadcycle = 0;
   while (Cardreadcycle < MaxNoCards){
      // Look for new cards
  if ( ! mfrc522.PICC_IsNewCardPresent()) {
     }
    // Select one of the cards
  if ( ! mfrc522.PICC_ReadCardSerial()) {
     }
    CurrentCardId = "";
    for (int i = 0; i < mfrc522.uid.size; i++) {  // 
    CurrentCardId = CurrentCardId + mfrc522.uid.uidByte[i];
    }
    if (CurrentCardId != PreviousCardId)
      {
      Cardreadcycle++;
       Serial.print("*");
       Serial.print(ReaderId);
       Serial.print("^");
       Serial.print(Cardreadcycle);
       Serial.print("|");
       Serial.println(CurrentCardId);
       PreviousCardId = CurrentCardId;
      }      
    mfrc522.PICC_HaltA(); // Stop reading
  }
  Serial.println("Two cards have been read, function closed");
  CurrentCardId = "";
  PreviousCardId = "";
  mfrc522.PICC_HaltA(); // Stop reading
}

I can't find the error, either. I have a similar project on a NodeMcu, but your code gives me a WDT crash one second after entering "1" or "2". This is because the cardScan function is a blocking function. In general you don't want blocking code.

I would separate the cardscan from the logic that follows.

Here is the loop function from my project. Maybe it will help.

//============================= Loop =============================
void loop() {


  // Look for new cards
  if ( ! rfid.PICC_IsNewCardPresent())
    return;

  // Verify if the NUID has been read
  if ( ! rfid.PICC_ReadCardSerial())
    return;

  MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);
  Serial.println(rfid.PICC_GetTypeName(piccType));

  // Check is the PICC of Classic MIFARE type
  if (piccType != MFRC522::PICC_TYPE_MIFARE_MINI &&
      piccType != MFRC522::PICC_TYPE_MIFARE_1K &&
      piccType != MFRC522::PICC_TYPE_MIFARE_4K) {
    Serial.println(F("Your tag is not of type MIFARE Classic."));
    return;
  }


  // A new card has been detected.

  cardId = 0;

  // Store NUID into nuidPICC array
  for (byte i = 0; i < 4; i++) {
    nuidPICC[i] = rfid.uid.uidByte[i];
    cardId = cardId + nuidPICC[i];            //Make the card ID
  }


  char buf [6];
  sprintf (buf, "%04i", cardId);
  client.publish(msgTopic, buf);
  Serial.println(buf);


  Serial.print(F("cardId= "));
  Serial.print(cardId);
  Serial.println();



  // Halt PICC
  rfid.PICC_HaltA();

  // Stop encryption on PCD
  rfid.PCD_StopCrypto1();

  delay(450);                            // Prevents accidental duplicate reads

}

Hope this helps.