Problem using MFRC522 - Data from previous card stays saved

Hi everyone,

I’m trying to read out the data from two datablocks in MIFARE Classic 1k NFC cards. Everything is working as it should until the next card that I read has less bytes saved in the data blocks than the last one.

Using “status = mfrc522.MIFARE_Read(block, tempArray, &byteCount);” I’m saving the bytes in “tempArray” and from “tempArray” I’m copying some elements in another array called “asciiArray”.

What happens is if the data from the first card looks like e.g. “x, x, x, x” and the data from the second card is e.g. “y, y, y” I will get “y, y, y, x” in my “asciiArray” rather that just “y, y, y”. The fourth byte from the previous card stays somewhere in the memory. If I scan my second card again, I get the right data, i.e. “y, y, y”. I tried emptying the arrays but it didn’t work. This last unwanted byte comes from “MIFARE_Read” function as it seems.

My code has 1500 lines so I will copy the important parts.

Setup lines of code:

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

#define NR_KNOWN_KEYS   8

MFRC522 mfrc522(SS_PIN, RST_PIN);

byte knownKeys[NR_KNOWN_KEYS][MFRC522::MF_KEY_SIZE] =  {
  {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, // FF FF FF FF FF FF = factory default
  {0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5}, // A0 A1 A2 A3 A4 A5
  {0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5}, // B0 B1 B2 B3 B4 B5
  {0x4d, 0x3a, 0x99, 0xc3, 0x51, 0xdd}, // 4D 3A 99 C3 51 DD
  {0x1a, 0x98, 0x2c, 0x7e, 0x45, 0x9a}, // 1A 98 2C 7E 45 9A
  {0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7}, // D3 F7 D3 F7 D3 F7
  {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}, // AA BB CC DD EE FF
  {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}  // 00 00 00 00 00 00
};

  char asciiArray[1000];

void setup() {

  SPI.begin();
  mfrc522.PCD_Init();
  mfrc522.PCD_SetAntennaGain(mfrc522.RxGain_max);

}

From void loop I’m calling the function rfid() as following:

if (mfrc522.PICC_IsNewCardPresent()) {
    rfid();
  }

In rfid() I’m trying to access the card using the list of common keys:

void rfid() {

  MFRC522::MIFARE_Key key;
  for (byte k = 0; k < NR_KNOWN_KEYS; k++) {
    // Copy the known key into the MIFARE_Key structure
    for (byte i = 0; i < MFRC522::MF_KEY_SIZE; i++) {
      key.keyByte[i] = knownKeys[k][i];
    }
    // Try the key
    if (try_key(&key)) {
      // Found and reported on the key and block,
      // no need to try other keys for this PICC
      break;
    }

    // http://arduino.stackexchange.com/a/14316
    if ( ! mfrc522.PICC_IsNewCardPresent())
      break;
    if ( ! mfrc522.PICC_ReadCardSerial())
      break;
  }

}

After that, I do the reading in the try_key() function from the data blocks 4 and 5:

bool try_key(MFRC522::MIFARE_Key *key)
{
  bool result = false;
  for (int j = 4; j < 6; j++) {
    byte tempArray[18] = {0};
    byte block = j;
    MFRC522::StatusCode status;

    // Serial.println(F("Authenticating using key A..."));
    status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, block, key, &(mfrc522.uid));
    if (status != MFRC522::STATUS_OK) {
      // Serial.print(F("PCD_Authenticate() failed: "));
      // Serial.println(mfrc522.GetStatusCodeName(status));
      return false;
    }
    // Read block

    byte byteCount = sizeof(tempArray);

    status = mfrc522.MIFARE_Read(block, tempArray, &byteCount);
    if (status != MFRC522::STATUS_OK) {
      // Serial.print(F("MIFARE_Read() failed: "));
      // Serial.println(mfrc522.GetStatusCodeName(status));
    }
    else {
      // Successful read
      result = true;
      if (j == 4) {
        for (byte i = 11; i < 16; ++i) {
          if (tempArray[i] != 254) {
            // Serial.print(char(buffer[i]));
            asciiArray[i - 11] = char(tempArray[i]);
          }
        }
      } else {
        for (byte i = 0; i < 16; ++i) {
          if (tempArray[i] != 254) {
            // Serial.print(char(buffer[i]));
            asciiArray[i + 5] = char(tempArray[i]);
          }
        }
      }
    }
  }
  // Serial.println();
  mfrc522.PICC_HaltA();       // Halt PICC
  mfrc522.PCD_StopCrypto1();  // Stop encryption on PCD
  scanFinished();
  return result;
}

I tried resetting the MRFC522 and that didn’t work either. Only thing that works is if I reset everything over reset button or, as mentioned, scan the second card two times.

Thanks in advance :slight_smile:

David

My code has 1500 lines so I will copy the important parts.

In most cases we read such sentences the error is in that part of the code people are hiding from us. From what I've seen in a quick view of your excerpts the same is true for your case.

Post complete code! If it's too big to be posted inline, attach it to the post.

Sorry, here is the code.

esdcontrolv060_mega.ino (42 KB)

You fill half of your RAM with global variables, most of them are string constants. Learn to use the F() macro! Although the Mega2560 has 8kB of RAM you don't have to waste it that way.

Don't use the String class on AVR Arduinos! If fragments the memory in no time and once you the system cannot allocate enough space anymore the results are unpredictable.

Do you really need to allocate 1000 bytes in your asciiArray? For the current sketch a size of about 20 bytes should be sufficient.

You don't terminate the string you copy to asciiArray. C-strings must be null-byte terminated.