This is some elegant-looking code, but could I have done this better?

I would manage my 16 byte uids with something like the following:

#include <EEPROM.h>

struct UidData {
  uint8_t uid[16];
  UidData(const uint8_t* fromBuffer) {
    set(fromBuffer);
  }
  UidData(const char* fromCstring) {
    set(fromCstring);
  }
  void set(const uint8_t* fromBuffer) {
    memcpy(uid, fromBuffer, sizeof(uid));
  }
  void set(const char* fromCstring) {
    strncpy((char*)uid, fromCstring, sizeof(uid));
  }
  void getEE(uint16_t adr) {
    EEPROM.get(adr, *this);
  }
  void putEE(uint16_t adr) {
    EEPROM.put(adr, *this);
  }
  void dump() {
    for (byte i = 0; i < sizeof(uid); i++) {
      Serial.write(' ');
      if (uid[i] < 0x20) {
        Serial.write('.');
      } else {
        Serial.write(uid[i]);
      }
    }
    Serial.println();
    for (byte i = 0; i < sizeof(uid); i++) {
      if (uid[i] < 16) {
        Serial.write('0');
      }
      Serial.print(uid[i], HEX);
    }
    Serial.println();
  }
};

uint8_t testBuffer[16] = { 'i', 'l', 'l', 'e', 'g', 'a', 'l', 'y', ' ', 'c', 'l', 'o', 'n', 'e', 'd', '!'};

void setup() {
  UidData testUid("0123456789abcdef");
  Serial.begin(250000);
  testUid.dump();
  testUid.putEE(0x100);
  testUid.set(testBuffer);
  testUid.dump();
  testUid.getEE(0x100);
  testUid.dump();
}
void loop() {}
 0 1 2 3 4 5 6 7 8 9 a b c d e f
30313233343536373839616263646566
 i l l e g a l y   c l o n e d !
696C6C6567616C7920636C6F6E656421
 0 1 2 3 4 5 6 7 8 9 a b c d e f
30313233343536373839616263646566

Example contains:

  • creation from buffer or cstring
  • set from buffer or cstring
  • save to EEPROM
  • read from EEPROM
  • dump

An RFID of 32 bits will fit into a long int.
If that is not enough then 64 bits will fit into a long long.

There is no need to piddle about with ints.

Just stick all the bytes you read into a single variable when you read the card. I think that is the part you are missing. But as you don’t seem to post the bit where you read the card it is hard to tell you what to do.

Grumpy_Mike:
An RFID of 32 bits will fit into a long int.
If that is not enough then 64 bits will fit into a long long.

There is no need to piddle about with ints.

Just stick all the bytes you read into a single variable when you read the card. I think that is the part you are missing. But as you don’t seem to post the bit where you read the card it is hard to tell you what to do.

ppcc_gate.ino (21 KB)

To my knowledge. you can directly write readbackblock into eeprom.

    readBlock(BanKeyBlock, readbackblock);
EEPROM.put(EEPROMIndex, readbackblock);

This will store it as read from the card. You will have to adjust other functions.

For the compare, you can use something like

