Arduino with RFID scanner and relay freezes after some time

Hello,

I am using an Arduino UNO with a RFID scanner that triggers a relay with a lock behind it.
It sends an HTTP GET request to my website and gets either true or false back.
If the response is true, the lock opens.

This is all working except that it gets stuck sometimes.
Resetting the board works but it gets stuck a bit later again.

This is the code I'm using

#include <ArduinoJson.h>
#include <Ethernet.h>
#include <SPI.h>
#include <EEPROM.h> 
#include <MFRC522.h>
#include  <Servo.h>

#define COMMON_ANODE

#ifdef COMMON_ANODE
#define LED_ON LOW
#define LED_OFF HIGH
#else
#define LED_ON HIGH
#define LED_OFF LOW
#endif

#define redLed 7    // Set Led Pins
#define greenLed 6
#define blueLed 5

#define relay   2  // Set Relay Pin

/////// RFID Settings ///////
#define RST_PIN         3          
#define SS_PIN          4       
MFRC522 mfrc522(SS_PIN, RST_PIN);   // Create MFRC522 instance.
int statusCode = 0;
/////// Keypad Settings ///////
/////// Servo Settings ///////
Servo lock; //declares servo
String getReq, tag, rfid, pincode;
int rStatus = 0; // RFID Status
int pStatus = 0; // PIN Status
String registeredCard = "160196116163";
void setup() {
  pinMode(redLed, OUTPUT);
  pinMode(greenLed, OUTPUT);
  pinMode(blueLed, OUTPUT);

  pinMode(relay, OUTPUT);
  //Be careful how relay circuit behave on while resetting or power-cycling your Arduino
  digitalWrite(redLed, LED_OFF);  // Make sure led is off
  digitalWrite(greenLed, LED_OFF);  // Make sure led is off
  digitalWrite(blueLed, LED_OFF); // Make sure led is off
  // Initialize Serial port
  Serial.begin(9600);
  while (!Serial) continue;

  // Initialize Ethernet library
  byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x0F};
  if (!Ethernet.begin(mac)) {
    Serial.println(F("Failed to configure Ethernet"));
  }
  delay(1000);
  /////// RFID Setup ///////
  Serial.println("Initializing RFID Module.");
  mfrc522.PCD_Init();   // Initiate MFRC522
  Serial.println("RFID Ready.");
  Serial.println("");
  delay(1000);

  /////// Keypad Setup ///////

  Serial.println("Setting up servo motor...");
  lock.attach(13);
  Serial.println("Servo Motor Ready.");
  Serial.println("");
  delay(1000);
  
  Serial.println("Please tap RFID Card.");
  digitalWrite(relay, LOW);    // Make sure door is locked
}

void loop() {
  if (rStatus == 0)
  {
    readRFID();
  }

  if (rStatus == 1)
  {
    rStatus = 0;
    Serial.println("Opening lock");
    digitalWrite(relay, HIGH);    // Make sure door is unlocked
    delay(5000);
    Serial.println("Closing lock");
    digitalWrite(relay, LOW);    // Make sure door is locked
  }
Serial.println("test");
rStatus = 0;
delay(1000);
}

void request(String rfid) {
  Serial.println(F("Connecting..."));

  // Connect to HTTP server
  EthernetClient client;
  client.setTimeout(10000);
  if (!client.connect("mylink.com", 80)) {
    Serial.println(F("Connection failed"));
    return;
  }

  Serial.println(F("Connected!"));

  // Send HTTP request
  client.println("GET /gates/check?sid=RFID0002&pid=" + rfid + " HTTP/1.0");
  client.println(F("Host: mylink.com"));
  client.println(F("Connection: close"));
  if (client.println() == 0) {
    Serial.println(F("Failed to send request"));
    return;
  }

  // Check HTTP status
  char status[32] = {0};
  client.readBytesUntil('\r', status, sizeof(status));
  if (strcmp(status, "HTTP/1.1 200 OK") != 0) {
    Serial.print(F("Unexpected response: "));
    Serial.println(status);
    return;
  }

  // Skip HTTP headers
  char endOfHeaders[] = "\r\n\r\n";
  if (!client.find(endOfHeaders)) {
    Serial.println(F("Invalid response"));
    return;
  }

  // Allocate the JSON document
  // Use arduinojson.org/v6/assistant to compute the capacity.
  const size_t capacity = JSON_OBJECT_SIZE(3) + JSON_ARRAY_SIZE(2) + 60;
  DynamicJsonDocument doc(capacity);

  // Parse JSON object
  DeserializationError error = deserializeJson(doc, client);
  if (error) {
    Serial.print(F("deserializeJson() failed: "));
    Serial.println(error.c_str());
    return;
  }

  // Extract values
  Serial.println(F("Response:"));
  String response = doc["access"].as<String>();
  Serial.println(response);
  if (response == "true") {
    Serial.println("Open Gate");
    rStatus = 1;
  } else {
    Serial.println("No access");
    rStatus = 0;
  }
  // Disconnect
  client.stop();
}

void readRFID()
{
  // Look for new cards
  if ( ! mfrc522.PICC_IsNewCardPresent())
  {
    return;
  }
   //Select one of the cards
  if ( ! mfrc522.PICC_ReadCardSerial())
  {
    return;
  }

  //Show UID on serial monitor
  Serial.print("PID tag : ");
  String content = "";
  //byte letter;
  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));
    //Serial.print(mfrc522.uid.uidByte[i]);
    //content.concat(String(mfrc522.uid.uidByte[i]));
  }http://192.168.0.74/mjpg/video.mjpg?timestamp=1587029376092
  Serial.println();
  Serial.println(content);
  tag = String(content);
  request(tag);
  //Serial.println(rfid);
  Serial.println("End of scan loop");
}

I tried diffrent boards / ethernet shields aswell but it doesn't solve the problem.

CasBekhuis:
This is all working except that it gets stuck sometimes.
Resetting the board works but it gets stuck a bit later again.

Can you provide more detailed information? "gets stuck" is not very informative.

Have you added Serial.print() statements in an effort to see exactly where the problem arises?

...R

Robin2:
Can you provide more detailed information? "gets stuck" is not very informative.

Have you added Serial.print() statements in an effort to see exactly where the problem arises?

...R

Hello,
Yes, I have several print statements.
The println("test") in the loop keeps printing.
It's like it isn't looking at the if else statement.
It doesn't scan an RFID tag and it doesn't trigger the relay

The other lines only print when I scan a pass / send a request / the lock opens/closes

It is not a good idea to use the String (capital S) class on an Arduino as it can cause memory corruption in the small memory on an Arduino. This can happen after the program has been running perfectly for some time. Just use cstrings - char arrays terminated with '\0' (NULL).

When using Cstrings you must use strcmp() to compare values rather than ==

...R