Esp32 + rfid + microsd

Buen día Foro!
En mi proyecto, necesito implementar el Modulo RFID (MRFC522) y el Módulo MicroSD.

El ESP32 que estoy utilizando es el DOIT-DEV-KIT-V1 y especificamente hay un altercado en el Pin MISO (D18) de ambos, ya que si los conecto ambos, solo considera el de la MicroSD, y si los conecto de forma individual (probando uno a uno) los dos módulos me funcionan correctamente.

inclusive, probe el RFID individual y el pin MISO lo conecte al (D21) y me leia sin problemas.
Probe ambos, MISO de la MicroSD al (D18) y MISO del RFID al (D21) y seguia tomando solo el de la MicroSD.

Tengo en aquí mismo una resistencia de 330 ohm 1/2w, por si me surgieren algo, quedo atento sus comentarios.

(anexare el codigo como de prueba para hacer funcionar ambos módulos luego de ser asi ponerlos en mi proyecto, pero no he tenido exito):

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

#define SS_RFID 27  // Pin SS para el lector RFID
#define SS_SD 5     // Pin SS para la tarjeta MicroSD
#define RST_RFID 25  // Pin RST para el lector RFID

MFRC522 mfrc522(SS_RFID, RST_RFID);
File myFile;

void setup() {
  Serial.begin(9600);
  Serial.println("INICIAR..");
  pinMode(SS_RFID, OUTPUT);
  pinMode(SS_SD, OUTPUT);  
  
  // Inicializar el lector RFID
  SPI.begin();
  mfrc522.PCD_Init();
  
  // Inicializar la tarjeta MicroSD
  if (!SD.begin(SS_SD)) {
    Serial.println("Error al inicializar la tarjeta SD.");
    while (1);
  } 
  Serial.println("TARJETA INICIADA...");
  
}

void loop() {


  // Verificar la presencia de una tarjeta RFID
  if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) {
    // Desactivar CS del MicroSD
    
 digitalWrite(SS_SD, HIGH);

    // Obtener el UID de la tarjeta RFID
    String uid = "";
    for (byte i = 0; i < mfrc522.uid.size; i++) {
      uid += String(mfrc522.uid.uidByte[i] < 0x10 ? "0" : "");
      uid += String(mfrc522.uid.uidByte[i], HEX);
    }
    Serial.println(uid);

    // Activar CS del MicroSD nuevamente
    digitalWrite(SS_SD, LOW);
    
    // Detener la lectura de la tarjeta RFID
    //mfrc522.PICC_HaltA();

    // Guardar el UID en un archivo en la MicroSD
    myFile = SD.open("/datos.txt", FILE_WRITE);
    if (myFile) {
      myFile.println(uid);
      myFile.close();
      Serial.println("Datos guardados en la tarjeta SD.");
    } else {
      Serial.println("Error al abrir el archivo en la tarjeta SD.");
    }
  } 
  
  // Tu código principal aquí
}

No hay ningún problema. Todos los dispositivos SPI comparten 3 lineas. Lee acerca del tema.
Comparten MOSI, MISO y SKL que es el reloj que sincroniza. Luego cada dispositivo tiene una línea llamada CS Chip Select, que selecciona el Integrado sea la SD o sea el lector RFID y establece la comunicación y luego lo pone en deshabilitado.
Asi que solo usa dos CS diferentes para queda módulo y todo funcionara.
En tu código veo que haces eso

#define SS_RFID 27  // Pin SS para el lector RFID
#define SS_SD 5     // Pin SS para la tarjeta MicroSD

Esto lo retiras del setup()

  pinMode(SS_RFID, OUTPUT);
  pinMode(SS_SD, OUTPUT);  

Ambas librerías lo hacen por su cuenta.
Prueba a ver si cambia algo.

Sigue sin funcionar, hice multiples pruebas, colocando el cambiador de nivel ALTO o BAJO en puntos especificos donde recorre el codigo, pero nada.
Incluso, aun así, se inicia el modulo MicroSD, pero el RFID sigue sin poder leer, cuando comente este if:

  // Inicializar la tarjeta MicroSD
  if (!SD.begin(SS_SD)) {
    Serial.println("Error al iniciar Modulo MicroSD..");
    //while (1);
  } 