byte compare[18];
for(byte cnt=0;cnt<number of keys in eeprom;cnt++)
{
  EEPROM.get((cnt*18), compare);

  if(memcmp(compare, GivenKey, sizeof(compare)) == 0
  {
    return cnt;
  }
}

return -1;

Note that given key needs to be an array of bytes, not a String (capital S).

I did not follow all your code (a bit confused about 16 vs 18), but this is just to give you some ideas; you need a lot of adjustments to your existing code but as said before, the memXXX functions are your friend.

sterretje:
To my knowledge. you can directly write readbackblock into eeprom.

    readBlock(BanKeyBlock, readbackblock);

EEPROM.put(EEPROMIndex, readbackblock);



This will store it as read from the card. You will have to adjust other functions.

For the compare, you can use something like


byte compare[18];
for(byte cnt=0;cnt<number of keys in eeprom;cnt++)
{
  EEPROM.get((cnt*18), compare);

if(memcmp(compare, GivenKey, sizeof(compare)) == 0
  {
    return cnt;
  }
}

return -1;



Note that given key needs to be an array of bytes, not a String (capital S).

I did not follow all your code (a bit confused about 16 vs 18), but this is just to give you some ideas; you need a lot of adjustments to your existing code but as said before, the memXXX functions are your friend.

I think part of what is confusing me is that a bite is two characters. But the key is a set of four bites. So how am I able to load that into a variable that has to be compatible with a byte what essentially it is for bytes

The hexadecimal text representation of a byte is two characters., the byte itself is what it is.

Ok, so i think i'm getting closer to the way this should be made.

the bellow code works. The object is to check if the id of the card is in the EEPROM. You can see the commented lines i use to setup cards and to manually put the card id into the EEPROM. This works fine. In a few I will post the added code that is meant to take a key id (put into block 4) and put that into the EEPROM. When i do that, I get jibberish. which I do not understand because i'm basicialy doing the same thing.

but with your help i think i'm getting closer. thank you

#include <SPI.h>//include the SPI bus library
#include <MFRC522.h>//include the RFID reader library
#include <EEPROM.h>
#define SS_PIN 10  //slave select pin
#define RST_PIN 9  //reset pin
MFRC522 mfrc522(SS_PIN, RST_PIN); // instatiate a MFRC522 reader object.
MFRC522::MIFARE_Key key; //create a MIFARE_Key struct named 'key', which will hold the card information

byte nuidPICC[4];
int PasswordBlock = 2; //this is the block number we will write into and then read. Do not write into 'sector trailer' block, since this can make the block unusable.
int BanKeyBlock = 4;//this is the block that stores a key programmed into a tag to be deactivated when that tag is used
byte blockcontent[16] = {"ppcc"}; //an array with 16 bytes to be written into one of the 64 card blocks is defined!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
byte deactivatecardblockcontent[16] = {"deactivate"};//all zeros. This can be used to delete a block.
byte readbackblock[18]; //This array is used for reading out a block. The MIFARE_Read method requires a buffer that is at least 18 bytes to hold the 16 bytes of a block.


void setup(){
  pinMode(4, OUTPUT);
  pinMode(3, OUTPUT);
  Serial.begin(9600); // Initialize serial communications with the PC
  SPI.begin(); // Init SPI bus
  mfrc522.PCD_Init(); // Init MFRC522 card (in case you wonder what PCD means: proximity coupling device)
  Serial.println("Scan a MIFARE Classic card");
  for (byte i = 0; i < 6; i++) {
    key.keyByte[i] = 0xFF; //keyByte is defined in the "MIFARE_Key" 'struct' definition in the .h file of the library
  }
}

void loop() {
// Look for new cards (in case you wonder what PICC means: proximity integrated circuit card)
  if (!mfrc522.PICC_IsNewCardPresent()) { //if PICC_IsNewCardPresent returns 1, a new card has been found and we continue
    return; //if it did not find a new card is returns a '0' and we return to the start of the loop
  }
  // Select one of the cards
  if (!mfrc522.PICC_ReadCardSerial()) { //if PICC_ReadCardSerial returns 1, the "uid" struct (see MFRC522.h lines 238-45)) contains the ID of the read card.
    return; //if it returns a '0' something went wrong and we return to the start of the loop
  }
  Serial.println("card selected");
  String txt; //This is where we store block 2, the password
  //Store Card UID
  for (byte i = 0; i < 4; i++) {
    nuidPICC[i] = mfrc522.uid.uidByte[i];
  }
  /*
  /////These 3 lines are used to setup cards manually//////
  //writeBlock(PasswordBlock, blockcontent);//the blockcontent array is written into the card block
  //writeBlock(BanKeyBlock, nuidPICC);//the blockcontent array is written into the card block
  //writeBlock(PasswordBlock, deactivatecardblockcontent);//the blockcontent array is written into the card block
  //return;

  //////these lines are to add banned card to eeprom manually/////
  //EEPROM.write(4, nuidPICC[0]);
  //EEPROM.write(5, nuidPICC[1]);
  //EEPROM.write(6, nuidPICC[2]);
  //EEPROM.write(7, nuidPICC[3]);
  */

  //check if uid is in eprom and needs to be deactivated
  int EEPROMIndex = LookForUidInEEPROM();
  if (EEPROMIndex > -1){
    Serial.println("deleting card");
    Serial.print("first byte of card id in eeprom is: ");
    Serial.println(EEPROMIndex);
    delay(1000);
    //uid is in eeprom, we need to deactivate it and remove from eeprom
//  writeBlock(PasswordBlock, deactivatecardblockcontent);
//  EEPROM.write(EEPROMIndex, 255);
//  EEPROM.write(EEPROMIndex + 1, 255);
//  EEPROM.write(EEPROMIndex + 2, 255);
//  EEPROM.write(EEPROMIndex + 3, 255);
    return;
   }
   

   
  //uid is not in eeprom. continue
/*  Serial.println("Continuing, card isn't banned, reading block 2");
  //read block 2 for password or other keywords
  readBlock(PasswordBlock, readbackblock);
  for (int j = 0; j < 16; j++){
    Serial.write(readbackblock[j]); //Serial.write() transmits the ASCII numbers as human readable characters to serial monitor
    txt = txt + (byte) readbackblock[j]; //adds the acii character to the string. the data ends up being "1121129999000000000000" It needs to be converted to "ppcc000000000000"
  }
  //handle keyworkds from tag
  byte KeyToBeBanned[4];
  if (txt == "100101979911610511897116101000000") {
    Serial.println("deactivate card used");
    //get key  from block BanKeyBlock
    readBlock(BanKeyBlock, readbackblock);
    for (int j = 0; j < 4; j++){
    Serial.write(readbackblock[j]); //Serial.write() transmits the ASCII numbers as human readable characters to serial monitor
    KeyToBeBanned[0] = readbackblock[j]; 
    KeyToBeBanned[1] = readbackblock[j]; 
    KeyToBeBanned[2] = readbackblock[j]; 
    KeyToBeBanned[3] = readbackblock[j]; 
  }
  Serial.println();
  Serial.println("new text is");
  Serial.println(txt);
  if (KeyToBeBanned[0] == nuidPICC[0] && KeyToBeBanned[1] == nuidPICC[1] && KeyToBeBanned[2] == nuidPICC[2] &&  KeyToBeBanned[3] == nuidPICC[3]){
    Serial.println("they match");
  }else {
    Serial.println("they don't match");
  }
  delay(99999);
  return;
 */
  
  //reset card reader
  mfrc522.PICC_HaltA();
  mfrc522.PCD_StopCrypto1();
}
}

///// functions ////
int LookForUidInEEPROM(){
  byte compare[4];
  for (int i = 0; i < EEPROM.length()+1; i = i + 4){
  compare[0] = EEPROM.read(i);
  compare[1] = EEPROM.read(i+1);
  compare[2] = EEPROM.read(i+2);
  compare[3] = EEPROM.read(i+3);  
    
    if(compare[0] == nuidPICC[0] && compare[1] == nuidPICC[1] && compare[2] == nuidPICC[2] && compare[3] == nuidPICC[3]){
      return i;
    }
  }
  return -1;
}

int FindFirstAvailableEEPROMSetOf8(){

  for (int i = 0; EEPROM.length(); i = i + 4){

    if(EEPROM.read(i)== 255){

      return(i);

    }else if(i > EEPROM.length()){

      return(32767);

    }
  }
}

//// rfid functions ////
int readBlock(int blockNumber, byte arrayAddress[]) {

  int largestModulo4Number = blockNumber / 4 * 4;

  int trailerBlock = largestModulo4Number + 3; //determine trailer block for the sector


  /*****************************************authentication of the desired block for access***********************************************************/

  byte status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, trailerBlock, & key, & (mfrc522.uid));

  //byte PCD_Authenticate(byte command, byte blockAddr, MIFARE_Key *key, Uid *uid);

  //this method is used to authenticate a certain block for writing or reading

  //command: See enumerations above -> PICC_CMD_MF_AUTH_KEY_A = 0x60 (=1100000),    // this command performs authentication with Key A

  //blockAddr is the number of the block from 0 to 15.

  //MIFARE_Key *key is a pointer to the MIFARE_Key struct defined above, this struct needs to be defined for each block. New cards have all A/B= FF FF FF FF FF FF

  //Uid *uid is a pointer to the UID struct that contains the user ID of the card.

  if (status != MFRC522::STATUS_OK) {

    Serial.print("PCD_Authenticate() failed (read): ");

    Serial.println(mfrc522.GetStatusCodeName(status));

    return 3; //return "3" as error message

  }

  //it appears the authentication needs to be made before every block read/write within a specific sector.

  //If a different sector is being authenticated access to the previous one is lost.


  /*****************************************reading a block***********************************************************/


  byte buffersize = 18; //we need to define a variable with the read buffer size, since the MIFARE_Read method below needs a pointer to the variable that contains the size... 

  status = mfrc522.MIFARE_Read(blockNumber, arrayAddress, & buffersize); //&buffersize is a pointer to the buffersize variable; MIFARE_Read requires a pointer instead of just a number

  if (status != MFRC522::STATUS_OK) {

    Serial.print("MIFARE_read() failed: ");

    Serial.println(mfrc522.GetStatusCodeName(status));

    return 4; //return "4" as error message

  }

  Serial.println("block was read");

}

