SD CARD and RFID not working together / spi conflict

hi everyone, ı am new member in arduino forum.
ı want to work sd card with rfid card reader but sd card and rfid card reader not working together. sd card is connect true but rfid card reader isnt reading card. ı think due to two modeles' spi conflict they arent working together. how can ı overcome this problem?
Also modules' mıso,mosı,sck pins same but cs pin is different

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

#define CS_RFID 10
#define RST_RFID 9
#define CS_SD 4

File myyFile;

MFRC522 rfid(CS_RFID,RST_RFID);

String uidString;

void setup() {
  
  pinMode(CS_RFID,OUTPUT);
  digitalWrite(CS_RFID,HIGH);
  pinMode(CS_SD,OUTPUT);
  digitalWrite(CS_SD,HIGH);

  Serial.begin(9600);
  SPI.begin();
  rfid.PCD_Init();
   Serial.print("connect SD card ...");
  if(!SD.begin(CS_SD)) {
    Serial.println("sd card fail");}
    else {
      Serial.print("sd true");
    }
  }
  

void loop() {
  digitalWrite(CS_RFID,LOW);
  
  if(rfid.PICC_IsNewCardPresent()){
    readRFID();
    digitalWrite(CS_RFID,HIGH);
    writeSD();
  }
delay(10);

}
void readRFID(){
  rfid.PICC_ReadCardSerial();
  Serial.print("Tag uid: ");
   uidString = String(rfid.uid.uidByte[0]) + " " + String(rfid.uid.uidByte[1]) + " " + 
    String(rfid.uid.uidByte[2]) + " " + String(rfid.uid.uidByte[3]);
    Serial.print(uidString);
}
void writeSD(){
  digitalWrite(CS_SD,LOW);
  myyFile=SD.open("DATA2.txt",FILE_WRITE);
   if (myyFile) {
    Serial.println("File opened ok");
    myyFile.print(uidString);
    myyFile.print(", "); 
   }
digitalWrite(CS_SD,HIGH);
}

1 Like

Some SD card modules will not play well with other devices on the SPI bus. The problem is with the way the level shifter on the SD module is wired. The ones that do not work well have the MISO signal running through the level shifter. That causes the MISO signal to not be released so that the other devices can control it. The modules made by Adafruit (and some others) have the MISO signal going from the SD card straight to the MISO, bypassing the level shifter. Look at the schematic for the Adafruit module to see what to look for. DO (data out) is the MISO signal.

Post photos of your SD card module.

1 Like


This video may help you. This tutorial use SD card and RFID reader together.

In post #11 of this thread there is a schematic of the SD module that shows the MISO line going through the level shifter.

I didn't understand what I'm supposed to do

Hello, maybe it's a little late, but I had the same problem, and looking around the forum I found that you have to put a ~330 Ohm resistor between the common MISO pin and the SD card MISO pin.
Hope works for you.

To any one still finding an answer like me.
330 ohms resistor? Did not work
High Low Output for CS/SS SD card module? Did not work
Chinese made module that might possibly the reason why so many of these solution doesn't work? Most probably

My only solution to this is using a transistor
NPN transistor that has a 1K ohm resistor on its base that is controlled by a output pin on any arduino pin
The Collector is connected to the MISO SD card
The Emitter is connected to the MISO Arduino pin

You can then set the transistor pin to high so that the arduino will read the SD card module.

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

#define RST_PIN 9
#define RFID_SS_PIN 8
MFRC522 mfrc522(RFID_SS_PIN, RST_PIN);
#define SD_SS_PIN 4
#define transistor 7