aunque deje librerias del SD y lo demas del SD, me leyo el RFID, algo pasa que al detectar la tarjeta, el RFID no arranca.

Asi tengo el codigo actualmente:

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

#define SS_RFID 27  // Pin SS para el lector RFID
#define SS_SD 5     // Pin SS para la tarjeta MicroSD
#define RST_RFID 25  // Pin RST para el lector RFID

MFRC522 mfrc522(SS_RFID, RST_RFID);
File myFile;

void setup() {
  Serial.begin(9600);
  Serial.println("INICIAR..");
  
  // Inicializar el lector RFID
  SPI.begin();
  mfrc522.PCD_Init();
  
  // Inicializar la tarjeta MicroSD
  if (!SD.begin(SS_SD)) {
    Serial.println("Error al iniciar Modulo MicroSD..");
    //while (1);
  } 
  Serial.println("TARJETA INICIADA...");
  
  
}

void loop() {

  // Verificar la presencia de una tarjeta RFID
  if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) {
    // Desactivar CS del MicroSD

    // Obtener el UID de la tarjeta RFID
    String uid = "";
    for (byte i = 0; i < mfrc522.uid.size; i++) {
      uid += String(mfrc522.uid.uidByte[i] < 0x10 ? "0" : "");
      uid += String(mfrc522.uid.uidByte[i], HEX);
    }
    Serial.println(uid);

    // Activar CS del MicroSD nuevamente
    digitalWrite(SS_SD, LOW);
    digitalWrite(RST_RFID, HIGH);
    
    // Detener la lectura de la tarjeta RFID
    //mfrc522.PICC_HaltA();

    // Guardar el UID en un archivo en la MicroSD
    myFile = SD.open("/datos.txt", FILE_WRITE);
    if (myFile) {
      myFile.println(uid);
      myFile.close();
      Serial.println("Datos guardados en la tarjeta SD.");
    } else {
      Serial.println("Error al abrir el archivo en la tarjeta SD.");
    }

    digitalWrite(RST_RFID, LOW);
  } 
  
  // Tu código principal aquí
}

Inclusive, dejando todo como esta, sin comentar nada, solo desconecte el pin MISO del Modulo MicroSD, esta en (D18), el RFID me lee sin problemas.
El MISO del RFID lo tengo en (D21).

El problema esta en el pin MISO del Módulo MicroSD.

Los pines SPI del ESP32 no van donde tu quieras. Hay pines dedicados.
Busca cuales corresponde a tu ESP32.
Aca los tienes


MOSI GPIO23
MISO GPIO19
SCK GPIO18

La mayoría de los módulos microSD (no digo todos porque tal vez haya alguno bien diseñado) tienen un pequeño detalle, nunca ponen MISO en alta impedancia.
El problema es que en lugar de tener conectada la habilitación de la salida del buffer al CS del módulo la han conectado a masa, entonces la salida está siempre activa.
La solución, aunque complicada, es modificar la placa.

En tu caso, una solución sin tener que modificar la placa puede ser usar el segundo puerto SPI, de esa forma no habría "colisiones" entre las señales MISO por estar en pines diferentes.

Respecto al ESP32 DevKit V1, que pines son del segundo puerto SPI?

Google: "ESP32 DevKit v1 pinout"

Okey, HSPI y VSPI, voy a probar por individual en el HSPI, si me da el RFID, colocare la mciroSD en el VSPI haber si me funciona

Para que tengas de guía (si lo llegas a necesitar)

https://espressif-docs.readthedocs-hosted.com/projects/arduino-esp32/en/latest/api/spi.html

Usar los 2 buses SPI funciona, tengo una SD en el HSPI y una pantalla, que no usa CS entonces mantiene el bus "capturado", en el VSPI.

Aquí me confirmas que el RFID va al HSPI y la MicroSD va al VSPI?

Conectalos como prefieras.

Intente con las indicaciónes aquí dada, casi toda la noche, no pude.

Intente con esto:

// Conexiones para la tarjeta MicroSD en el bus SPI HSPI
#define SS_RFID      15  // Pin SS para el lector RFID
#define RST_RFID     25  // Pin RST para el lector RFID
#define SCK_RFID     14   // Pin de SCK para RFID
#define MISO_RFID    12   // Pin de MISO para RFID
#define MOSI_RFID    13   // Pin de MOSI para RFID


// Conexiones para la tarjeta MicroSD en el bus SPI VSPI
#define SS_SD      5    // Pin de Slave Select (CS) para la tarjeta MicroSD
#define SCK_SD     18   // Pin de SCK para la tarjeta MicroSD
#define MISO_SD    19   // Pin de MISO para la tarjeta MicroSD
#define MOSI_SD    23   // Pin de MOSI para la tarjeta MicroSD

MFRC522 mfrc522(SS_RFID, RST_RFID);
File myFile;

void setup() {
  Serial.begin(9600);
  Serial.println("INICIAR..");
  
  SPI.begin(SCK_RFID, MISO_RFID, MOSI_RFID, SS_RFID);
  mfrc522.PCD_Init();

  SPIClass& sdSPI = SPI;
  sdSPI.begin(SCK_SD, MISO_SD, MOSI_SD, SS_SD); 
  
  if (!SD.begin(SS_SD)) {
    Serial.println("Error al inciar el Modulo MicroSD");
  }    
  
  Serial.println("TARJETA INICIADA...");
  
}

tampoco pude, ahora mismo estoy revisando la libreria de SPI, estoy en la hoja "SPI.cpp" y especificamente este metodo, leyendo su estructura el solo toma uno de los puertos, ya sea VSPI o HSPI, en este caso, esta tomando el HSPI (donde tengo conectado el RFID)
el VSPI no lo esta tomando, ya que al iniciar el monitor serial, da este estos dos errores:

INICIAR..
[ 615][E][sd_diskio.cpp:805] sdcard_mount(): f_mount failed: (3) The physical drive cannot work
[ 1116][E][sd_diskio.cpp:126] sdSelectCard(): Select Failed
Error al inciar el Modulo MicroSD

Las conexiones esta arriba de este mismo comentario.

void SPIClass::begin(int8_t sck, int8_t miso, int8_t mosi, int8_t ss)
{
    if(_spi) {
        return;
    }

    if(!_div) {
        _div = spiFrequencyToClockDiv(_freq);
    }

    _spi = spiStartBus(_spi_num, _div, SPI_MODE0, SPI_MSBFIRST);
    if(!_spi) {
        return;
    }

    if(sck == -1 && miso == -1 && mosi == -1 && ss == -1) {
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
        _sck = (_spi_num == FSPI) ? SCK : -1;
        _miso = (_spi_num == FSPI) ? MISO : -1;
        _mosi = (_spi_num == FSPI) ? MOSI : -1;
        _ss = (_spi_num == FSPI) ? SS : -1;
#elif CONFIG_IDF_TARGET_ESP32C3
        _sck = SCK;
        _miso = MISO;
        _mosi = MOSI;
        _ss = SS;
#else
        _sck = (_spi_num == VSPI) ? SCK : 14;
        _miso = (_spi_num == VSPI) ? MISO : 12;
        _mosi = (_spi_num == VSPI) ? MOSI : 13;
        _ss = (_spi_num == VSPI) ? SS : 15;
#endif
    } else {
        _sck = sck;
        _miso = miso;
        _mosi = mosi;
        _ss = ss;
    }

    spiAttachSCK(_spi, _sck);
    spiAttachMISO(_spi, _miso);
    spiAttachMOSI(_spi, _mosi);

}

Ahora no puedo fijarme porque no estoy en casa pero más tarde te paso como tengo hecha la inicialización de los puertos SPI en el código que tengo funcionando.
Teneme paciencia. :wink:

1 Like

Te espero :> estoy al pendiente

Bueno, nada del otro mundo...

Para la pantalla uso el VSPI porque es el que usa por defecto la librería TFT_eSPI.
Para la SD, obviamente el HSPI.
En el código

#include <SPI.h>

SPIClass sdSPI = SPIClass(HSPI);

#include <SD.h>

#define SS_SD 15

// y en setup()