This is the code that does not work. This is where I will put the key's into the EEPROM that need to be banned. for the moment ive put my rfid tag's into block 4 of the same tag. I'm just trying to read the tag from block 4 as well as the built in function that reads the tag in block 1 and compare to make sure i'm getting the same thing. but i don't, i get jibberish.

#include <SPI.h>//include the SPI bus library
#include <MFRC522.h>//include the RFID reader library
#include <EEPROM.h>
#define SS_PIN 10  //slave select pin
#define RST_PIN 9  //reset pin
MFRC522 mfrc522(SS_PIN, RST_PIN); // instatiate a MFRC522 reader object.
MFRC522::MIFARE_Key key; //create a MIFARE_Key struct named 'key', which will hold the card information

byte nuidPICC[4];
int PasswordBlock = 2; //this is the block number we will write into and then read. Do not write into 'sector trailer' block, since this can make the block unusable.
int BanKeyBlock = 4;//this is the block that stores a key programmed into a tag to be deactivated when that tag is used
byte blockcontent[16] = {"ppcc"}; //an array with 16 bytes to be written into one of the 64 card blocks is defined!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
byte deactivatecardblockcontent[16] = {"deactivate"};//all zeros. This can be used to delete a block.
byte readbackblock[18]; //This array is used for reading out a block. The MIFARE_Read method requires a buffer that is at least 18 bytes to hold the 16 bytes of a block.


