'Arduino RFID (MFRC522) problem - stops reading tags after some time

For some time I wanted to have an Arduino controlled light switcher for outdoors and few weeks ago I created it, but I have problems with it.

I needed to have a RFID reader outside, that switches lights on for some time when a proper tag is given and it works all good but only for some time. Sometimes after few hours, sometime after few days of using the tag feature doesn't work anymore until I reset whole Arduino (also have a Hall sensor mounted that turns lights on when my door is open and it works perfectly fine)

My question is - what is wrong with this code (I suspect the "rfid.PICC_HaltA(); rfid.PCD_StopCrypto1();" bottom part, cause I have no idea how to use it and what it does to be fully honest). I'm not a programmer, I'm a total noob and I would really appreciate your help.

Edit: Draw quick representation in paint to show how it looks IRL:

enter image description here

I didnt draw all separate colors and connections to GPIO cause they are all fine - like I said it works but only for some time until I reset the whole thing. Arduino is Nano (Old Bootloader) and RFID reader is RC522. Magnetic Hall sensor is just a normal sensor with a magnet mounted on door beneath it so it knows when the door is opened/closed. The whole idea is this:

When door open - lights up and stay up for 6 more seconds after closing the door

When door is closed and tag is presented - lights up for 15s, then go back to checking if door is opened/closed

#include <SPI.h>
#include <MFRC522.h>

//#define czas_trwania 5000
//blue
const byte UID1[] = {0xA7, 0x8C, 0x24, 0xD9};
//blacks
const byte UID2[] = {0x10, 0x84, 0xD2, 0x2A};
const byte UID3[] = {0xDC, 0x46, 0xB6, 0x91};
const byte UID4[] = {0xB0, 0xE8, 0xC4, 0x2A};
//reds
const byte UID5[] = {0x9E, 0xC8, 0xEA, 0xB3};
const byte UID6[] = {0xFE, 0xA5, 0xF7, 0xB3};
//const byte UID6[] = {0x70, 0xBA, 0x35, 0xA5};

MFRC522 rfid(10, 9);
MFRC522::MIFARE_Key key;
int in1 = 7;
int dooropen = 8;
int state = 0;
int tester = 0;
void setup() {
  Serial.begin(9600);
  SPI.begin();
  rfid.PCD_Init();
  pinMode(in1, OUTPUT);
  pinMode(dooropen, INPUT);
  digitalWrite(in1, LOW);
}

void loop() {

  state = digitalRead(dooropen);

  if (state == HIGH) {
    //Serial.println("Door Opened");
    tester = 1;
    digitalWrite(in1, HIGH);
  } else {
    if (tester == 1) {
      delay(6000);
      tester = 0;
    }
    //Serial.println("Door Closed");
    digitalWrite(in1, LOW);

    if (rfid.PICC_IsNewCardPresent() && rfid.PICC_ReadCardSerial()) {
      if (rfid.uid.uidByte[0] == UID1[0] &&
          rfid.uid.uidByte[1] == UID1[1] &&
          rfid.uid.uidByte[2] == UID1[2] &&
          rfid.uid.uidByte[3] == UID1[3] ||
          rfid.uid.uidByte[0] == UID2[0] &&
          rfid.uid.uidByte[1] == UID2[1] &&
          rfid.uid.uidByte[2] == UID2[2] &&
          rfid.uid.uidByte[3] == UID2[3] ||
          rfid.uid.uidByte[0] == UID3[0] &&
          rfid.uid.uidByte[1] == UID3[1] &&
          rfid.uid.uidByte[2] == UID3[2] &&
          rfid.uid.uidByte[3] == UID3[3] ||
          rfid.uid.uidByte[0] == UID4[0] &&
          rfid.uid.uidByte[1] == UID4[1] &&
          rfid.uid.uidByte[2] == UID4[2] &&
          rfid.uid.uidByte[3] == UID4[3] ||
          rfid.uid.uidByte[0] == UID5[0] &&
          rfid.uid.uidByte[1] == UID5[1] &&
          rfid.uid.uidByte[2] == UID5[2] &&
          rfid.uid.uidByte[3] == UID5[3] ||
          rfid.uid.uidByte[0] == UID6[0] &&
          rfid.uid.uidByte[1] == UID6[1] &&
          rfid.uid.uidByte[2] == UID6[2] &&
          rfid.uid.uidByte[3] == UID6[3]) {
            digitalWrite(in1, HIGH);
            delay(15000);
            digitalWrite(in1, LOW);
          }
          rfid.PICC_HaltA();
          rfid.PCD_StopCrypto1();
        }
      }
    }

I know that this if will make some of you cringe hard, but I didn't know how to manage otherwise :(



Solution 1:[1]

I could not find the problem, so instead, I just re-designed your project, and it should work. I have made it more maintainable and optimized than your current project.

For the new design, I have created a schematic and the code:

Schematic: Schematic For Project

Code:

#include <SPI.h>
#include <MFRC522.h>

#define SS_PIN 10
#define RST_PIN 9
#define LED_PIN 7

bool toggle = false;

MFRC522 mfrc522(SS_PIN, RST_PIN);

void setup()
{
  Serial.begin(9600);
  SPI.begin();
  mfrc522.PCD_Init();

  pinMode(LED, OUTPUT);
}
void loop()
{
  if (!mfrc522.PICC_IsNewCardPresent())
  {
    return;
  }
  // Select one of the cards
  if (!mfrc522.PICC_ReadCardSerial())
  {
    return;
  }

  // Use this function to serial print your UID.
  checkUID();

  if (content.substring(1) == "[Insert UID Here]")
  {
    Serial.println("LED Toggle");
    toggleLight();
  }
  else
  {
    Serial.println(" Access denied");

  }
}

void toggleLight()
{
  if (toggle)
  {
    toggle = false;
  }
  else
  {
    toggle = true;
  }
}

void checkUID()
{
  String content = "";
  for (byte i = 0; i < mfrc522.uid.size; i++)
  {
    Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
    Serial.print(mfrc522.uid.uidByte[i], HEX);
    content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
    content.concat(String(mfrc522.uid.uidByte[i], HEX));
  }
}

I do not have the resources to try this, but if you encounter any issues make sure to let me know and I will help you resolve them.

You will also need to include the library:

Library

I have spent a lot of time making this, so I would appreciate an upvote! ?

Solution 2:[2]

MFRC522 library has the Version 2. https://github.com/OSSLibraries/Arduino_MFRC522v2

  // Halt PICC.
  reader.PICC_HaltA(); 
  // Stop encryption on PCD. (Proximity Coupling Device (PCD))
  reader.PCD_StopCrypto1();

for PICC_HaltA(), read http://wg8.de/wg8n1496_17n3613_Ballot_FCD14443-3.pdf chapter 6.

6.3.5 HALT state
Description:
In the HALT state, the PICC shall respond only to a WUPA command.
State exit conditions and transitions:
The PICC enters the READY* state after it has received a valid WUPA command and transmitted its ATQA.

For PCD_StopCrypto1, In the source code, MFRC522V2.cpp, the note of Function MFRC522::StatusCode MFRC522::PCD_Authenticate

  • Executes the MFRC522 MFAuthent command.
    ... ...
  • Remember to call PCD_StopCrypto1() after communicating with the authenticated PICC - otherwise no new communications can start.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 James Barnett
Solution 2 Marvin Tang