My code below controls a servo that's attached to a door handle. When a card with a matching UID is brought near the RFID reader, it is supposed to rotate the servo to open and then close the door. The code works completely normally shortly after resetting the Arduino Uno that it's running on. However, after it's been left running for a while (say 45 minutes or so), it completely stops working and no longer responds to RFID tags.
After it's entered this state, power cycling the MFRC522 independently has no effect, indicating to me that the problem is with the Arduino code rather than the RFID reader.
I've been able to sorta patch this issue with a counter that triggers a device reset every number of program loops, but even this would fail occasionally and I'd like to find the root of the issue.
It seems like it could be a memory leak problem, but I'm not exactly sure how to go about debugging that.
#include <SPI.h>
#include <MFRC522.h>
#include <Servo.h>
#define RST_PIN 9
#define SS_PIN 10
#define SERVO_PIN 6
const int NUM_USERS = 4;
const unsigned long ALLOWED_UIDS[NUM_USERS] = { 1234, 12345, 123456, 1234567 };
const int DOOR_OPEN_SECONDS = 2;
Servo doorServo; // Set up servo
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance
void setup() {
SPI.begin(); // Init SPI bus
mfrc522.PCD_Init(); // Init MFRC522
delay(15); // Optional delay. Some board do need more time after init to be ready, see Readme
mfrc522.PCD_SetRegisterBitMask(mfrc522.RFCfgReg, (0x07 << 4)); // Sets reader to maximum gain
doorServo.attach(SERVO_PIN); // Attach servo
doorServo.write(180); // Set servo to closed position
}
void loop() {
// Reset the loop if no new card present on the sensor/reader
if (!mfrc522.PICC_IsNewCardPresent()) {
return;
}
// Only gets here if there's a new card present
unsigned long uid; // Get UID of card
uid = mfrc522.uid.uidByte[0] << 24;
uid += mfrc522.uid.uidByte[1] << 16;
uid += mfrc522.uid.uidByte[2] << 8;
uid += mfrc522.uid.uidByte[3];
mfrc522.PICC_HaltA(); // Stop reading
for (int i = 0; i < NUM_USERS; i++) { // Iterate through allowed UIDs
if (uid == ALLOWED_UIDS[i]) { // If UID matches
doorServo.write(0); // Open door
delay(DOOR_OPEN_SECONDS * 1000); // Wait some time
doorServo.write(180); // Close door
delay(250);
}
}
}