RFID Card Reader

Hey guys,

A friend of mine was building a RFID door opener, but got stuck and handed it to me. I'm also kinda stuck and wondering if it's actually possible.

I have an Arduino Mega, with a Ethernet/SD card shield attached:

There is also an RFID-RC522 connected to the shield.

Most of the core code is done, at the moment you can swipe a card and it'll check the EEPROM, if the code matches a code stored in EEPROM, it unlocks a relay.

My friend wants the codes to be stored on an SD card, not the EEPROM, with a web interface so he can update the codes via a web page.

I started adding the code, I've got the ethernet up and I can ping it. When the unit boots, it also lists the contents of the SD card out via serial.

The problem is: Any time the code that initializes the SD card reader is called, the RFID reader stops reading, when you swipe a card over it, nothing happens.

comment out the line that calls the SD card init, and the RFID reader works again.

I'm new-ish to Arduino, so did some digging and found that the RFID, Ethernet and SD card all use the SPI Bus.

Further to this, the SD card and RFID both use pin 53 (which as far as I can tell isn't a physical pin?)

Is what we're trying to do possible? or are there too many conflicting devices on the SPI bus?

The line of code that breaks RFID is:

if (!card.init(SPI_HALF_SPEED, chipSelect)) {

chipSelect is defined here:

const int chipSelect = 53;

and the code that initializes the RFID reader is here:

#define SS_PIN 53
#define RST_PIN 49
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance.

Can one of the devices be moved to another pin? I looked but those pin numbers above don't match physical pins.

The Arduino Ethernet Shield uses Pin 10 for the Ethernet SlaveSelect/ChipSelect and Pin 4 for the SD Card SlaveSelect/ChipSelect. Neither should be using 53.

Pick an otherwise unused pin for the RFID SlaveSelect/ChipSelect. Check the Ethernet Shield documentation to see what pins they use and DON'T use one of them. Also, don't use Pin 0 or Pin 1 which are the Serial pins. And don't use Pin 53 for anything but a digital output. If you use it as an input, the SPI hardware will think you want to be a Slave instead of a Master.

Thanks John,

I had another look and I can see the RFID reader is plugged into those pins (hidden by the Ethernet shield)...

The CS pin was plugged into pin 53, but I have moved it to 47. I tested as-is to make sure I had moved the correct pin and the reader wouldn't start, which was what I expected.

I then updated the code and changed

const int chipSelect = 53;


const int chipSelect = 47;

This got the reader working again, so I'm pretty sure I moved the right wire.

I also changed:

if (!card.init(SPI_HALF_SPEED, chipSelect)) {


if (!card.init(SPI_HALF_SPEED, 4)) {

But the problem still remains. If I comment out the above code, the SD card reader doesn't start (obviously) but the RFID reader works fine.

If I leave that code uncommeted, the SD card reader starts, and outputs the contents of the SD card on boot, but the RFID reader won't read. The debug output says the RFID reader starts fine, but waving cards around it doesn't trigger the unlock code.

It is possible that one or more of the libraries are old enough that they don't use SPI.beginTransction() and SPI.endTransaction() or the rough equivalent. There are various SPI settings that might be different for different devices. Each device should refresh the settings before using the SPI interface, in case some other device set them to different values. The begin and end functions also prevent a different device from using SPI in the middle of an SPI transaction.

You may have to find an updated library to take care of that for you.