void setup(){
  pinMode(4, OUTPUT);
  pinMode(3, OUTPUT);
  Serial.begin(9600); // Initialize serial communications with the PC
  SPI.begin(); // Init SPI bus
  mfrc522.PCD_Init(); // Init MFRC522 card (in case you wonder what PCD means: proximity coupling device)
  Serial.println("Scan a MIFARE Classic card");
  for (byte i = 0; i < 6; i++) {
    key.keyByte[i] = 0xFF; //keyByte is defined in the "MIFARE_Key" 'struct' definition in the .h file of the library
  }
}

void loop() {
// Look for new cards (in case you wonder what PICC means: proximity integrated circuit card)
  if (!mfrc522.PICC_IsNewCardPresent()) { //if PICC_IsNewCardPresent returns 1, a new card has been found and we continue
    return; //if it did not find a new card is returns a '0' and we return to the start of the loop
  }
  // Select one of the cards
  if (!mfrc522.PICC_ReadCardSerial()) { //if PICC_ReadCardSerial returns 1, the "uid" struct (see MFRC522.h lines 238-45)) contains the ID of the read card.
    return; //if it returns a '0' something went wrong and we return to the start of the loop
  }
  Serial.println("card selected");
  String txt; //This is where we store block 2, the password
  //Store Card UID
  for (byte i = 0; i < 4; i++) {
    nuidPICC[i] = mfrc522.uid.uidByte[i];
  }
  /*
  /////These 3 lines are used to setup cards manually//////
  //writeBlock(PasswordBlock, blockcontent);//the blockcontent array is written into the card block
  //writeBlock(BanKeyBlock, nuidPICC);//the blockcontent array is written into the card block
  //writeBlock(PasswordBlock, deactivatecardblockcontent);//the blockcontent array is written into the card block
  //return;

  //////these lines are to add banned card to eeprom manually/////
  //EEPROM.write(4, nuidPICC[0]);
  //EEPROM.write(5, nuidPICC[1]);
  //EEPROM.write(6, nuidPICC[2]);
  //EEPROM.write(7, nuidPICC[3]);
  */

/*  //check if uid is in eprom and needs to be deactivated
  int EEPROMIndex = LookForUidInEEPROM();
  if (EEPROMIndex > -1){
    Serial.println("deleting card");
    Serial.print("first byte of card id in eeprom is: ");
    Serial.println(EEPROMIndex);
    delay(1000);
    //uid is in eeprom, we need to deactivate it and remove from eeprom
//  writeBlock(PasswordBlock, deactivatecardblockcontent);
//  EEPROM.write(EEPROMIndex, 255);
//  EEPROM.write(EEPROMIndex + 1, 255);
//  EEPROM.write(EEPROMIndex + 2, 255);
//  EEPROM.write(EEPROMIndex + 3, 255);
    return;
   }
   */

   
  //uid is not in eeprom. continue
  Serial.println("Continuing, card isn't banned, reading block 2");
  //read block 2 for password or other keywords
  readBlock(PasswordBlock, readbackblock);
  for (int j = 0; j < 16; j++){
    Serial.write(readbackblock[j]); //Serial.write() transmits the ASCII numbers as human readable characters to serial monitor
    txt = txt + (byte) readbackblock[j]; //adds the acii character to the string. the data ends up being "1121129999000000000000" It needs to be converted to "ppcc000000000000"
  }
  //handle keyworkds from tag
  byte KeyToBeBanned[4];
  if (txt == "100101979911610511897116101000000") {
    Serial.println("deactivate card used");
    //get key  from block BanKeyBlock
    readBlock(BanKeyBlock, readbackblock);
    for (int j = 0; j < 4; j++){
    Serial.write(readbackblock[j]); //Serial.write() transmits the ASCII numbers as human readable characters to serial monitor
    KeyToBeBanned[0] = readbackblock[j]; 
    KeyToBeBanned[1] = readbackblock[j]; 
    KeyToBeBanned[2] = readbackblock[j]; 
    KeyToBeBanned[3] = readbackblock[j]; 
  }
  Serial.println("new text is");
  Serial.println(txt);
  if (KeyToBeBanned[0] == nuidPICC[0] && KeyToBeBanned[1] == nuidPICC[1] && KeyToBeBanned[2] == nuidPICC[2] &&  KeyToBeBanned[3] == nuidPICC[3]){
    Serial.println("they match");
  }else {
    Serial.println("they don't match");
  }
  delay(99999);
  return;
  
  //reset card reader
  mfrc522.PICC_HaltA();
  mfrc522.PCD_StopCrypto1();
}
}

