Hi everyone, this is my first post so thanks for any support that may come.
I have an Arduino Uno with an adafruit NFC shield on top and Wave shield on top of that. Below is a stripped down version of some code for troubleshooting purposes. When I load the code below, I get the following problems:
- If I include the portions of the code that initialize the SD card, then the RFID card reading portion of the code gets 'stuck'. If I comment out the SD card initialization lines of code, the RFID portion of the code works fine. Additionally, the hardware works fine with the RFID library examples (Adafruit_NFCShield_I2C.h) and Wave shield examples when run on their own. The problem seems to comes when they are combined. All of the Serial.println("loop test") in the loop are my attempt to troubleshoot and figure out where the program is getting stuck. I would move it around and reload the program and watch the serial monitor to see where it would get stuck. I found that if I left the code in that initialized the SD card, the program would get stuck at the following line:
success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength);
By 'stuck', I mean, it wouldn't display any serial print commands past that line and if you hold an RFID card up to the shield, it won't recognize it. If you comment out the SD card initialization lines of code, the hardware will recognize an RFID card and display its info in the serial monitor.
- When I load the code and open the serial monitor, every other time I load it, the program does not recognize the NFC board firmware/version during the following check:
uint32_t versiondata = nfc.getFirmwareVersion();
if (! versiondata) {
Serial.print("Didn't find PN53x board");
while (1); // halt
The code returns the 'Didn't find PN53x board' message. If I run it again, it recognizes the board fine and returns the correct software version and goes on further in the program. It is every other time, not sporadic, which makes me think there is something about how the uint32_t variable starts off that I don't understand.
Any help or suggestions are appreciated.
Thanks,
Adam
#include <Wire.h>
#include <Adafruit_NFCShield_I2C.h>
#include <WaveHC.h>
#include <WaveUtil.h>
#define IRQ (11) // this trace must be cut and rewired!
#define RESET (8)
Adafruit_NFCShield_I2C nfc(IRQ, RESET);
SdReader card; // This object holds the information for the card
FatVolume vol; // This holds the information for the partition on the card
FatReader root; // This holds the information for the volumes root directory
FatReader file; // This object represent the WAV file for a pi digit or period
WaveHC wave; // This is the only wave (audio) object, since we will only play one at a time
#define error(msg) error_P(PSTR(msg))
void setup(void) {
Serial.begin(9600);
// find Adafruit RFID/NFC shield
PgmPrintln("Pi speaker");
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);
// configure board to read RFID tags
nfc.SAMConfig();
Serial.println("Waiting for an ISO14443A Card ...");
card.init();
vol.init(card);
root.openRoot(vol);
PgmPrintln("Files found:");
root.ls();
}
/////////////////////////////////// LOOP
//unsigned digit = 0;
void loop() {
Serial.println("loop test");
uint8_t success;
uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 }; // Buffer to store the returned UID
uint8_t uidLength; // Length of the UID (4 or 7 bytes depending on ISO14443A card type)
// Wait for an ISO14443A type cards (Mifare, etc.). When one is found
// 'uid' will be populated with the UID, and uidLength will indicate
// if the uid is 4 bytes (Mifare Classic) or 7 bytes (Mifare Ultralight)
success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength);
Serial.println("loop test");
uint32_t identifier = 0;
Serial.println("loop test");
if (success) {
// Found a card!
Serial.print("Card detected #");
// turn the four byte UID of a mifare classic into a single variable #
identifier = uid[3];
identifier <<= 8; identifier |= uid[2];
identifier <<= 8; identifier |= uid[1];
identifier <<= 8; identifier |= uid[0];
Serial.println(identifier);
// repeat this for loop as many times as you have RFID cards
if (identifier == 967167447) { // this is the card's unique identifier
playcomplete("1.WAV"); // these are file names for the sample audio files - change them to your own file names
}
if (identifier == 2146122274) {
playcomplete("2.WAV");
}
}
}
/////////////////////////////////// HELPERS
/*
- print error message and halt
*/
void error_P(const char str) {
PgmPrint("Error: ");
SerialPrint_P(str);
sdErrorCheck();
while(1);
}
/ - print error message and halt if SD I/O error
/
void sdErrorCheck(void) {
if (!card.errorCode()) return;
PgmPrint("\r\nSD I/O error: ");
Serial.print(card.errorCode(), HEX);
PgmPrint(", ");
Serial.println(card.errorData(), HEX);
while(1);
}
/ - Play a file and wait for it to complete
*/
void playcomplete(char *name) {
playfile(name);
while (wave.isplaying);
// see if an error occurred while playing
sdErrorCheck();
}
/*
- Open and start playing a WAV file
*/
void playfile(char *name) {
if (wave.isplaying) {// already playing something, so stop it!
wave.stop(); // stop it
}
if (!file.open(root, name)) {
PgmPrint("Couldn't open file ");
Serial.print(name);
return;
}
if (!wave.create(file)) {
PgmPrintln("Not a valid WAV");
return;
}
// ok time to play!
wave.play();
}