RFID Logger Problems Identifying Tags Correctly

Little background. I will eventually have 35 tags that are programmed to this code, but using just a couple right now to work the kinks out. I also have a placeholder in the code for counting the number of scans, still working that out, so no code in there for that yet, just points to the next action in line. Eventually I am going to incorporate a display screen, but just using the TFT shield right now for the SD card.

I am using an Arduino Mega, Elegoo TFT shield with an SD card, a DS3231 RTC and an RTC522.

I have an interesting issue that I can’t seem to resolve or make happen consistently. When I scan my RFID tag, most of the time it links to the correct name associated with the tag, but every now and then it adds a record for the previously scanned tag, even when scanning one that is not programmed in yet.

I have not been able to find anything that seems to trigger this behavior and it has me stumped.

My code is below. Please feel free to rip apart, especially if I have some useless coding in there. This is the first project I have used SD cards on and I am not too familiar with using CHAR arrays, so there may be room for improvement or I may have something incorrect that is leading to not reading RFID tags correctly.

Many thanks in advance for any insight in to this behavior.

#include <MFRC522.h> // for the RFID
#include <SPI.h> // for the RFID and SD card module
#include <SD.h> // for the SD card
#include <RTClib.h> // for the RTC
#include <Adafruit_NeoPixel.h>

// define pins for RFID
#define CS_RFID 53
#define RST_RFID 9

// define select pin for SD card module
#define CS_SD 48



// Create a file to store the data
File myFile;

char filename[13];
char dateandtime[17];

// Instance of the class for RFID
MFRC522 rfid(CS_RFID, RST_RFID); 

// Variable to hold the tag's UID
String uidString;

// Instance of the class for RTC
RTC_DS1307 rtc;


//Truck Numbers and tag ID
struct USER
{
  unsigned long ID;
  const char *name;
} Users[] =
{
  {0x734AD60, "7100"},
  {0xE4429C22, "7101"},
};
const byte UserCount = sizeof Users / sizeof Users[0];

char *nametocard = "";

int loadcount = 0;
int newloadcount = 1;


// Pins for LEDs and buzzer
const int buzzer = 5;
#define LEDpin 6

Adafruit_NeoPixel led = Adafruit_NeoPixel(1, LEDpin, NEO_GRB + NEO_KHZ800);

/////////////////////////////////////////////////////////////////////Program Setup/////////////////////////////////////////////////////////////////////