///// functions ////
int LookForUidInEEPROM(){
  byte compare[4];
  for (int i = 0; i < EEPROM.length()+1; i = i + 4){
  compare[0] = EEPROM.read(i);
  compare[1] = EEPROM.read(i+1);
  compare[2] = EEPROM.read(i+2);
  compare[3] = EEPROM.read(i+3);  
    
    if(compare[0] == nuidPICC[0] && compare[1] == nuidPICC[1] && compare[2] == nuidPICC[2] && compare[3] == nuidPICC[3]){
      return i;
    }
  }
  return -1;
}

int FindFirstAvailableEEPROMSetOf8(){

  for (int i = 0; EEPROM.length(); i = i + 4){

    if(EEPROM.read(i)== 255){

      return(i);

    }else if(i > EEPROM.length()){

      return(32767);

    }
  }
}

//// rfid functions ////
int readBlock(int blockNumber, byte arrayAddress[]) {

  int largestModulo4Number = blockNumber / 4 * 4;

  int trailerBlock = largestModulo4Number + 3; //determine trailer block for the sector


  /*****************************************authentication of the desired block for access***********************************************************/

  byte status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, trailerBlock, & key, & (mfrc522.uid));

  //byte PCD_Authenticate(byte command, byte blockAddr, MIFARE_Key *key, Uid *uid);

  //this method is used to authenticate a certain block for writing or reading

  //command: See enumerations above -> PICC_CMD_MF_AUTH_KEY_A = 0x60 (=1100000),    // this command performs authentication with Key A

  //blockAddr is the number of the block from 0 to 15.

  //MIFARE_Key *key is a pointer to the MIFARE_Key struct defined above, this struct needs to be defined for each block. New cards have all A/B= FF FF FF FF FF FF

  //Uid *uid is a pointer to the UID struct that contains the user ID of the card.

  if (status != MFRC522::STATUS_OK) {

    Serial.print("PCD_Authenticate() failed (read): ");

    Serial.println(mfrc522.GetStatusCodeName(status));

    return 3; //return "3" as error message

  }

  //it appears the authentication needs to be made before every block read/write within a specific sector.

  //If a different sector is being authenticated access to the previous one is lost.


  /*****************************************reading a block***********************************************************/


  byte buffersize = 18; //we need to define a variable with the read buffer size, since the MIFARE_Read method below needs a pointer to the variable that contains the size... 

  status = mfrc522.MIFARE_Read(blockNumber, arrayAddress, & buffersize); //&buffersize is a pointer to the buffersize variable; MIFARE_Read requires a pointer instead of just a number

  if (status != MFRC522::STATUS_OK) {

    Serial.print("MIFARE_read() failed: ");

    Serial.println(mfrc522.GetStatusCodeName(status));

    return 4; //return "4" as error message

  }

  Serial.println("block was read");

}

