Hello World,
It's been 2 days since I have started searching for a solution to solve this issue. The issue - as suggested by the title of the post - is that 2 devices communicating with Arduino using SPI are malfunctioning!! That is, I cannot establish connection with both of them at the same time.
However, I have solved the issue after reading so many posts here and there. So, as to thank the forum and the community for helping me out (even though I haven't posted a question), I want to post the problem and the solution.
Problem Description:
It's required to connect this RFID reader and this SD card to Mega Arduino board so I can read RFID tags and load some files from the card to process some data.
Solution:
Part 1 (if you know about software SPI, you can skip to part 2):
The PN532 library (the library used to interface with the NFC device using SPI) implements Software SPI. It doesn't use the hardware SPI. Meaning, you don't have to stick to the SPI pins mentioned for your arduino module. You can use any other digital pin for the SPI.
example using Mega:
It's mentioned in the Mega product page, that the SPI pins are:
- MISO: 50
- MOSI: 51
- SCK: 52
- SS: 53
So, without learning about the software SPI, one would connect the MOSI of the NFC device with the MOSI pin of the arduino, the MISO of the device with the MISO pin of the arduino and so on and so forth. Here's a code sample:
#define SCK 52
#define MOSI 51
#define SS 53
#define MISO 50
PN532 nfc(SCK, MISO, MOSI, SS);
The new thing here is that you can change the pins connected to the arduino board. For example, we can connect SS [NFC] to pin 40 [Mega], MISO [NFC] to pin 38 [Mega], MOSI [NFC] to pin 39 [Mega] and SCK [NFC] to pin 37 [Mega] (completely random digital pins) and use the same initialization after editing the pin definitions:
#define SCK 37
#define MOSI 39
#define SS 40
#define MISO 38
Part 2:
Now that you know about the software SPI. You need to know that Software SPI doesn't work with libraries that use hardware SPI.
The SD card library uses hardware SPI. That's why I faced the problem of making them communicate over the same data lines.
By the way, the SD card library I use is the standard - out dated - library pre-installed with arduino setup.
Here's a full version of some test code I created to test both devices together: (Note: I have used hardware SPI pins mentioned in the Mega Product page for the SD card device. Obviously, I have used Mega Arduino board)
#include <PN532.h>
#include <SD.h>
#define SCK 37
#define MOSI 39
#define SS 40
#define MISO 38
PN532 nfc(SCK, MISO, MOSI, SS);
const uint8_t SdChipSelect = 53;
void setup() {
Serial.begin(9600);
pinMode(SS, OUTPUT);
pinMode(SdChipSelect, OUTPUT);
digitalWrite(SS, HIGH);
digitalWrite(SdChipSelect, HIGH);
Initialize_NFC_First();
checkPins();
testNFC();
}
void loop() {
}
void Initialize_NFC_First() {
InitializeNFC();
InitializeSDCard();
}
void Initialize_SDCard_First() {
InitializeSDCard();
InitializeNFC();
}
void InitializeNFC() {
digitalWrite(SdChipSelect, HIGH);
digitalWrite(SS, LOW);
nfc.begin();
uint32_t versiondata = nfc.getFirmwareVersion();
if (! versiondata) {
Serial.print("Didn't find PN53x board");
while (1); // halt
}
// Got ok data, print it out!
Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX);
Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC);
Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);
Serial.print("Supports "); Serial.println(versiondata & 0xFF, HEX);
// configure board to read RFID tags and cards
nfc.SAMConfig();
digitalWrite(SS, HIGH);
digitalWrite(SdChipSelect, HIGH);
}
void InitializeSDCard() {
digitalWrite(SdChipSelect, LOW);
digitalWrite(SS, HIGH);
digitalWrite(SdChipSelect, LOW);
Serial.print("Initializing SD card...");
if (!SD.begin()) {
Serial.println("initialization failed!");
return;
}
Serial.println("initialization done.");
digitalWrite(SS, HIGH);
digitalWrite(SdChipSelect, HIGH);
}
void checkPins() {
if(digitalRead(SS) == LOW) Serial.println("Reader is Active");
else Serial.println("Serial is inActive");
if(digitalRead(SdChipSelect) == LOW) Serial.println("SD Card is Active");
else Serial.println("SD Card is inActive");
}
void testNFC() {
digitalWrite(SdChipSelect, HIGH);
digitalWrite(SS, LOW);
uint32_t versiondata = nfc.getFirmwareVersion();
if (! versiondata) {
Serial.print("Didn't find PN53x board");
while (1); // halt
}
// Got ok data, print it out!
Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX);
Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC);
Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);
Serial.print("Supports "); Serial.println(versiondata & 0xFF, HEX);
digitalWrite(SS, HIGH);
digitalWrite(SdChipSelect, HIGH);
}
Note:
You may need to read the user guide to have the NFC library work.
Another note:
There's no specific reason to use uint8_t data type for sd card select. I just happened to use it.
and this concludes the post.