ESP32-S3 SPI interface to RC522

haz_coder
Posts: 5
Joined: Sat Oct 26, 2024 3:52 pm

ESP32-S3 SPI interface to RC522

Postby haz_coder » Sat Oct 26, 2024 4:02 pm

I have been trying for the past 2 days to get the SPI working on my sample project. I have the ESP32-S3 connected to the RC522.
For the life of me, I am not able to get them to communicate properly.
Here is what I tried:
First, I ran the project with:

Code: Select all

// Serial.print("MOSI: ");
  // Serial.println(MOSI);
  // Serial.print("MISO: ");
  // Serial.println(MISO);
  // Serial.print("SCK: ");
  // Serial.println(SCK);
  // Serial.print("SS: ");
  // Serial.println(SS); 
The output I got matches my pin assignment:
// Setup SPI2 pins

Code: Select all

const int SPI2_MISO = 13;
const int SPI2_MOSI = 11;
const int SPI2_SCK  = 12;
Here is my complete code. I only have a single RC522 connected for now to get it working.
I have the reset pin tied high, and the SDA pin tied low, so I am only trying to debug the communication lines, without any control lines, so I narrow down my debug.
Here is the complete code:

Code: Select all

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

// Setup SPI2 pins
const int SPI2_MISO = 13;
const int SPI2_MOSI = 11;
const int SPI2_SCK  = 12;

// Create an instance of the SPIClass for SPI2-HSPI
SPIClass hspi = SPIClass(HSPI);

// Setup MFRC522
const byte NR_OF_READERS = 3;
const int RST_PIN = 8;   // Define Reset pin
const int IRQ_PIN_0 = 7;   // Define the interrupt pin
const int IRQ_PIN_1 = 16; // CHANGE...CONFLICTS WITH NEXTION
const int IRQ_PIN_2 = 10;
const int SS_PIN_0 = 15;  // Define SS for all 3 RC522
const int SS_PIN_1 = 9;
const int SS_PIN_2 = 14;

// Define SPI pin arrays
byte ssPins[] = {SS_PIN_0, SS_PIN_1, SS_PIN_2};
byte irqPins[] = {IRQ_PIN_0, IRQ_PIN_1, IRQ_PIN_2};
// Define 
byte UIDCard[NR_OF_READERS][4];  // Matrix for storing UID over each reader
MFRC522 mfrc522[NR_OF_READERS];     // Create MFRC522 instances

// Forward declaration of handleRFIDInterrupt
void ICACHE_RAM_ATTR handleRFIDInterrupt();
// Forward declaration of writeStringToBlock
void writeStringToBlock(MFRC522 &rfid, byte blockAddr, String data);
// Forward declaration of readStringFromBlock
void readStringFromBlock(MFRC522 &rfid, byte blockAddr);

void initSPI2() {
  // Initialize the SPI2 bus
  hspi.begin(SPI2_SCK, SPI2_MISO, SPI2_MOSI, SS_PIN_0);
}

// Initialize RC522
void initRC522() {
  for (byte i = 0; i < NR_OF_READERS; i++) {
    mfrc522[i].PCD_Init(ssPins[i], RST_PIN); // Init each MFRC522 card
    mfrc522[i].PCD_DumpVersionToSerial();
    // Configure the interrupt pin
    pinMode(irqPins[i], INPUT_PULLUP);
    attachInterrupt(digitalPinToInterrupt(irqPins[i]), handleRFIDInterrupt, FALLING);
  }
}

// ISR to handle RFID interrupt
void ICACHE_RAM_ATTR handleRFIDInterrupt() {
  // Loop through all readers to check the IRQ pin state
  for (byte i = 0; i < NR_OF_READERS; i++) {
    // Check if the IRQ pin is LOW (indicating an interrupt)
    if (digitalRead(irqPins[i]) == LOW) {
      // Check if a new card is present
      if (mfrc522[i].PICC_IsNewCardPresent() && mfrc522[i].PICC_ReadCardSerial()) {
        Serial.print("Card detected on reader ");
        Serial.println(i);
        
        // Retrieve and print the UID
        Serial.print("Card UID: ");
        for (byte j = 0; j < mfrc522[i].uid.size; j++) {
          Serial.print(mfrc522[i].uid.uidByte[j] < 0x10 ? " 0" : " ");
          Serial.print(mfrc522[i].uid.uidByte[j], HEX);
        }
        Serial.println();

        // Write a string to block 4
        writeStringToBlock(mfrc522[i], 4, "Hello, RFID!");

        // Read data from block 4
        readStringFromBlock(mfrc522[i], 4);

        mfrc522[i].PICC_HaltA(); // Halt PICC
      }
    }
  }
}

void setup() {
  // Serial port for debugging purposes
  Serial.begin(115200);

  // Serial.print("MOSI: ");
  // Serial.println(MOSI);
  // Serial.print("MISO: ");
  // Serial.println(MISO);
  // Serial.print("SCK: ");
  // Serial.println(SCK);
  // Serial.print("SS: ");
  // Serial.println(SS);  

  // Initialize SPI2
  initSPI2();

  // Initialize RC522
  initRC522();

}

void loop() {

}

void writeStringToBlock(MFRC522 &rfid, byte blockAddr, String data) {
  byte buffer[18];
  data.getBytes(buffer, sizeof(buffer));

  // Ensure the data fits in the block (16 bytes)
  if (data.length() > 16) {
    Serial.println("Data too long for block");
    return;
  }

  // Pad the buffer with zeros if necessary
  for (byte i = data.length(); i < 16; i++) {
    buffer[i] = 0;
  }

  MFRC522::StatusCode status = rfid.MIFARE_Write(blockAddr, buffer, 16);
  if (status != MFRC522::STATUS_OK) {
    Serial.print("MIFARE_Write() failed: ");
    Serial.println(rfid.GetStatusCodeName(status));
  } else {
    Serial.println("Data written to block successfully");
  }
}

