Why MFRC522 can not work with SD module
Besides learning to post your code correctly, perhaps you need to NOT use the SPI pins for anything else.
Pins 10, 11, 12, and 13 are off limits when using the SPI bus. Pin 10 must be an OUTPUT.
Where in your program do you set up 2 different SS pins.
Mark
They are CS (chip select) pins. The Arduino pin 10 is called SS because it functions
as "Slave Select" when using the SPI hardware in slave mode (which is very rarely
done). To allow multiple masters to work the SPI hardware will automatically switch
to slave mode if SS is made an input, which is why it has to be left as an output
(any pin can be used as CS's, pin 10 is just conveniently already setup as an output
when using SPI in master mode).
Back to the plot:
Using more than one SPI device is fraught because different devices may use
different modes, clock speeds and may not be SPI compliant in the first place
(for instance an SPI device should make MISO tri-state instantly if the CS goes high)
Some devices malfunction if the clock speed is too high, limiting the speed for
all devices on the SPI bus. Each device must ignore clock pulses if not selected
and every device must require the clock line to be in the same state on idle
(in other words some SPI modes are incompatible with each other).
I've seen several chips purporting to support both I2C and SPI but in fact their
SPI support was broken.
holmes4:
Where in your program do you set up 2 different SS pins.Mark
Here:
#define SS_PIN 10
#define RST_PIN 9
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance.
and here:
if (!SD.begin(4)) {
But, OP, you never set pin 10 as OUTPUT, which is required for SPI to work at all. You really should pick a different pin to use as the SS pin for the MFRC522.
MFRC522 Libarary sets SS pin as OUTPUT
pinMode(_chipSelectPin, OUTPUT);
Reference/SPI says
When a device's Slave Select pin is low, it communicates with the master. When it's high, it ignores the master. This allows you to have multiple SPI devices sharing the same MISO, MOSI, and CLK lines.
Do not init RC522 module in setup. Write SD SS pin LOW and init RFID Module in loop Scan a Card when a card once scanned Write RFID module's SS pin LOW then init SD Module
I modified your code but it trowed an error (IDE 1.0.5 r2) : call of overloaded 'String(byte [10], int)' is ambiguous
Do you need buffer ? i removed it and renewed CardID String code, now it compiles but i dont have any SD Module to test.
#include <SPI.h>
#include <MFRC522.h>
#include "Wire.h"
#include <SD.h>
//#define DS1307_ADDRESS 0x68
#define DS1307_I2C_ADDRESS 0x68 // the I2C address of Tiny RTC
#define SDSSPIN 4
File myFile;
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
String CardID = "";
#define SS_PIN 10
#define RST_PIN 9
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance.
void setup() {
Serial.begin(9600); // Initialize serial communications with the PC
digitalWrite(SS_PIN, LOW); //Make sure RFID SS pin is LOW
SPI.begin(); // Init SPI bus
SD.begin(SDSSPIN); // For testing purpose
if (!SD.begin(SDSSPIN)) {
Serial.println("SD Module initialization failed!");
return;
}
Serial.println("SD Module initialization done.");
Wire.begin();
Serial.println("Scan a MIFARE Classic PICC to demonstrate Value Blocks.");
}
void loop() {
digitalWrite(SDSSPIN, LOW); //Make sure SD SS Pin is LOW we are going to use RFID first
mfrc522.PCD_Init(); // Init MFRC522 card
// Look for new cards
if ( ! mfrc522.PICC_IsNewCardPresent()) {
return;
}
// Select one of the cards
if ( ! mfrc522.PICC_ReadCardSerial()) {
return;
}
// Dump debug info about the card. PICC_HaltA() is automatically called.
//mfrc522.PICC_DumpToSerial(&(mfrc522.uid));
// Dump UID
CardID=("");
Serial.print("Card UID:");
for (byte i = 0; i < mfrc522.uid.size; i++) {
CardID += String(mfrc522.uid.uidByte[i] < 0x10 ? "0" : "");
CardID += String(mfrc522.uid.uidByte[i], HEX);
}
Serial.println(CardID);
digitalWrite(SS_PIN,LOW); // We got UID now set pin to LOW in order to communicate with SD Module
digitalWrite(SDSSPIN,HIGH); // Enable SD Module communication
myFile = SD.open("datalog.txt", FILE_WRITE);
// if the file opened okay, write to it:
if (myFile) {
Serial.print("Writing to datalog.txt...");
// Wire.beginTransmission(DS1307_ADDRESS);
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.write(decToBcd(0));
Wire.endTransmission();
Wire.requestFrom(DS1307_I2C_ADDRESS, 7);
// Wire.requestFrom(DS1307_ADDRESS, 7);
second = bcdToDec(Wire.read() & 0x7f);
minute = bcdToDec(Wire.read());
hour = bcdToDec(Wire.read() & 0x3f); // Need to change this if 12 hour am/pm
dayOfWeek = bcdToDec(Wire.read());
dayOfMonth = bcdToDec(Wire.read());
month = bcdToDec(Wire.read());
year = bcdToDec(Wire.read());
//print the date EG 3/1/11 23:59:59
CardID = CardID+","+dayOfMonth+","+month+",20"+year+","+hour+":"+minute;
//myFile.println("\n");
myFile.println(CardID);
myFile.close();
Serial.println("done.");
}
else {
// if the file didn't open, print an error:
Serial.println("error opening datalog.txt");
}
// re-open the file for reading:
myFile = SD.open("datalog.txt");
if (myFile) {
Serial.println("datalog.txt:");
// read from the file until there's nothing else in it:
while (myFile.available()) {
Serial.write(myFile.read());
}
// close the file:
myFile.close();
}
else {
// if the file didn't open, print an error:
Serial.println("error opening datalog.txt");
}
}
// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
return ( (val/10*16) + (val%10) );
}
// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
return ( (val/16*10) + (val%16) );
}
We are doing it wrong. Now I understood how SPI slaves works Can you please connect RFID's SS pin to Arduino's DigitalPin 5 (if available, if not connect another digital pin and change to this pin in code) and test this code.
#include <SPI.h>
#include <MFRC522.h>
#include "Wire.h"
#include <SD.h>
//#define DS1307_ADDRESS 0x68
#define DS1307_I2C_ADDRESS 0x68 // the I2C address of Tiny RTC
#define SDSSPIN 4
File myFile;
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
String CardID = "";
#define SS_PIN 5
#define RST_PIN 9
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance.
void setup() {
Serial.begin(9600); // Initialize serial communications with the PC
pinMode(10, OUTPUT); // Testing
digitalWrite(SS_PIN, HIGH); //Make sure RFID SS pin HIGH
digitalWrite(SDSSPIN,LOW); // Testing
SPI.begin(); // Init SPI bus
SD.begin(SDSSPIN); // For testing purpose
if (!SD.begin(SDSSPIN)) {
Serial.println("SD Module initialization failed!");
return;
}
Serial.println("SD Module initialization done.");
Wire.begin();
Serial.println("Scan a MIFARE Classic PICC to demonstrate Value Blocks.");
}
void loop() {
digitalWrite(SDSSPIN, HIGH); //Make sure SD SS Pin is HIGH we are going to use RFID first
digitalWrite(SS_PIN, LOW); ////Make sure RFID SS Pin is LOW we are going to use RFID first
mfrc522.PCD_Init(); // Init MFRC522 card
// Look for new cards
if ( ! mfrc522.PICC_IsNewCardPresent()) {
return;
}
// Select one of the cards
if ( ! mfrc522.PICC_ReadCardSerial()) {
return;
}
// Dump debug info about the card. PICC_HaltA() is automatically called.
//mfrc522.PICC_DumpToSerial(&(mfrc522.uid));
// Dump UID
CardID=("");
Serial.print("Card UID:");
for (byte i = 0; i < mfrc522.uid.size; i++) {
CardID += String(mfrc522.uid.uidByte[i] < 0x10 ? "0" : "");
CardID += String(mfrc522.uid.uidByte[i], HEX);
}
Serial.println(CardID);
digitalWrite(SS_PIN,HIGH); // We got UID now set pin to HIGH in order to communicate with SD Module
delay(1000);
digitalWrite(SDSSPIN,LOW); // Enable SD Module communication
delay(1000);
myFile = SD.open("datalog.txt", FILE_WRITE);
// if the file opened okay, write to it:
if (myFile) {
Serial.print("Writing to datalog.txt...");
// Wire.beginTransmission(DS1307_ADDRESS);
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.write(decToBcd(0));
Wire.endTransmission();
Wire.requestFrom(DS1307_I2C_ADDRESS, 7);
// Wire.requestFrom(DS1307_ADDRESS, 7);
second = bcdToDec(Wire.read() & 0x7f);
minute = bcdToDec(Wire.read());
hour = bcdToDec(Wire.read() & 0x3f); // Need to change this if 12 hour am/pm
dayOfWeek = bcdToDec(Wire.read());
dayOfMonth = bcdToDec(Wire.read());
month = bcdToDec(Wire.read());
year = bcdToDec(Wire.read());
//print the date EG 3/1/11 23:59:59
CardID = CardID+","+dayOfMonth+","+month+",20"+year+","+hour+":"+minute;
//myFile.println("\n");
myFile.println(CardID);
myFile.close();
Serial.println("done.");
}
else {
// if the file didn't open, print an error:
Serial.println("error opening datalog.txt");
}
// re-open the file for reading:
myFile = SD.open("datalog.txt");
if (myFile) {
Serial.println("datalog.txt:");
// read from the file until there's nothing else in it:
while (myFile.available()) {
Serial.write(myFile.read());
}
// close the file:
myFile.close();
}
else {
// if the file didn't open, print an error:
Serial.println("error opening datalog.txt");
}
}
// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
return ( (val/10*16) + (val%10) );
}
// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
return ( (val/16*10) + (val%16) );
}
Did you succeeded with this code?
no bro,i have tested your code its sd card initialization is keep on failing
pls try to modify sd card code