void setup()
{
  pinMode(transistor, OUTPUT);
  
  Serial.begin(9600);
  SPI.begin(); // Init SPI bus

  Serial.print("Initializing SD card...");

  digitalWrite(transistor, HIGH);

  if (!SD.begin(SD_SS_PIN))
  {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");
  digitalWrite(transistor, LOW);

  mfrc522.PCD_Init();
}
1 Like

First of all I must say that this solution that I will put here is definitive, BUT it is done with unconventional tools, such as an air soldering station, to remove the integrated circuit from the board, and a microscope to make the cutting and tracing work.

The SPI BUS has 4 wires, three of them goes from the MASTER (Arduino) to the SLAVEs (external SPI boards): MOSI (Master-Out to Slave-In, sends data from the Arduino to the slave boards), the clock signal, where the Ardunio controls the times of the signals, and the SS or slave selector, which chooses which of the SPI slaves it will work with. To keep in mind for this work, this signal activates the slave by a LOW signal, while if it is HIGH, the slave comes to disabled. And the fourth wire, MISO (Master-In Slave-Out), which goes from the SLAVEs to the MASTER (Arduino), carrying the signal with the data of all the slaves. If two or more of these signals (coming from two or more SPI devices connected to the SPI bus at the same time) are on the MISO BUS wire at the same time, they overlap, generating interference and invalid data.

The SD card module uses a 74ABT125PW integrated circuit to control the four wires of the SPI bus. For this, it uses four line controllers with 3-state outputs: output in L or H same state of the input when the controller is LOW, and high impedance ("off", "no voltage") if the controller is HIGH, controlled by output enablers (OE pins), as if they were a transistor. In particular, these inputs enable the output by LOW signal, and not HIGH (like NPN transistors does). We can see in the module diagram, that these pins (OE, pins 1, 4, 10 and 13), are ALL grounded, so the enablers are ALWAYS enabling the four controllers. Enabling those that go from Master to Slave does not affect the operation of the SPI bus. But constantly enabling the MISO wire is a circuit design error, since the board would be constantly sending its information, even if it is not its turn (chosen by the SS). So, how to solve it? As the drivers of the integrated circuit are activated by LOW and what was said before about the SS signal (that it also enables by LOW signal), we are going to use the state of the SS pin as a driver enabler that activates or deactivates the MISO wire (pin 13) of the module. The SS wire enters through pin 8 and exits through pin 9, and can be connected to any of them, since being always active, the input signal will be the same as the output signal. For convenience of location and circuit, we will use the output, pin 9. So, the objective is to join them: that pin 9 sends its signal to pin 13.

To start, we desolder the integrated circuit 74ABT125PW

Here we have pins 13 and 8, which we must connect to each other.
As you can see in the yellow circle, pin 13 is connected to ground.
In the green circle there is a pass to the other side of the tile, where there is more mass, so at work we must leave it outside the line that we are going to try to do. If we remove it completely, there is no problem, since the masses will continue to be connected, for example in the same way in the blue circle. Anyway, after doing the new path, you can test continuity between pins 1 and 7 (in the brown circles) of the integrated circuit.

Once the path is done, we will scrape where the yellow circles are, until leaving the copper in sight. Then we will join the two tracks directly with tin (if you can't, put some wire on it)

And here we've got it finished

finally we solder the integrated circuit again

we can see how the tin sticks out a bit under the IC

And finally, since the problem was with RFID that works with 3V3, and that this module internally also works with 3V3, after lowering the 5V input with a 1117, I removed the regulator and joined the input with the exit pins. Just be carrefull, now the module MUST BE powered with 3V3 only

In my sketches I enable the board that I am going to use (setting them to LOW) and I disable the others (setting them to HIGH) every time I am going to use one of them, since I don't know if libraries do it internally.
Xakko

2 Likes

Oh my, thats a deep knowledge. Im having the same issues... I will try to change the SD module before going into this but its quite a definitive solution. Controlling the RFID via I2c bus seems to be another option but i cant find the propper library.

I hope I dont have to use your solution for hundreds of sd modules!

1 Like

The Adafruit micro SD module is wired so that the MISO signal bypasses the level shifter.

An easier solution than that depicted in post #9 is to pry the enable pin (pin 13) of the IC up from the board, and run a jumper from that pin to the chip select line (pin 8). No need to actually remove the chip.

Yes, thats right. but unsolder the pin 13 and solder a wire in it, without an special soldering iron for the very small IC, is not so easy. if you can use a heat station, you can see its much easier work with it. I know it is not a "normal" machine, but it is much easier and with less risk of damaging the circuit unsolder and solder again the IC with it.

serious question: is there anything that speaks against the NPN transistor solution?

I'm a bit confused because it is ignored by others, but it totally works for me after I tried everything else that @idontdohardware also mentions without any success.

I don't have any adafruit module available neither want to hack my cheap module like described in #9 or other posts.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.