void readStringFromBlock(MFRC522 &rfid, byte blockAddr) {
  byte buffer[18];
  byte size = sizeof(buffer);

  MFRC522::StatusCode status = rfid.MIFARE_Read(blockAddr, buffer, &size);
  if (status != MFRC522::STATUS_OK) {
    Serial.print("MIFARE_Read() failed: ");
    Serial.println(rfid.GetStatusCodeName(status));
    return;
  }

  Serial.print("Data from block ");
  Serial.print(blockAddr);
  Serial.print(": ");
  for (byte i = 0; i < 16; i++) {
    Serial.write(buffer[i]);
  }
  Serial.println();
}
The output keeps giving me this:
Firmware Version: 0x0 = (unknown)
WARNING: Communication failure, is the MFRC522 properly connected?
Firmware Version: 0x0 = (unknown)
WARNING: Communication failure, is the MFRC522 properly connected?
Firmware Version: 0x0 = (unknown)
WARNING: Communication failure, is the MFRC522 properly connected?

Using VS Code with PlatformIO.
.ini:
[env:esp32-s3-devkitc-1]
platform = espressif32
board = esp32-s3-devkitc-1
framework = arduino
monitor_speed = 115200
lib_deps =
miguelbalboa/MFRC522@^1.4.11


Any help is appreciated. I have scoured the internet for a solution. SPI should not be that hard...not sure why it's made so hard.

haz_coder
Posts: 5
Joined: Sat Oct 26, 2024 3:52 pm

Re: ESP32-S3 SPI interface to RC522

Postby haz_coder » Sun Oct 27, 2024 11:42 pm

I figured it out.
Replaced hspi with just SPI in the below
hspi.begin(SPI2_SCK, SPI2_MISO, SPI2_MOSI, SS_PIN_0);.

So SPI.Begin...

Works given I am using the standard pins. Not sure how you'd go about using SPI2 or SPI3 with your pins...don't need it for my project, but not straight forward it seems.

There is a few other items in the code that I had to change for properly setting up the IRQ, but had to get the SPI working to get to the rest.

woosop
Posts: 1
Joined: Mon Mar 17, 2025 3:18 pm

Re: ESP32-S3 SPI interface to RC522

Postby woosop » Mon Mar 17, 2025 3:28 pm

Hi, I am trying to configure XIAO ESP32-C3 with RC522. Do you have any suggestions? Can it be possible?

woo

lbernstone
Posts: 1131
Joined: Mon Jul 22, 2019 3:20 pm

Re: ESP32-S3 SPI interface to RC522

Postby lbernstone » Wed Mar 19, 2025 1:32 am

AFAIK the example should work. Just call SPI.begin with the correct parameters.

horace99
Posts: 34
Joined: Mon Oct 14, 2024 10:38 am

Re: ESP32-S3 SPI interface to RC522

Postby horace99 » Sun Mar 23, 2025 10:50 am

this works on a ESP32-C3-MINI-1

Code: Untitled.cpp Select all


// ESP32-C3 MRFC522 RFID reader

#include <MFRC522v2.h>
#include <MFRC522DriverSPI.h>
#include <MFRC522DriverPinSimple.h>
#include <MFRC522Debug.h>

// ESP32-C3 pins used by MFRC522 RFID reader (VCC to 3.3V)
#define SCK 4
#define MISO 5
#define MOSI 6
#define CS 7

MFRC522DriverPinSimple ss_1_pin(CS); // Configurable, take an unused pin, only HIGH/LOW required, must be different to SS 2.
MFRC522DriverSPI driver_1{ ss_1_pin};
MFRC522 reader = driver_1; // Create MFRC522 instance.

void setup() {
Serial.begin(115200); // Initialize serial communications with the PC for debugging.
while (!Serial)
; // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4).
Serial.println("\n\nESP32-C3 MFRC522");
reader.PCD_Init(); // Init each MFRC522 card.
Serial.print(F("Reader "));
static uint8_t i = 0;
i++;
Serial.print(i);
Serial.print(F(": "));
MFRC522Debug::PCD_DumpVersionToSerial(reader, Serial);
}

/**
* Main loop.
*/
void loop() {
delay(2000);
Serial.println("reading RFID");
// Look for new cards.
if (reader.PICC_IsNewCardPresent() && reader.PICC_ReadCardSerial()) {
Serial.print(F("Reader "));
static uint8_t i = 0;
i++;
Serial.print(i);

// Show some details of the PICC (that is: the tag/card).
Serial.print(F(": Card UID:"));
MFRC522Debug::PrintUID(Serial, reader.uid);
Serial.println();

Serial.print(F("PICC type: "));
MFRC522::PICC_Type piccType = reader.PICC_GetType(reader.uid.sak);
Serial.println(MFRC522Debug::PICC_GetTypeName(piccType));

// Halt PICC.
reader.PICC_HaltA();
// Stop encryption on PCD.
reader.PCD_StopCrypto1();
}
}
serial output

Code: Untitled.cpp Select all

ESP32-C3 MFRC522
Reader 1: Firmware Version: 0x92 = v2.0
reading RFID
reading RFID
Reader 1: Card UID: 15 64 FD C2
PICC type: MIFARE 1KB
reading RFID
reading RFID
reading RFID
reading RFID
reading RFID
Reader 2: Card UID: BF EC 0C 04
PICC type: MIFARE 1KB
reading RFID
reading RFID
reading RFID
Reader 3: Card UID: C3 65 94 95
PICC type: MIFARE 1KB

Who is online

Users browsing this forum: No registered users and 1 guest