this is the jiberish i get

⸮yO⸮

birddseedd:
this is the jiberish i get

⸮yO⸮

Which line produces that? You have a couple of useful print statements before that but you leave that out so we don't have a reference.

I suspect that it comes after e.g. "deactivate card used". If so, the explanation is that the readbackblock variable contains binary data, the write method sends the binary data and the serial monitor only understands ascii (binary data from 0x20 to 0x7E (or 0x7F)) and prints rubbish when a byte isn't ascii.

Change the write to print and add spaces in between so you can recognise the individual bytes.

I would write a function to print the binary array

/*
  print an array of binary data in human readable format (hex representation)
  In:
    data to print
    number of bytes to print
*/
void printBinaryArray(byte *data, byte numBytes)
{
  // loop theough the data bytes
  for (byte cnt = 0; cnt < numBytes; cnt++)
  {
    // print a leading 0x
    Serial.print("0x");
    // if value less than 16 (0x10)
    if (data[cnt] < 0x10)
    {
      // print leading zero
      Serial.print("0");
    }
    // print the hex representation of the byte
    Serial.print(data[cnt], HEX);
    // separate individual bytes
    Serial.print(" ");
  }

  // new line
  Serial.println();
}

And everywere where you want to print the data (e.g. readbackblock), call that function
e.g.

  if (txt == "100101979911610511897116101000000") {
    Serial.println("deactivate card used");
    //get key  from block BanKeyBlock
    readBlock(BanKeyBlock, readbackblock);
    printBinaryArray(readbackblock, 4);

    ...
    ...

Instead of e.g.

      KeyToBeBanned[0] = readbackblock[j];
      KeyToBeBanned[1] = readbackblock[j];
      KeyToBeBanned[2] = readbackblock[j];
      KeyToBeBanned[3] = readbackblock[j];

I suggest that you use memcpy()

memcpy(KeyToBeBanned, readbackblock, 4);

===
You have a bug in readBlock; it does not always return a value

int readBlock(int blockNumber, byte arrayAddress[]) {
  ...
  ...

  if (status != MFRC522::STATUS_OK) {
    ...
    ...
    return 3; //return "3" as error message

  }

  ...
  ...


  if (status != MFRC522::STATUS_OK) {
    ...
    ...
    return 4; //return "4" as error message

  }

  Serial.println("block was read");

  // you need to return something here
}

If you do not return something, the calling function will use whatever is in the memory location where the return value is stored which can be anything from 0x0000 to 0xFFFF. In this case, on success return 0.

Please check all your functions that return an int. You can set file -> preferences -> compiler warnings to ALL to see this (and other) types of issues. Some can be ignored, some can't; matter of understanding the implications.

sterretje:
Which line produces that? You have a couple of useful print statements before that but you leave that out so we don't have a reference.

I suspect that it comes after e.g. "deactivate card used". If so, the explanation is that the readbackblock variable contains binary data, the write method sends the binary data and the serial monitor only understands ascii (binary data from 0x20 to 0x7E (or 0x7F)) and prints rubbish when a byte isn't ascii.

Change the write to print and add spaces in between so you can recognise the individual bytes.

I would write a function to print the binary array

/*

print an array of binary data in human readable format (hex representation)
  In:
    data to print
    number of bytes to print
*/
void printBinaryArray(byte *data, byte numBytes)
{
  // loop theough the data bytes
  for (byte cnt = 0; cnt < numBytes; cnt++)
  {
    // print a leading 0x
    Serial.print("0x");
    // if value less than 16 (0x10)
    if (data[cnt] < 0x10)
    {
      // print leading zero
      Serial.print("0");
    }
    // print the hex representation of the byte
    Serial.print(data[cnt], HEX);
    // separate individual bytes
    Serial.print(" ");
  }

// new line
  Serial.println();
}



And everywere where you want to print the data (e.g. readbackblock), call that function
e.g.


if (txt == "100101979911610511897116101000000") {
    Serial.println("deactivate card used");
    //get key  from block BanKeyBlock
    readBlock(BanKeyBlock, readbackblock);
    printBinaryArray(readbackblock, 4);

...
    ...




Instead of e.g.


KeyToBeBanned[0] = readbackblock[j];
      KeyToBeBanned[1] = readbackblock[j];
      KeyToBeBanned[2] = readbackblock[j];
      KeyToBeBanned[3] = readbackblock[j];



I suggest that you use [memcpy()](https://linux.die.net/man/3/memcpy)


memcpy(KeyToBeBanned, readbackblock, 4);




===
You have a bug in *readBlock*; it does not always return a value


int readBlock(int blockNumber, byte arrayAddress[]) {
  ...
  ...

if (status != MFRC522::STATUS_OK) {
    ...
    ...
    return 3; //return "3" as error message

}

...
  ...

if (status != MFRC522::STATUS_OK) {
    ...
    ...
    return 4; //return "4" as error message

}

Serial.println("block was read");

// you need to return something here
}



If you do not return something, the calling function will use whatever is in the memory location where the return value is stored which can be anything from 0x0000 to 0xFFFF. In this case, on success return 0.

Please check all your functions that return an int. You can set file -> preferences -> compiler warnings to ALL to see this (and other) types of issues. Some can be ignored, some can't; matter of understanding the implications.

Thanks for the help. you were correct on where the error was printing out. But here is what I do not understand.

What i was basicially doing was taking the data that the card reader out up (readbackblock) and load it into a new variable (KeyToBeBanned). And for some reason i got jiberish. Once i realized that the card reader was loading a byte array, i just decided to compare directly from that byte array if (readbackblock[0] == nuidPICC[0]

this works. I don't have it set to print what it is, but it does return true.

as far as memcmp. I googled it in order to read about it, i expected to see an arduino webpage showing documentation, instead all i got was forums telling people to use it. but i found it on cplusplus.com and it seems simple enough so im using it. and memcpy seems to be about as simple. just couldn't find it on arduino's website for some reason.

thanks for the help.