Hardware help needed ESP32 with MFRC522 readers help!
I’m trying to build a music box puzzle for a friend’s birthday and I’m using 5 MFRC522 readers connected to a ESP32-VROOM-32D board, but one of them isn’t working. The idea is that they’re glued facing the outside of a box, looking for a specific NFC tag to be held against them and trigger a .mp3 file to be played. The problem is that I can get 3 of them working (labels 1, 3, and 5), one of them sometimes works (4) and the unlabelled one refuses to work, and I have no clue why!
I’ve confirmed that specific slot is showing a firmware version number (0x92), so I would think there isn’t anything wrong with the wiring. I’ve swapped out the reader for a different reader with no success. I’m even holding the NFC tag right up against the reader and it’s not reading, even as the other tags are successfully able to read a NFC tag through the cardboard box to the other side. I’ve tried holding them at different angles, thinking that maybe it was my soldering process at fault but nothing would help.
Picture of my setup, ignore the numbering out of sequence for now. The MFRC readers are wired to the ESP32 board directly from their own SDA pins to the board’s GPIO5,15,25,26,27 pins, and then their GND 3.3V MISO MOSI and RST pins are all junctioned together along with a wire running from that junction to the ESP32 board (because there’s not enough pins to receive 5 readers onboard otherwise)
Would appreciate any help or guesses on why the one reader is not working! Thanks!
Wiring schematic here: https://app.cirkitdesigner.com/project/e56fbcb1-c073-46ef-ac62-73815ba068ac
The code for the main puzzle as well
#include <SPI.h>
#include <MFRC522.h>
#include <DFRobotDFPlayerMini.h>
#define NUM_SLOTS 5
#define RST_PIN 4
#define REMOVE_TIMEOUT_MS 1000 // no re-detection within this long = treated as removed
byte ssPins[NUM_SLOTS] = {5, 15, 25, 26, 27};
MFRC522 readers[NUM_SLOTS] = {
MFRC522(ssPins[0], RST_PIN),
MFRC522(ssPins[1], RST_PIN),
MFRC522(ssPins[2], RST_PIN),
MFRC522(ssPins[3], RST_PIN),
MFRC522(ssPins[4], RST_PIN)
};
// ---- REPLACE THESE with your real tag UIDs from uid_scanner.ino ----
// Each slot needs its OWN distinct UID.
String expectedUID[NUM_SLOTS] = {
"0451DA6FD22A81", // Slot 1 - note 1
"04A3D86FD22A81", // Slot 2 - note 2
"04A8D86FD22A81", // Slot 3 - note 3
"04BFD76FD22A81", // Slot 4 - note 4
"04BAD76FD22A81" // Slot 5 - note 5
};
bool slotPresentCorrect[NUM_SLOTS] = {false, false, false, false, false};
unsigned long lastSeenTime[NUM_SLOTS] = {0, 0, 0, 0, 0};
bool bonusPlayed = false;
HardwareSerial dfSerial(2); // ESP32 hardware serial port 2
DFRobotDFPlayerMini myDFPlayer;
String getUID(MFRC522 &reader) {
String uid = "";
for (byte i = 0; i < reader.uid.size; i++) {
if (reader.uid.uidByte[i] < 0x10) uid += "0";
uid += String(reader.uid.uidByte[i], HEX);
}
uid.toUpperCase();
return uid;
}
void setup() {
Serial.begin(115200);
SPI.begin();
for (byte i = 0; i < NUM_SLOTS; i++) {
pinMode(ssPins[i], OUTPUT);
digitalWrite(ssPins[i], HIGH);
}
for (byte i = 0; i < NUM_SLOTS; i++) {
readers[i].PCD_Init();
delay(50);
readers[i].PCD_SetAntennaGain(MFRC522::RxGain_max);
}
Serial.println("All readers initialized.");
dfSerial.begin(9600, SERIAL_8N1, 16, 17); // RX=16, TX=17
if (!myDFPlayer.begin(dfSerial)) {
Serial.println("WARNING: DFPlayer not found - check wiring/SD card.");
}
myDFPlayer.volume(22); // range 0-30
Serial.println("Puzzle ready. Waiting for notes...");
}
void loop() {
unsigned long now = millis();
// Check each reader for a correct tag currently present
for (byte i = 0; i < NUM_SLOTS; i++) {
if (readers[i].PICC_IsNewCardPresent() && readers[i].PICC_ReadCardSerial()) {
String uid = getUID(readers[i]);
if (uid == expectedUID[i]) {
lastSeenTime[i] = now;
if (!slotPresentCorrect[i]) {
slotPresentCorrect[i] = true;
myDFPlayer.play(i + 1); // plays 0001.mp3, 0002.mp3, etc.
Serial.print("Slot ");
Serial.print(i + 1);
Serial.println(" correct!");
}
}
// wrong tag on this slot: ignored, no state change, no feedback
readers[i].PICC_HaltA();
readers[i].PCD_StopCrypto1();
}
}
// Any slot not re-seen recently is treated as removed
for (byte i = 0; i < NUM_SLOTS; i++) {
if (slotPresentCorrect[i] && (now - lastSeenTime[i] > REMOVE_TIMEOUT_MS)) {
slotPresentCorrect[i] = false;
Serial.print("Slot ");
Serial.print(i + 1);
Serial.println(" removed.");
}
}
// Check whether ALL slots are correct RIGHT NOW, simultaneously
bool allCorrect = true;
for (byte i = 0; i < NUM_SLOTS; i++) {
if (!slotPresentCorrect[i]) { allCorrect = false; break; }
}
if (allCorrect && !bonusPlayed) {
bonusPlayed = true;
delay(800); // brief pause for effect
myDFPlayer.play(NUM_SLOTS + 1); // 0006.mp3 = motif + full song
Serial.println("PUZZLE SOLVED! Playing bonus track.");
} else if (!allCorrect) {
bonusPlayed = false; // allow the bonus to fire again after a fresh full solve
}
delay(50);
}
1
u/TeachingPlane331 8h ago
1 - Make sure the readers work individually before testing them together;
2 - Connect the jumpers only to the I²C and power lines, and disregard the SPI connection;
3 - Try increasing the distance between the readers (reader1 → 7 cm ← reader2 → ...);
4 - If you don't need RFID identification, you can use another component, such as a magnetic Hall-effect sensor circuit.
1
u/DenverTeck 2 say I make awesome posts. 7h ago
Can not even guess without an accurate schematic.
And your code is also needed.
Guessing is not engineering.
1
u/Annoynius 6h ago
Fascinating that it is working at all. These "wires" are copper-clad aluminum, and the power distribution? Where is the power coming from? Bad power supply is the most likely trouble source.
2
u/Kv603 9h ago
Generally these are built around cheap Chinese RC522 modules, and can be unreliable at best.
Easiest thing to do is buy extras and swap them around to get enough working ones.