How to read bytes from a RFID card and convert them into an integer

I prepared two example sketches both based on this tutorial

https://devcraze.com/tutorials/arduino/mfrc522-rfid-read-and-write-data-in-specific-rfid-block/

One sketch

  • to write a couple of characters to block 4 and integers to block 5 of a card

and the second one

  • to read the data from both blocks again.

Write example:

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

// For MEGA 
#define RST_PIN 5
#define SS_PIN 53

/* For UNO
#define RST_PIN 9                  // Configurable, see typical pin layout above
#define SS_PIN 10                  // Configurable, see typical pin layout above
*/
MFRC522 mfrc522(SS_PIN, RST_PIN);  // Create MFRC522 instance
MFRC522::MIFARE_Key key;
MFRC522::StatusCode status;


enum States { WAITFORCARD,
             READCARD,
             WRITECARD };
States state = WAITFORCARD;

void setup() {
 Serial.begin(115200);  // Initialize serial communications with the PC
 SPI.begin();           // Init SPI bus
 mfrc522.PCD_Init();    // Init MFRC522 card
 Serial.println(F("Write data on a MIFARE PICC "));
}

void loop() {
 switch (state) {
   case WAITFORCARD:
     if (newCardFound()) {
       state = READCARD;
     }
     break;
   case READCARD:
     if (cardReadSuccessfully()) {
       state = WRITECARD;
     } else {
       Serial.println(F("Card could not be read!"));
       state = WAITFORCARD;
     }
     break;
   case WRITECARD:
     writeToBlockNoBytes(4);
     writeToBlockNoIntegers(5);
     // Further write functions can be placed here
     finalizeWriting();
     Serial.println(F("Present next card please"));
     state = WAITFORCARD;
     break;
 }
}

void finalizeWriting() {
 mfrc522.PICC_HaltA();
 mfrc522.PCD_StopCrypto1();
}

boolean newCardFound() {
 return mfrc522.PICC_IsNewCardPresent();
}

boolean cardReadSuccessfully() {
 return mfrc522.PICC_ReadCardSerial();
}

void writeToBlockNoBytes(byte block) {
 Serial.setTimeout(20000L);
 byte buffr[] = { 0x30, 0x31, 0x32, 0x33,
                  0x34, 0x35, 0x36, 0x37,
                  0x38, 0x39, 0x41, 0x42,
                  0x20, 0x20, 0x20, 0x20 };
 writeBytesToBlock(block, buffr);
 Serial.println(" ");
}

void writeToBlockNoIntegers(byte block) {
 Serial.setTimeout(20000L);
 int buffI[] = { -32768, -1000, -255, -1,
                 0, 255, 1000, 32767 };
 byte buffr[16];
 for (byte i=0;i<8;i++){
   buffr[i*2]   = buffI[i] & 0xFF;
   buffr[i*2+1] = buffI[i] >> 8;
 }
 writeBytesToBlock(block, buffr);
 Serial.println(" ");
}


void prepareKey() {
 // Prepare key - all keys are set to FFFFFFFFFFFFh at chip delivery from the factory.
 for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF;
}

void writeBytesToBlock(byte block, byte buff[]) {
 prepareKey();
 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;
 } else Serial.println(F("PCD_Authenticate() success: "));
 // Write block
 status = mfrc522.MIFARE_Write(block, buff, 16);
 if (status != MFRC522::STATUS_OK) {
   Serial.print(F("MIFARE_Write() failed: "));
   Serial.println(mfrc522.GetStatusCodeName(status));
   return;
 } else Serial.println(F("MIFARE_Write() success: "));
}

Read example:

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

// For MEGA 2560
#define RST_PIN 5
#define SS_PIN 53
/*
// For UNO
#define RST_PIN 9                  // Configurable, see typical pin layout above
#define SS_PIN 10                  // Configurable, see typical pin layout above
*/

MFRC522 mfrc522(SS_PIN, RST_PIN);  // Create MFRC522 instance
MFRC522::MIFARE_Key key;
MFRC522::StatusCode status;

enum States {WAITFORCARD, READCARD, READANDPRINTDATA};
States state = WAITFORCARD;

