Skip to main content
2 of 5
added 97 characters in body

Issue with multiple rc522 connected to arduino uno

I've been working non-stop for over two weeks, trying to solve a problem. I'm building a puzzle with four RC522 modules. When I connect more than one RC522 to an Arduino Uno, the device stops working randomly. Initially, everything seemed fine. I began adding the modules one by one, but suddenly, without any apparent reason, the whole system stopped functioning.

I attempted to locate the issue by disconnecting all the RC522 modules. When only one RC522 is connected, everything works correctly. However, when I attach the MISO and MOSI pins of the second RC522 to the Arduino, the first device stops working. Additionally, when I tried using the DumpInfo example of the library, the output after adding the second device is as follows:

    Card UID: 33 6C E8 F6
    Card SAK: 08
    PICC type: MIFARE 1KB
    Sector Block   0  1  2  3   4  5  6  7   8  9 10 11  12 13 14 15  AccessBits
      15     63   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ] 
             62  MIFARE_Read() failed: A MIFARE PICC responded with NAK.
             61  MIFARE_Read() failed: Timeout in communication.
             60  MIFARE_Read() failed: Timeout in communication.
      14     59  PCD_Authenticate() failed: Timeout in communication.
      13     55  PCD_Authenticate() failed: Timeout in communication.
      12     51  PCD_Authenticate() failed: Timeout in communication.
      11     47  PCD_Authenticate() failed: Timeout in communication.
      10     43  PCD_Authenticate() failed: Timeout in communication.
       9     39  PCD_Authenticate() failed: Timeout in communication.
       8     35  PCD_Authenticate() failed: Timeout in communication.
       7     31  PCD_Authenticate() failed: Timeout in communication.
       6     27  PCD_Authenticate() failed: Timeout in communication.
       5     23  PCD_Authenticate() failed: Timeout in communication.
       4     19  PCD_Authenticate() failed: Timeout in communication.
       3     15  PCD_Authenticate() failed: Timeout in communication.
       2     11  PCD_Authenticate() failed: Timeout in communication.
       1      7  PCD_Authenticate() failed: Timeout in communication.
       0      3  PCD_Authenticate() failed: Timeout in communication.

It's noticeable that whenever I remove the MISO and MOSI pins of the second RC522, everything works.

I've tried using six different Arduinos and eleven different RC522 modules. Initially, they worked correctly, but after some time, everything went wrong, similar to the issue described above. I've experimented with different codes, considered power drop issues, and even added a 2-amp power supply. I've used both 3.3V and 5V supplies and attempted to add pull-up resistors to each CS line. I also made sure that every connection is correct by using the multimeter. I also tried to add decoupling cap on the VCC. I used shared and separated rst pins. Two sample codes are as below:

the simple one to just test the modules:

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

#define RST_PIN         3         // 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

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
  digitalWrite(SS_PIN, HIGH);
    mfrc522.PCD_Init();     // Init MFRC522
    delay(4);               // Optional delay. Some board do need more time after init to be ready, see Readme
    mfrc522.PCD_DumpVersionToSerial();  // Show details of PCD - MFRC522 Card Reader details
    Serial.println(F("Scan PICC to see UID, SAK, type, and data blocks..."));
}

void loop() {
    // Reset the loop if no new card present on the sensor/reader. This saves the entire process when idle.
    if ( ! mfrc522.PICC_IsNewCardPresent()) {
        return;
    }

    // Select one of the cards
    if ( ! mfrc522.PICC_ReadCardSerial()) {
        return;
    }

    // Dump debug info about the card; PICC_HaltA() is automatically called
    mfrc522.PICC_DumpToSerial(&(mfrc522.uid));
}

My own ocde:

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

#define SS_PIN_A 10
#define RST_PIN_A 3

#define SS_PIN_B 9
//#define RST_PIN_B 7

#define SS_PIN_C 8
//#define RST_PIN_C 5

#define SS_PIN_D 7
//#define RST_PIN_D 6

#define RELAY_PIN 4  // Pin connected to the relay

MFRC522 mfrc522Array[] = {
  MFRC522(SS_PIN_A, RST_PIN_A),
  MFRC522(SS_PIN_B, RST_PIN_A),
  MFRC522(SS_PIN_C, RST_PIN_A),
  MFRC522(SS_PIN_D, RST_PIN_A)
};

String MasterTagA = "336CE8";
String MasterTagB = "336CE8";
String MasterTagC = "336CE8";
String MasterTagD = "336CE8";

String MasterMainTag = "MASTER_TAG"; // Replace with the main master tag

