ESP32 und multiple RC522 - nur das zuletzt initialisierte funktioniert

Hallo liebe Maker-Freunde, in großer Not wende ich mich an euch. Ich verzweifel seit einigen Wochen an einem Projekt für einen Escape Room. In einem Bücherregal sollen 3 RC522 RFID Reader stecken. Wenn die 3 Chips richtig gestellt wurden, passiert etwas. Dazu gibt es natürlich noch Sound und einige andere Sachen, die hier aber unwichtig sind, weil die immer problemlos funktionieren.
Ursprünglich habe ich es mit einem einfachen Arduino Uno probiert. Aber es gab immer Probleme mit den RC522 Readern. Mal haben nicht alle initialisiert, mal funktionieren alle, mal keiner, einfach ein inkonsistentes Fehlerbild. Ich habe Wochen rumprobiert, das Internet durchforstet, mindestens 15 RC522 Module und verschiedene Controller durchgetestet etc. Ich habe immer wieder gelesen, dass die SPI Verbindung mit mehreren RC522 Modulen über längere Kabel (wobei es sich hier auch nur um ca. 80cm handelt) problematisch sein kann. Aber auch wenn ich die Reader direkt über Jumperkabel probiere gibt es die gleichen Probleme. Auch das Logic Level könnte ein Problem darstellen, auch wenn alle Tutorials die 3,3V Boards mit dem 5V Arduino laufen lassen. In zwei anderen Räumen habe ich ebenfalls mehrere Rätsel mit Arduinos und multiplen RC522 Readern seit Jahren zuverlässig am laufen, also gleiche Bauteile, gleicher Code, nur es läuft. Hier jetzt leider nicht. Ich habe sogar Logic Level Converter probiert, ohne Erfolg. Alle möglichen Tricks noch durchprobiert wie ein kurzes Delay nach jedem Initiliaisieren, weil RC522 anscheinend auch manchmal länger brauchen zum initialisieren. Auch eine zusätzliche 3,3V Einspeisung hat nix geändert. Alles ohne Erfolg.

Also habe ich mir mal ESP32 bestellt in der Hoffnung, dass es damit endlich funktioniert (wegen Logic Level und so). Es handelt sich um AZDelivery ESP32 Dev Kit C V4 NodeMCU. Nach einigem Testen bekomme ich das Problem leider immer noch nicht gelöst, aber immerhin gibt es diesmal ein konsistentes Fehlerbild bei dem ich die Hoffnung habe, dass jemand eine Lösung dafür weiß.

Wenn ich die 3 Reader initialisiere funktioniert immer nur der zuletzt initialisierte. Egal ob ich die Reihenfolge der Pins oder RC522 Module untereinander tausche, es funktioniert immer nur der letzte. Auch generell die SS Pins kann ich legen wie ich will, es führt alles zum gleichen Fehlerbild, es funktioniert immer nur der letzte. Der hat dann die richtige Firmware 0x92 = v2.0 und auch der Selftest ist ok. Bei den beiden ersten Boards ist es immer die Firmware 0x82 = (unknown) und der Selftest nicht ok. Stöpsel ich bei gleichem Code einfach die Boards um, funktioniert immer der zuletzt initialisierte. Und das scheint mir irgendwie ein verdächtig systematisches Problem zu sein, das vielleicht eine einfache Lösung hat.
Laut Pinout (Pinout) habe ich SCK, MOSI und MISO richtig auf 18, 23 und 19.

Ich krieg die Krise. Ich weiß nicht mehr weiter und BETE um eure Hilfe.

Hier natürlich noch der Code, der eigentlich fast 1:1 der Beispielcode der MFRC522 Library ist:

#include <SPI.h>
#include <MFRC522.h>
#define RST_PIN         4
#define NR_OF_READERS   3

byte ssPins[] = {27, 26, 25};

MFRC522 mfrc522[NR_OF_READERS];   // Create MFRC522 instance.

void setup() {
  delay(1000);
  Serial.begin(9600); // Initialize serial communications with the PC

  SPI.begin();        // Init SPI bus

  for (uint8_t reader = 0; reader < NR_OF_READERS; reader++) {
    mfrc522[reader].PCD_Init(ssPins[reader], RST_PIN); // Init each MFRC522 card
    delay(10);
    // Dump some debug information to the serial monitor
    Serial.print(F("Reader #"));
    Serial.print(reader);
    Serial.print(F(" init on pin "));
    Serial.print(String(ssPins[reader]));
    Serial.print(F(". Ant. strength: "));
    Serial.print(mfrc522[reader].PCD_GetAntennaGain());
    Serial.print(" SelfTest: ");
    Serial.print(mfrc522[reader].PCD_PerformSelfTest());
    Serial.print(F(". Version : "));
    mfrc522[reader].PCD_DumpVersionToSerial();
  }
  delay(100);
}

void loop() {

  for (uint8_t reader = 0; reader < NR_OF_READERS; reader++) {
    // Look for new cards

    if (mfrc522[reader].PICC_IsNewCardPresent() && mfrc522[reader].PICC_ReadCardSerial()) {
      Serial.print(F("Reader "));
      Serial.print(reader);
      // Show some details of the PICC (that is: the tag/card)
      Serial.print(F(": Card UID:"));
      dump_byte_array(mfrc522[reader].uid.uidByte, mfrc522[reader].uid.size);
      Serial.println();
      Serial.print(F("PICC type: "));
      MFRC522::PICC_Type piccType = mfrc522[reader].PICC_GetType(mfrc522[reader].uid.sak);
      Serial.println(mfrc522[reader].PICC_GetTypeName(piccType));

      // Halt PICC
      mfrc522[reader].PICC_HaltA();
      // Stop encryption on PCD
      mfrc522[reader].PCD_StopCrypto1();
    } 
  } 
}

/**
 * Helper routine to dump a byte array as hex values to Serial.
 */
void dump_byte_array(byte *buffer, byte bufferSize) {
  for (byte i = 0; i < bufferSize; i++) {
    Serial.print(buffer[i] < 0x10 ? " 0" : " ");
    Serial.print(buffer[i], HEX);
  }
}

Und das multiple Example geht auch nicht? (Pins anpassen....)

Leider nein, wenn ich das Beispiel nehme und wirkluch NUR die Pins anpasse ist das gleiche. Der zuletzt initialisierte hat die richtige Firmware und funktioniert, der andere hat diesmal Firmware 0x82 = (unknown) oder 0xEE = (unknown). Tausche ich dann die RC522 Module nur untereinander, also einfach umstecken, dann funktioniert wieder nur der zuletzt initialisierte... :frowning:

Kannst Du ein Foto vom Aufbau machen?

Wenn Du den aktuell letzten ziehst und nur die zwei davor dran lässt, geht dann dort auch nur der letzte?

Leider gerade nicht weil ich nicht vor Ort bin. Aber die ist auch nicht spektakulär, fürs Testen steckt alles mit Jumperkabel in einem Breadboard. SCK, MOSI, MISO und RST, genau wie 3,3V und GND kommen alle auf dem Breadboard zusammen und von dort in den ESP, nur die SS Pins laufen jeweils direkt vom RC522 in den ESP. Also quasi wirklich wie im cleanen Wiring Diagram

Ich kann nicht erkennen, wo du deine SS-Pins im Sketch (loop) an den ESP32 bindest.
Nur im Setup reicht es nicht. das muss auch im laufenden Betrieb geschehen.

Das ist aber im Example auch nur im setup().

Ok, dann frag ich mich wie es dann funktionieren kann.
Naja, dann wird das wohl über die Library gelöst.
Da bin ich dann mal raus.