//*****************************************************************************************//
void setup() {
  Serial.begin(115200);                               // Initialize serial communications with the PC
  SPI.begin();                                        // Init SPI bus
  mfrc522.PCD_Init();                                 // Init MFRC522 card
  Serial.print(F("Read block no. 4 (characters) and 5 (integers) "));
  Serial.println(F(" on a MIFARE PICC:"));  //shows in serial that it is ready to read
}
//*****************************************************************************************//
void loop() {
  switch(state){
    case WAITFORCARD:
       if (newCardDetected()){
         state = READCARD;
       }
      break;
     case READCARD :
         if (cardReadSuccessfully()) {
             state = READANDPRINTDATA;
         } else {
             Serial.println(F("Card could not be read!"));
             state = WAITFORCARD;
         }
      break;
    case READANDPRINTDATA:
        readAndPrintCharactersFromBlockNo(4);
        readAndPrintIntegersFromBlockNo(5);
        finalizeReading();
        state = WAITFORCARD;
        Serial.println(F("Present new card please"));
      break;


  }
}

void finalizeReading(){
  mfrc522.PICC_HaltA();
  mfrc522.PCD_StopCrypto1();
}

boolean newCardDetected(){
   return mfrc522.PICC_IsNewCardPresent();
  }

boolean cardReadSuccessfully(){
  return mfrc522.PICC_ReadCardSerial();
  }

void prepareKey() {
  // Prepare key - all keys are set to FFFFFFFFFFFFh at chip delivery from the factory.
  for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF;
}

void readAndPrintCharactersFromBlockNo(byte block) {
  Serial.println(F("**Card Detected:**"));
  byte buffer1[18];
  byte len = 18;
  prepareKey();
  status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, block, &key, &(mfrc522.uid));
  if (status != MFRC522::STATUS_OK) {
    Serial.print(F("Authentication failed: "));
    Serial.println(mfrc522.GetStatusCodeName(status));
    return;
  }
  status = mfrc522.MIFARE_Read(block, buffer1, &len);
  if (status != MFRC522::STATUS_OK) {
    Serial.print(F("Reading failed: "));
    Serial.println(mfrc522.GetStatusCodeName(status));
    return;
  }
  String value = "";
  for (uint8_t i = 0; i < 16; i++) {
    value += (char)buffer1[i];
  }
  value.trim();
  Serial.print(value);
  Serial.println(F("\n**End Reading**\n"));
}

void readAndPrintIntegersFromBlockNo(byte block) {
  byte buffer1[18];
  byte len = 18;
  prepareKey();
  status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, block, &key, &(mfrc522.uid));
  if (status != MFRC522::STATUS_OK) {
    Serial.print(F("Authentication failed: "));
    Serial.println(mfrc522.GetStatusCodeName(status));
    return;
  }
  status = mfrc522.MIFARE_Read(block, buffer1, &len);
  if (status != MFRC522::STATUS_OK) {
    Serial.print(F("Reading failed: "));
    Serial.println(mfrc522.GetStatusCodeName(status));
    return;
  }
  int data[8];
  for (uint8_t i = 0; i < 8; i++) {
    data[i] = int(buffer1[2*i])+int(buffer1[2*i+1] << 8);
    Serial.print(data[i]);
    Serial.print('\t');
    if (i == 3) Serial.println();
  }
  Serial.println(F("\n**End Reading**\n"));
}

Both sketches are "hardwired" to block 4 and 5 just to show the principle.

I changed the sketches to work as a simple statemachine which I find easier to understand and follow the program flow (I do not really like the use of "return" in loop() ...).

This is the function that writes an array of integers to the card:

void writeToBlockNoIntegers(byte block) {
 Serial.setTimeout(20000L);
 int buffI[] = { -32768, -1000, -255, -1,
                 0, 255, 1000, 32767 };
 byte buffr[16];
 for (byte i=0;i<8;i++){
   buffr[i*2]   = buffI[i] & 0xFF;
   buffr[i*2+1] = buffI[i] >> 8;
 }
 writeBytesToBlock(block, buffr);
 Serial.println(" ");
}

As one can see each integer value is stored as low byte first and high byte in the second place.

This is the function that restores the integers from the byte array buffer1[ ]:

  int data[8];
  for (uint8_t i = 0; i < 8; i++) {
    data[i] = int(buffer1[2*i])+int(buffer1[2*i+1] << 8);
    Serial.print(data[i]);
    Serial.print('\t');
    if (i == 3) Serial.println();
  }

Each integer value is calculated by shifting the second byte (high byte) 8 times to the left and adding the first (low) byte. Whether you use little or big endian is finally up to you (if it does not depend on other applications that read the data).

These are the results you should see after writing and reading the data:

**Card Detected:**
0123456789AB
**End Reading**

-32768 -1000 -255 -1
0 255 1000 32767
**End Reading**

Present new card please

The difference between the two types in the read example is that block 4 data are interpreted as ASCII characters and block 5 data as integer.

I hope that the examples allow you to develop your application as intended.

Good luck!