String tagIDA = "";
String tagIDB = "";
String tagIDC = "";
String tagIDD = "";

bool accessGrantedA = false;
bool accessGrantedB = false;
bool accessGrantedC = false;
bool accessGrantedD = false;

bool mainMasterTagDetected = false;

MFRC522::MIFARE_Key key;

unsigned long activationTime = 0;  // Time of last activation
unsigned long debounceDelay = 4000;  // Delay for relay activation (4 seconds)

// Function declarations
void activateRelay();

void setup() {
  SPI.begin();
  Serial.begin(9600);

  pinMode(RELAY_PIN, OUTPUT);
  digitalWrite(RELAY_PIN, HIGH);  // Ensure relay is initially deactivated

  for (int i = 0; i < 4; i++) {
    mfrc522Array[i].PCD_Init();
  }

  Serial.println("Scan a MIFARE Classic card");

  for (byte i = 0; i < 6; i++) {
    key.keyByte[i] = 0xFF;
  }
}

void loop() {
  for (int i = 0; i < 4; i++) {
    if (getID(&mfrc522Array[i], i)) {
      if (mainMasterTagDetected) {
        activateRelay();
        mainMasterTagDetected = false; // Reset main master tag detection flag
      } else {
        switch (i) {
          case 0:
            checkAccess(tagIDA, MasterTagA, accessGrantedA, "A");
            break;
          case 1:
            if (accessGrantedA) {
              checkAccess(tagIDB, MasterTagB, accessGrantedB, "B");
            }
            break;
          case 2:
            if (accessGrantedA && accessGrantedB) {
              checkAccess(tagIDC, MasterTagC, accessGrantedC, "C");
            }
            break;
          case 3:
            if (accessGrantedA && accessGrantedB && accessGrantedC) {
              checkAccess(tagIDD, MasterTagD, accessGrantedD, "D");
            }
            break;
        }
      }
      printAccessControlStatus();
    }
  }

  // If all access granted and relay not activated yet
  if (accessGrantedA && accessGrantedB && accessGrantedC && accessGrantedD && millis() - activationTime >= debounceDelay) {
    activateRelay();
    // Reset access granted flags
    accessGrantedA = false;
    accessGrantedB = false;
    accessGrantedC = false;
    accessGrantedD = false;
  }
}

boolean getID(MFRC522* mfrc522, int moduleIndex) {
  if (!mfrc522->PICC_IsNewCardPresent()) {
    return false;
  }
  if (!mfrc522->PICC_ReadCardSerial()) {
    return false;
  }

  String tagID = "";
  for (uint8_t i = 0; i < 3; i++) {
    tagID.concat(String(mfrc522->uid.uidByte[i], HEX));
  }
  tagID.toUpperCase();
  if (tagID == MasterMainTag) {
    mainMasterTagDetected = true; // Set main master tag detection flag
  }
  storeTagID(tagID, moduleIndex);
  mfrc522->PICC_HaltA();
  return true;
}

void storeTagID(String tagID, int moduleIndex) {
  switch (moduleIndex) {
    case 0:
      tagIDA = tagID;
      break;
    case 1:
      tagIDB = tagID;
      break;
    case 2:
      tagIDC = tagID;
      break;
    case 3:
      tagIDD = tagID;
      break;
  }
}

void checkAccess(String tagID,
String masterTag, bool& accessGranted, String moduleName) {
  Serial.println(tagID);

  if (tagID == masterTag) {
    accessGranted = true;
    Serial.print("Access Granted to Module ");
    Serial.println(moduleName);
  } else {
    accessGranted = false;
    Serial.println("Access Denied!");
  }
}

void activateRelay() {
  digitalWrite(RELAY_PIN, LOW);  // Activate relay
  delay(2000);  // Wait for 2 seconds
  digitalWrite(RELAY_PIN, HIGH); // Deactivate relay
  activationTime = millis(); // Update activation time
}

void printAccessControlStatus() {
  Serial.print("Access Control Status: ");
  Serial.print("Module A: ");
  Serial.print(accessGrantedA ? "Granted  " : "Denied  ");
  Serial.print("Module B: ");
  Serial.print(accessGrantedB ? "Granted  " : "Denied  ");
  Serial.print("Module C: ");
  Serial.print(accessGrantedC ? "Granted  " : "Denied  ");
  Serial.print("Module D: ");
  Serial.println(accessGrantedD ? "Granted  " : "Denied  ");
}

this is the method which I connected the modules:

enter image description here

UPDATE: I added 1 sec delay before accessing each rc522 but did not solve the problem.