Hi Everyone,
I have been working on a project for a while but currently, got stuck at this one step.
When I only use MPR121, the main loop works as expected. But once I added in RFID module, it stops working. I tried a simplified version where I just scan an NFC tag without doing anything further with the scanned result and then use MPR121, it still doesn't work.
Has anyone encountered a similar situation before? At first, I suspected it might be because I am using the SD card module as well. I read about two SPI modules interfere with each other. However, I tried with only using SD card and RFID, there is no problem using the two together. So now, I am very confused.
The interaction is 1) scan an NFC tag to find the page number 2) check if there are any recordings associated with that page 3) if no, goes to the recording mode. if yes, go to the play mode. 4) in recording mode, touch one cap, it records the audio accordingly. the audio name is saved as [page number]-[sensor number], for example "1-2.wav".
Here are my codes:
#include <Wire.h>
#include "Adafruit_MPR121.h"
#ifndef _BV
#define _BV(bit) (1 << (bit))
#endif
#include <SD.h>
#include <SPI.h>
#include <TMRpcm.h>
#include <MFRC522.h>
#define SD_ChipSelectPin 10
TMRpcm audio;
#define RST_PIN 9 // Configurable, see typical pin layout above
#define SS_PIN 8 // Configurable, see typical pin layout above
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance
MFRC522::MIFARE_Key key;
uint16_t lasttouched = 0;
uint16_t currtouched = 0;
Adafruit_MPR121 cap = Adafruit_MPR121();
uint8_t touchThreshold = 40;
uint8_t releaseThreshold = 20;
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50;
uint8_t successRead;
byte readCard[7];
typedef struct _RFID_TABLE
{
uint8_t serNum0;
uint8_t serNum1;
uint8_t serNum2;
uint8_t serNum3;
uint8_t serNum4;
int pageid;
} RFID_TABLE;
static const RFID_TABLE PROGMEM table[] =
{
//serNum0 serNum1 serNum2 serNum3 serNum4 pageid
{ 0x4, 0x73, 0x27, 0xE2, 0xA8, 1, },
{ 0x4, 0xDE, 0x21, 0xE2, 0xA8, 2, },
};
char audioname[] = "X-XX.wav"; // record-mode file name
char chosenFileName[]= "X-XX.wav"; //create another name just to tell the difference from record mode
char tempname[] = "X-XX.wav"; // use to check if the names exist
char extension[] = "wav";
int i;
int TouchCounter[2][12];
int pad[12]={1,2,3,4,5,6,7,8,9,10,11,12};
void setup() {
Serial.begin(115200);
while (!Serial) { // needed to keep leonardo/micro from starting too fast!
delay(10);
}
Serial.println("Adafruit MPR121 Capacitive Touch sensor test");
// Default address is 0x5A, if tied to 3.3V its 0x5B
// If tied to SDA its 0x5C and if SCL then 0x5D
if (!cap.begin(0x5A)) {
Serial.println("MPR121 not found, check wiring?");
while (1);
}
Serial.println("MPR121 found!");
//check SD module
if (!SD.begin(SD_ChipSelectPin)) {
return;
}else{
Serial.println("SD OK");
}
audio.CSPin = SD_ChipSelectPin;
SPI.begin(); // Init SPI bus
mfrc522.PCD_Init(); // Init MFRC522 card
for (byte a = 0; a < 6; a++) {
key.keyByte[a] = 0xFF;
}
Serial.println("Ready to read a card");
delay(100);
//assign 0 as default value for each Touchcounter
for (int i=0;i<2; i++){
for (uint8_t j=0; j<12; j++) {
TouchCounter[i][j]=0;
}
}
}
void loop() {
// add start button
do{
successRead=getUID();
}
while (!successRead);
getPage();
checkAudio();
}
uint8_t getUID() {
if ( ! mfrc522.PICC_IsNewCardPresent()) { //If a new PICC placed to RFID reader continue
return 0;}
if ( ! mfrc522.PICC_ReadCardSerial()) { //Since a PICC placed get Serial and continue
return 0;}
// Now a card is selected. The UID and SAK is in mfrc522.uid.
Serial.print("Card UID:");
for (byte a= 0; a< 7; a++) {
readCard[a] = mfrc522.uid.uidByte[a];
Serial.print(readCard[a], HEX);
}
Serial.println("");
mfrc522.PICC_HaltA();// Stop reading
return 1;
}
int getPage () {
for (unsigned i=0; i<sizeof(table)/sizeof(table[0]); ++i){
uint8_t _serNum0=pgm_read_dword(&table[i].serNum0);
uint8_t _serNum1=pgm_read_dword(&table[i].serNum1);
uint8_t _serNum2=pgm_read_dword(&table[i].serNum2);
uint8_t _serNum3=pgm_read_dword(&table[i].serNum3);
uint8_t _serNum4=pgm_read_dword(&table[i].serNum4);
if(_serNum0==readCard[0]
&& _serNum1==readCard[1] &&
_serNum2==readCard[2] &&
_serNum3==readCard[3] &&
_serNum4==readCard[4]){
int _pageid=pgm_read_dword(&table[i].pageid);
return (_pageid);
}
}
}
void checkAudio() {
i=getPage();
for (int k=0; k<12; k++) {
sprintf(tempname,"%u-%u.%s",i,pad[k],extension);
Serial.println(tempname);//debug
}
if (SD.exists(tempname)) {
Serial.println("This page has been recorded.");
//playModeLED();
playMode();
}
else {
Serial.println("this hasn't been recorded");
//recordModeLED();
recordMode();
}
}
void recordMode() {
Serial.println("Test. Start Record Mode");//debug
currtouched = cap.touched();
for (uint8_t j=0; j<12; j++) {
if ((millis() - lastDebounceTime) > debounceDelay) {
if ((currtouched & _BV(j)) && !(lasttouched & _BV(j))) {
lastDebounceTime = millis();
}
if (!(currtouched & _BV(j)) && (lasttouched & _BV(j))) {
TouchCounter[i][j]++;
if (TouchCounter[i][j] == 1) {
Serial.print(j); Serial.println(" Touched Once");
sprintf(audioname,"%u-%u.%s",i,pad[j],extension); //create filename
audio.startRecording(audioname, 16000, A0);
}
if (TouchCounter[i][j] ==2) {
Serial.print(j); Serial.println(" Touched Twice");
audio.stopRecording(audioname);
}
if ((TouchCounter[i][j] >2) && (TouchCounter[i][j]%2==1)) {
Serial.print(j); Serial.println(" Playing");
audio.play(audioname);
}
if ((TouchCounter[i][j] >2) && (TouchCounter[i][j]%2==0)) {
Serial.print(j); Serial.println(" Pause Playing");
audio.pause();
}
}
delay(50);
}
}
// reset our state
lasttouched = currtouched;
return;
// debugging info, what
Serial.print("\t\t\t\t\t\t\t\t\t\t\t\t\t 0x"); Serial.println(cap.touched(), HEX);
Serial.print("Filt: ");
for (uint8_t i=0; i<12; i++) {
Serial.print(cap.filteredData(i)); Serial.print("\t");
}
Serial.println();
Serial.print("Base: ");
for (uint8_t i=0; i<12; i++) {
Serial.print(cap.baselineData(i)); Serial.print("\t");
}
Serial.println();
// put a delay so it isn't overwhelming
delay(100);
}
void playMode() {
currtouched = cap.touched();
for (uint8_t j=0; j<12; j++) {
if ((millis() - lastDebounceTime) > debounceDelay) {
if ((currtouched & _BV(j)) && !(lasttouched & _BV(j))) {
lastDebounceTime = millis();
}
if (!(currtouched & _BV(j)) && (lasttouched & _BV(j))) {
TouchCounter[i][j]++;
if (TouchCounter[i][j]%2==1) {
Serial.print(i); Serial.println(" Playing");
sprintf(chosenFileName,"%u-%u.%s",i,pad[j],extension);
audio.play(chosenFileName);
}
if (TouchCounter[i][j]%2==0) {
Serial.print(i); Serial.println(" Pause Playing");
audio.pause();
}
}
delay(50);
}
}
// reset our state
lasttouched = currtouched;
return;
}