I'm wondering if there's anyone that may be able to shed some light on a issue I'm having with an Arduino Mega and MFRC522 NFC reader.
Before I describe the particular issue I'll point out that the code works 99.9% of the time with no issues and I'm hoping somone can help me refine it to prevent the issue I have occasionally.
Within my sketch I have a byte array named:
uint8_t TagRead[4];
There are also a number of arrays storing the card UIDs:
uint8_t RED1[4] = { 0x17, 0xF6, 0xE2, 0xA4 };
uint8_t RED2[4] = { 0x77, 0xF9, 0xD5, 0xA4 };
uint8_t RED3[4] = { 0x85, 0x83, 0xB1, 0xFB };
Within the loop section of my code I do this:
void loop() {
do {
readflag = checkread(); //Returns 1 if the MFRC522
detects a card
}
while (!readflag);
NewTone(readerbuzzer, 1000, 180); //Beep
recordid(); //Record the scanned card's ID
action(); //Do something
}
checkread() looks like this:
int checkread() {
if ( ! mfrc522.PICC_IsNewCardPresent()) {
return 0;
}
mfrc522.PICC_HaltA();
return 1;
}
So basically, if a card is detected it returns 1.
recordid() looks like this:
void recordid() {
mfrc522.PICC_IsNewCardPresent();
mfrc522.PICC_ReadCardSerial();
for (int i = 0; i < mfrc522.uid.size; i++) {
TagRead[i] = mfrc522.uid.uidByte[i];
}
mfrc522.PICC_HaltA();
}
So I end up with the scanned card's UID in the RagRead array. With this I can perform some action, for example compare it to one of the cards that's declared already:
void action() {
if (*((uint32_t *)TagRead) == *((uint32_t *)RED1)) {
dosomething();
}
else if (*((uint32_t *)TagRead) == *((uint32_t *)RED1)) {
dosomethingelse();
}
}
This all works OK 99% of the time.
The problem
Sometimes, if a card is scanned but removed too quickly, the system detects a new card (and so triggers recordid() and action()...) but the new card's UID is not recorded in TagRead[]. TagRead[] keeps the value of the previous card and so the action for the card scanned previously is triggered again.
Does anyone know why this is happening and more importantly, how I can prevent it?
If the card isn't scanned properly, could I call another function that warns the user they need to scan again?
The most important thing to solve is the calling of the action function if TagRead[] hasn't been updated with the new UID.
Is it possible that the card is detected (enough to break out of the loop) but the card info is not being obtained?
Thank you in advance.