void setup() {
  
  led.begin(); //initialize LED 
  led.show(); // Initialize all pixels to 'off'
  pinMode(buzzer, OUTPUT); // Set buzzer as an output

  
  Serial.begin(9600);//initialize serial port at 9600 baud rate
  while(!Serial); //wait for serial to initialize before proceeding
  
  SPI.begin(); // initilize SPI bus
  
  rfid.PCD_Init(); //initialize RFID

  // Setup SD card
  Serial.print("Initializing SD card...");
  if(!SD.begin(CS_SD)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");

  // Setup for the real rime clock  
  if(!rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while(1);
  }
  else {
    // following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }
  if(!rtc.isrunning()) {
    Serial.println("RTC is NOT running!");
  }
}

/////////////////////////////////////////////////////////////////////Main Loop/////////////////////////////////////////////////////////////////////

void loop() {
  DateTime now = rtc.now();
  
  sprintf(filename, "%04d%02d%02d.txt", now.year(), now.month(), now.day()); //creates file name for saving daily data in the format yyyymmdd.txt
  
  //Look for new cards
  if(rfid.PICC_IsNewCardPresent()) {
    readRFID(); //if new card is found, read the RFID
  }
  delay(10);
}

/////////////////////////////////////////////////////////////////////Read RFID Card/////////////////////////////////////////////////////////////////////

void readRFID() {
  rfid.PICC_ReadCardSerial();

  unsigned long UIDVal = rfid.uid.uidByte[0];
  UIDVal = (UIDVal << 8) | rfid.uid.uidByte[1];
  UIDVal = (UIDVal << 8) | rfid.uid.uidByte[2];
  UIDVal = (UIDVal << 8) | rfid.uid.uidByte[3];

  Serial.print("Tag UID: 0x");
  Serial.println(UIDVal, HEX);

  boolean authorized = false;
  char *name = "";
  
  for (int i = 0; i < UserCount; i++)
  {
    if (UIDVal == Users[i].ID)
    {
      authorized = true;
      name = Users[i].name;
      break;  // No need to look a the rest
    }
  }
  
  
  // Sound the buzzer when a card is read
  tone(buzzer, 2000); 
  delay(300);        
  noTone(buzzer);
  
  
  delay(500);

  if(authorized){

   nametocard = name;
   led.setPixelColor(0, 255, 0, 0);
   led.show();
   truckCount();
  }
  else{
    Serial.println("Card Not Linked");
    delay(100);

    led.setPixelColor(0, 0, 255, 0);
    led.show();  
    tone(buzzer, 1000); 
    delay(100);        
    noTone(buzzer);
    led.setPixelColor(0, 0, 0, 0);
    led.show();  
    delay(100);

    led.setPixelColor(0, 0, 255, 0);
    led.show();  
    tone(buzzer, 1000); 
    delay(100);        
    noTone(buzzer);
    led.setPixelColor(0, 0, 0, 0);
    led.show();  
    delay(100);

    led.setPixelColor(0, 0, 255, 0);
    led.show();  
    tone(buzzer, 1000); 
    delay(100);        
    noTone(buzzer);
    led.setPixelColor(0, 0, 0, 0);
    led.show();  
    delay(100);

    return;
  }
}

/////////////////////////////////////////////////////////////////////Truck Count/////////////////////////////////////////////////////////////////////

void truckCount(){

  logCard();
}

/////////////////////////////////////////////////////////////////////Log RFID Card/////////////////////////////////////////////////////////////////////

void logCard() {
  // Enables SD card chip select pin
  digitalWrite(CS_SD,LOW);
  
  // Open file
  
  myFile=SD.open(filename, FILE_WRITE);

  if (myFile) {
    DateTime now = rtc.now();
    
    Serial.println("Saving Data.....");
  

    sprintf(dateandtime, "%04d/%02d/%02d,%02d:%02d", now.year(), now.month(), now.day(), now.hour(),now.minute()); //compiles date and time yyyy/mm/dd,hh:mm
    
    Serial.print("Truck Number: ");
    Serial.println(nametocard);
    Serial.print("Date and Time: ");
    Serial.println(dateandtime);
    
    myFile.print(nametocard);
    myFile.print(",");  
    myFile.println(dateandtime);
        
    myFile.close();
    delay(500);
    led.setPixelColor(0,0,0,0);
    led.show();

  }
  // Disables SD card chip select pin  
  digitalWrite(CS_SD,HIGH);
}

In this function

void readRFID() {
  rfid.PICC_ReadCardSerial();
 //...

PICC_ReadCardSerial() can fail which will leave the rfid data as it was in the previous call and hence, a record of a previous scan. You should only proceed if the call is successful.

void readRFID() {
  if (!rfid.PICC_ReadCardSerial()) return;  // failure so bail out
  //...
[code]

Excellent! I never even thought of the reading failing. That would make sense. The below is the correct way to display an error message on Serial Print if the tag doesn’t read correctly, yes?

The return will just dump it back in to the main loop, correct?

void readRFID() {
  
  if(!rfid.PICC_ReadCardSerial()){
    Serial.println("Please Scan RFID Tag Again");
    return;
  }


  unsigned long UIDVal = rfid.uid.uidByte[0];
  UIDVal = (UIDVal << 8) | rfid.uid.uidByte[1];
  UIDVal = (UIDVal << 8) | rfid.uid.uidByte[2]; 
//...

ClncyFshSlayer:
Excellent! I never even thought of the reading failing. That would make sense. The below is the correct way to display an error message on Serial Print if the tag doesn't read correctly, yes?

The return will just dump it back in to the main loop, correct?

that is correct.