if (!SD.begin(SS_SD)) {  // otra forma SD.begin(SS_SD, sdSPI)

Probá repetir esta configuración, conectando el lector en VSPI y la SD en HSPI.

Tené en cuenta que por defecto se usa el puerto VSPI así que no hace falta definirlo.

Gracias, lo acabe de probar, asi como me indicaste, tengo el lector en VSPI y la microSD en HSPI, en primera instancia, no me funciono ninguno de los dos, luego en "setup()" invoque "SPI.begin()" pero solo me funciono el RFID:


#include <SPI.h>

SPIClass sdSPI = SPIClass(HSPI);

#include <MFRC522.h>
#include <SD.h>

 // Conexiones para la tarjeta MicroSD en el bus SPI HSPI
#define SS_RFID      5  // Pin SS para el lector RFID
/*#define RST_RFID     25  // Pin RST para el lector RFID
#define SCK_RFID     14   // Pin de SCK para RFID
#define MISO_RFID    12   // Pin de MISO para RFID
#define MOSI_RFID    13   // Pin de MOSI para RFID */


// Conexiones para la tarjeta MicroSD en el bus SPI VSPI
#define SS_SD      15    // Pin de Slave Select (CS) para la tarjeta MicroSD
/*#define SCK_SD     18   // Pin de SCK para la tarjeta MicroSD
#define MISO_SD    19   // Pin de MISO para la tarjeta MicroSD
#define MOSI_SD    23   // Pin de MOSI para la tarjeta MicroSD */


MFRC522 mfrc522(SS_RFID, 25);
File myFile;

void setup() {
  Serial.begin(9600);
  Serial.println("INICIAR..");
  
  SPI.begin();
  // Inicializar el lector RFID
  mfrc522.PCD_Init();

  
  if (!SD.begin(SS_SD, sdSPI)) {
    Serial.println("Error al inciar el Modulo MicroSD");
  }    
  
  Serial.println("TARJETA INICIADA...");
  
}

void loop() {

  // Verificar la presencia de una tarjeta RFID
  if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) {
    // Desactivar CS del MicroSD

    // Obtener el UID de la tarjeta RFID
    String uid = "";
    for (byte i = 0; i < mfrc522.uid.size; i++) {
      uid += String(mfrc522.uid.uidByte[i] < 0x10 ? "0" : "");
      uid += String(mfrc522.uid.uidByte[i], HEX);
    }
    Serial.println(uid);

    // Activar CS del MicroSD nuevamente
    //digitalWrite(SS_SD, LOW);
    
    // Detener la lectura de la tarjeta RFID
    mfrc522.PICC_HaltA();

    // Guardar el UID en un archivo en la MicroSD
    myFile = SD.open("/datos.txt", FILE_APPEND);
    if (myFile) {
      myFile.println(uid);
      myFile.close();
      Serial.println("Datos guardados en la tarjeta SD.");
    } else {
      Serial.println("Error al abrir el archivo en la tarjeta SD.");
    } 

  } 
  
}

Terminal:

INICIAR..
[   604][E][sd_diskio.cpp:805] sdcard_mount(): f_mount failed: (3) The physical drive cannot work
[  1105][E][sd_diskio.cpp:126] sdSelectCard(): Select Failed
Error al inciar el Modulo MicroSD
TARJETA INICIADA...
bad128be
[  4508][E][vfs_api.cpp:24] open(): File system is not mounted
Error al abrir el archivo en la tarjeta SD.

allí claramente leyo la tarjeta, salio el codigo.

¿Verificaste el formato de la SD, es FAT32?

Claro, la formatee a FAT32, incluso, me percarte que no estaba alimentado la microSD (pin mal colocado) y cuiando eso paso, ya no me permitia cargar el codigo y cuando abria el monitor serial, salia muchas letras raras haciendo recorrido, creo que es el PIN12 que molesta al iniciar.

por el alto consumo de energia de la MicroSD, si o si debe estar el RFID en HSPI, hare retornar todo y pruebo nuevamente.

Si, es probable que el MISO siempre conectado "moleste", la verdad es que tengo un lector de microSD pero hasta ahora no lo usé.
También tengo un lector RFID, voy a ver si los pruebo con el ESP32...

Me parece raro lo que me decís del consumo de la memoria, yo no he tenido ningún problema.

Lo voy a probar