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.

Who is online

Users browsing this forum: No registered users and 49 guests