RFID RELAY SWITCH

hey guys i'm new to the forum so i apologize if this question isn't structured correctly.

all i;m trying to achieve is for an RFID tag to switch a relay on when in range of the reader and then when the card is out of range the relay to be switched off immediately. I'm very new to coding so I've just used the sample code from this door lock project "https://create.arduino.cc/projecthub/Heathen_Hacks-v2/rfid-relay-rfid-door-lock-code-rfid-pc-switch-eee1d1?ref=search&ref_id=rfid%20switch&offset=0" which i've been trying to modify to suit my intended purpose but my programming knowledge is very limited so i'm having a bit of trouble. If anyone could give me some tips I'd really appreciate it.

this project does not fit your usecase very well, does it?

what you would need is instead of "open_lock"

to switch on the relay and to set a variable previousMillis=millis();
This will store the "current time" (=millis()) in a variable as long as the card gets readed.

and an additional check in the loop if millis()-previousMillis > timeout and to switch off the relais.

See the example "BlinkWithoutDelay" in the IDE how to deal with millis - let the LED blink, and then try to adopt the RFID code.

Thank you so much for the quick reply and the tips ill give that a try. really appreciate the advice :slight_smile:

I’m still having a bit of trouble, this is what i’ve done so far but i am honestly lost on how to alter the code correctly.
this is probably completely wrong to be honest

// constants won’t change. Used here to set a pin number:
const int ledPin = LED_BUILTIN;// the number of the LED pin

// Variables will change:

String read_rfid; // Add how many you need and don’t forget to include the UID.
String ok_rfid_1=“e199312d”; // This is for my main RFID Card. aka. The one I will be using to turn on my PC. Can also be used to shut it down if you want to.
int relay1 = 7; // For the Card.
int relay1 = LOW; // ledState used to set the LED

// Generally, you should use “unsigned long” for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0; // will store last time LED was updated

// constants won’t change:
const long interval = 1000; // interval at which to blink (milliseconds)

void setup() {
// set the digital pin as output:

Serial.begin(9600); // Initialize serial communications with the PC
while (!Serial); // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
SPI.begin(); // Init SPI bus
mfrc522.PCD_Init(); // Init MFRC522 card

//Choose which lock below:
pinMode(relay1, OUTPUT);
pinMode(relay1, OUTPUT);
}
void dump_byte_array(byte buffer, byte bufferSize) {
read_rfid="";
for (byte i = 0; i < bufferSize; i++) {
read_rfid=read_rfid + String(buffer
, HEX);*
void loop() {

  • // here is where you’d put code that needs to be running all the time.*

  • // check to see if it’s time to blink the LED; that is, if the difference*

  • // between the current time and last time you blinked the LED is bigger than*

  • // the interval at which you want to blink the LED.*

  • unsigned long currentMillis = millis();*

  • if millis()-previousMillis > timeout;*

  • if (currentMillis - previousMillis >= interval) {*

  • // save the last time you blinked the LED*

  • previousMillis = currentMillis;*

  • }*

  • // Look for new cards*

  • if ( ! mfrc522.PICC_IsNewCardPresent())*

  • return;*

  • // Select one of the cards*

  • if ( ! mfrc522.PICC_ReadCardSerial())*

  • return;*

  • dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size);*

  • Serial.println(read_rfid);*

  • if (read_rfid==ok_rfid_1) {*

  • // if the LED is off turn it on and vice-versa:*

  • if (relay1 == LOW) {*

  • relay1 = HIGH;*

  • } else {*

  • relay1 = LOW;*

  • }*

  • // set the LED with the ledState of the variable:*

  • digitalWrite(ledPin, ledState);*

  • }*
    }

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

#define RST_PIN         9           // Configurable, see typical pin layout above
#define SS_PIN          10          // Configurable, see typical pin layout above

MFRC522 mfrc522(SS_PIN, RST_PIN);   // Create MFRC522 instance.

                                // constants won't change. Used here to set a pin number:
const int RELAY =  7;// the number of the LED pin
String read_rfid;                   // Add how many you need and don't forget to include the UID.
String ok_rfid_1="e199312d";        // This is for my main RFID Card. aka. The one I will be using to turn on my PC. Can also be used to shut it down if you want to.
String ok_rfid_2="fbecb673";        // This is for the RFID Keyfob. aka. Shutdown Keyfob. Not advisable tho. Just shutdown your PC normally.
int RELAY = LOW

// The value will quickly become too large for an int to store
unsigned long previousMillis = 0;        // will store last time RELAY was updated
                    
/*
 * Initialize.
 */
void setup() {
    Serial.begin(9600);         // Initialize serial communications with the PC
    while (!Serial);            // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
    SPI.begin();                // Init SPI bus
    mfrc522.PCD_Init();         // Init MFRC522 card

   
    pinMode(RELAY, OUTPUT);
   
}
/*
 * Helper routine to dump a byte array as hex values to Serial.
 */
void dump_byte_array(byte *buffer, byte bufferSize) {
    read_rfid="";
    for (byte i = 0; i < bufferSize; i++) {
        read_rfid=read_rfid + String(buffer[i], HEX);
    }
}



void loop() {
 
  // check to see if it's time to switch the RELAY; that is, if the difference
  // between the current time and last time you switched the RELAY is bigger than
  // the interval at which you want to switch the RELAY.
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;
    
  if millis()-previousMillis > timeout
    
    // if the RELAY is off turn it on and vice-versa:
    if (RELAY == LOW) {
      RELAY = HIGH;
    } else {
      RELAY = LOW;
    }
      // Look for new cards
    if ( ! mfrc522.PICC_IsNewCardPresent())
        return;

    // Select one of the cards
    if ( ! mfrc522.PICC_ReadCardSerial())
        return;

    dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size);
    Serial.println(read_rfid);
    if (read_rfid==ok_rfid_1) {
      //ok, open the door.
      open_lock();
    }

    Serial.println(read_rfid);
    if (read_rfid==ok_rfid_2) {
      //ok, open the door.
      close_lock2();
    }
    //Add below as many "keys" as you want
    //if (read_rfid==ok_rfid_2) {
      //also ok, open the door
    //  open_lock();
    //}
    // else not needed. Anything else is not ok, and will not open the door...
}

Okay this is what i’ve got so far, i figured i’d post what i’ve done before bed.
I feel a bit better about posting this one haha.
I’ve obviously got a few errors as it’s incomplete.
I really really appreciate your help with this. I’ll have a read through the sticky posts tomorrow morning :slight_smile:

Try compiling it. There are a number of simple things to fix.

I haven’t connected any hardware but this compiles.
It IS awfull code, it should only show you what I’ve ment in #1.

// switch on output as long as valid key is read

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

#define RST_PIN         9           // Configurable, see typical pin layout above
#define SS_PIN          10          // Configurable, see typical pin layout above

MFRC522 mfrc522(SS_PIN, RST_PIN);   // Create MFRC522 instance.

String read_rfid;                   // Add how many you need and don't forget to include the UID.
String ok_rfid_1 = "e199312d";      // This is for my main RFID Card. aka. The one I will be using to turn on my PC. Can also be used to shut it down if you want to.

const uint8_t outputPin = 7;
const uint16_t timeout = 500;       // after how many ms the GPIO will set to LOW
uint32_t previousMillis;            // timestamp of last


/*
   Initialize.
*/
void setup() {
  Serial.begin(115200);       // Initialize serial communications with the PC
  while (!Serial);            // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
  SPI.begin();                // Init SPI bus
  mfrc522.PCD_Init();         // Init MFRC522 card

  pinMode(outputPin, OUTPUT);
}
/*
   Helper routine to dump a byte array as hex values to Serial.
*/
void dump_byte_array(byte *buffer, byte bufferSize) {
  read_rfid = "";
  for (byte i = 0; i < bufferSize; i++) {
    read_rfid = read_rfid + String(buffer[i], HEX);
  }
}

void valid_rfid()
{
  previousMillis = millis();
  if (digitalRead(outputPin) == LOW)
    digitalWrite(outputPin, HIGH);
}

void loop() {
  // check if it is time to shut down the output
  if (digitalRead(outputPin) == HIGH && millis() - previousMillis > timeout)
  {
    digitalWrite(outputPin, LOW);
  }

  // Look for new cards
  if ( ! mfrc522.PICC_IsNewCardPresent())
    return;

  // Select one of the cards
  if ( ! mfrc522.PICC_ReadCardSerial())
    return;

  dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size);
  Serial.println(read_rfid);
  if (read_rfid == ok_rfid_1) {
    valid_rfid();
  }
}

For your purpose, here is the code I’ve decided to make opensource with credits, as I found someone was stealing my codes and ideas for commercial purpose and made a good amount of money too…

It was the first kind of cloud type thing, which sends polling data, and also posts into SQL directly via a php script. It’s hugely used in my hotel for in-out reporting and i tried to implement it in a school and the vendor stolen it and made his money. (I was given the task of development by a brigadier general who was transferred and new admin appointed new vendor and new vendor cheated).

The device serial generation is not quite good here and in my another project I corrected that. the library bdneteeprom2.h is basically a modified version of neteeprom2.h.

/*
 *  Target Hardware: mega2560
 *  
 *  Target Network module W5500
 *  
 *  The system uses Weigand 26 and readers are supporting both. Thus it needsproper selection via reader's pins
 *  for ARDUINO MEGA2560 :
 *  Reader 1 :
 *  DATA0 of Wiegand connects to Arduino PIN 2 
 *  DATA1 of Wiegand connects to Arduino PIN 3
 *  Reader 2 :
 *  DATA0 of Wiegand connects to Arduino PIN 21 
 *  DATA1 of Wiegand connects to Arduino PIN 20
 *  Reader 3 :
 *  DATA0 of Wiegand connects to Arduino PIN 19 
 *  DATA1 of Wiegand connects to Arduino PIN 18
 *  
 *  LED is to be pulled down for turning green. Buzzer sounds when pushed hi. 
 *  For both LED and buzzer, we may use smart delay, which is a logical delay (but not code execution halt) so that system
 *  will get enough time to post in server.
 *  
 *  The system will send keepalive every after 3 mins.
 *  The ystem will reboot itself every after 2 hours and few mre seconds.
 *  The system is enabled with a watchdog timer of 8s. Make sure to use the reset watchdog in proper locations.
 *  
 *  EEPROM MAP, each address has 1 byte storage.
 *  
 *  The below address map is available in BDNetEEPROM library
 *  * DEFAULT eepromOffset = 0 [Address 0]
 *  #define MAC_OFFSET (eepromOffset + 1) [Start at 0+1=1, used for MAC (6byte), ends at 6]
 *  #define DHCP_OFFSET (MAC_OFFSET + 6) [Start at 1+6=7, used for DHCP config (1byte), ends at 7]
 *  #define IP_OFFSET (DHCP_OFFSET + 1) [Start at 7+1=8, used for IP config (4byte), ends at 11]
 *  #define DNS_OFFSET (IP_OFFSET + 4) [Start at 11+4=15, used for DNS config (4byte), ends at 18]
 *  #define GW_OFFSET (DNS_OFFSET + 4) [Start at 18+4=22, used for Gateway config (4byte), ends at 25]
 *  #define SUBNET_OFFSET (GW_OFFSET + 4) [Start at 25+4=29, used for Subnet config (4byte), ends at 32]
 *  
 *  Anything else is to be used from Address 33 and onwards. [Aka. ADDR 0-32 RESERVED for NETWORK CONFIG]
 *  Maxthhere has been considered as 100 bytes. 
 *  #define WIEGAND_OFFSET (33) [Start at 33, used for WIEGAND config (1byte), ends at 33]
 *  #define REBOOT_OFFSET (WIEGAND_OFFSET + 1) [Start at 33+1=34, used for REBOOT_OFFSET (1byte), ends at 34]
 *  #define KEEPALIVE_OFFSET (REBOOT_OFFSET + 1) [Start at 34+1=35, used for KEEPALIVE_OFFSET (1byte), ends at 35]
 *  #define SERVER_ADDR_SIZE (WIEGAND_OFFSET + 1) [Start at 35+1=36, used for SERVER_ADDR_SIZE (1byte), ends at 36]
 *  #define SERVER_ADDR_OFFSET (SERVER_ADDR_SIZE + 1) [Start at 36+1=37, used for SERVER_ADDR_OFFSET (100byte including NULL Char), ends at 137]
 *  #define NEXT_STR_SIZE (SERVER_ADDR_OFFSET + 100) [Start at 35+100=135, used for NEXT_STR_SIZE (1byte), ends at 136]
 *  #define NEXT_STR_OFFSET (NEXT_STR_SIZE + 1) [Start at 137+1=138, used for NEXT_STR_OFFSET (100byte including NULL Char), ends at 238]
 *  
 * 
*/

#include <SPI.h>
#include <Ethernet2.h>
#include <EEPROM.h>
#include <BDNetEEPROM2.h> //Special library for banglardamal.org's NetEEPROM
#include <Wiegand.h>
#include <elapsedMillis.h>
#include <avr/wdt.h>
#include <MemoryFree.h>

#define fw_ver "2.1.0"
#define softwareTAG "NRFID20171216"

#define hwSS 53
#define ethCS 10
#define systemLED 13
#define readerLED 4
#define buzzer 5
#define protocolSelector 6
#define configTimeoutTick 60000 //1 min

// EEPROM Address Definitions
//#define STRING_LENGTH_BYTE 100
#define DHCP_OFFSET 7 //Originally 7 as per BDNetEEPROM library
#define WIEGAND_OFFSET 33
#define REBOOT_OFFSET (WIEGAND_OFFSET + 1)
#define KEEPALIVE_OFFSET (REBOOT_OFFSET + 1)
#define SERVER_ADDR_SIZE (KEEPALIVE_OFFSET + 1)
#define SERVER_ADDR_OFFSET (SERVER_ADDR_SIZE + 1)

// The necessary variables for RS232 Communication
//String sub_str = "";
String str_rx = "";

String data = "";
boolean isBusy = false;
boolean inetOK;
unsigned long rebootTimer;
unsigned long keepAliveTimer;

// Initialize the Ethernet client library
// with the IP address and port of the server
// that you want to connect to (port 80 is default for HTTP):
EthernetServer server(8080);
EthernetClient client;
elapsedMillis keepAliveTimeElapsed;
elapsedMillis systemRunningTimeElapsed;
elapsedMillis configTimeoutTimer;
WIEGAND wg;

void setup() {
  pinMode(hwSS, OUTPUT);
  pinMode(buzzer, OUTPUT);
  pinMode(readerLED, OUTPUT);
  pinMode(systemLED, OUTPUT);
  digitalWrite(buzzer, LOW);
  digitalWrite(readerLED, HIGH);
  digitalWrite(systemLED, HIGH);
  delay(100);
  digitalWrite(buzzer, HIGH);
  rebootTimer = EEPROM.read(REBOOT_OFFSET) * 3600000;
  keepAliveTimer = EEPROM.read(KEEPALIVE_OFFSET) * 60000;
  
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  splashScreen();
  Serial.println();
  Serial.println(F("Type 'conf t' in 4 seconds to enter config mode\n"));
  smartDelayPrompt(4000);
  //Config the system
  if (str_rx == "conf t") {
    str_rx = ""; 
    configMode();
  }
  wdt_enable(WDTO_8S);
  wiegandInit();
  Serial.println();
  // start the Ethernet connection:
  if (inetInit()){
    Serial.println(F("Ethernet is up and ready with the config:"));
    showNetConfig ();
    keepAlive();
    digitalWrite(readerLED, LOW);
    digitalWrite(systemLED, LOW);
  } else {Serial.println(F("Ethernet failed to be ready."));soft_reset(3000);}
  
}

void loop() {
  wdt_reset();
  digitalWrite(readerLED, LOW);
  digitalWrite(systemLED, LOW);

  while (Serial.available() > 0){
    str_rx = String(Serial.readStringUntil('\n'));
    if (str_rx == "conf t") {
      str_rx = ""; 
      configMode();
    }
  }
  
  if(wg.available()) {
    wdt_reset();
    isBusy = true;
    digitalWrite(readerLED, HIGH);
    //delay(500);
    Serial.print(F("Wiegand HEX = "));
    Serial.print(wg.getCode(),HEX);
    Serial.print(F(", DECIMAL = "));
    Serial.print(wg.getCode());
    Serial.print(F(", Type W"));
    Serial.println(wg.getWiegandType());    

    data = String(wg.getCode());
    data.trim();
    Serial.print(F("Found Data:"));
    Serial.println(data);
    postData();
    delay(1000);
    data = "";
    digitalWrite(readerLED, LOW);
    isBusy = false;
  }

  if (keepAliveTimeElapsed > keepAliveTimer) {        
      if (isBusy == false) {
        isBusy = false;
        keepAlive(); 
      }
  }

  if (systemRunningTimeElapsed > rebootTimer) {        
      if (isBusy == false) {
        isBusy = false;
        soft_reset(3000); 
      }
  }

}


// End of main loop
// ================================ BELOW ARE THE CUSTOM FUNCTIONS THAT WE MAY NEED ================================ //

// This custom version of delay() ensures that the Serial object is being "fed".
static void smartDelayPrompt(unsigned long ms) {
  unsigned long start = millis();
  do {
    while (Serial.available() > 0){  
      str_rx = String(Serial.readStringUntil('\n'));
    }
  } 
  while (millis() - start < ms);
  //do something
}

// The software Reset Function
void soft_reset(int a) {
  Serial.print(F("System Reboot in "));
  Serial.print(a/1000);
  Serial.println(F(" seconds..."));
  wdt_reset();
  delay(a);
  wdt_reset(); 
  asm volatile (" jmp 0 "); 
}

// the splash screen
void splashScreen() {
  Serial.println();
  Serial.println(F("********************************"));
  Serial.println(F("***     banglardamal.org     ***"));
  Serial.println(F("********************************"));
  Serial.println();
  Serial.println(F("n-RFID Network Node Unit"));
  Serial.println(F("Code Name: n-RFID MARK-I"));
  Serial.print(F("Firmware Version: "));
  Serial.println(fw_ver);
  Serial.print(F("Software Tag: "));
  Serial.println(softwareTAG);
  Serial.flush();
  teachersDayTribute();
  Serial.println();
}

// interface initialization
bool inetInit() {
  wdt_reset();
  inetOK = false;
  NetEeprom.begin();
  delay(2000);
  Serial.flush();
  inetOK = true;
  return true;
}

// interface initialization
void wiegandInit() {
  // PIN assigment and declaration for Arduino Mega 
  //GATE A 
  wg.D0PinA =2;   
  wg.D1PinA =3;   

  //GATE B
  wg.D0PinB =18;  
  wg.D1PinB =19;   

  //GATE C
  wg.D0PinC =20;  
  wg.D1PinC =21;
  bool reader[1];
  int readerConfig = EEPROM.read(WIEGAND_OFFSET);
  switch (readerConfig) {
        case 000:
        {
          reader[0] = 0;
          reader[1] = 0;
          reader[2] = 0;
        }
        
        break;
        case 100:
        {
          reader[0] = 1;
          reader[1] = 0;
          reader[2] = 0;
        }
        break;
        case 110:
        {
          reader[0] = 1;
          reader[1] = 1;
          reader[2] = 0;
        }
        break;
        case 111:
        {
          reader[0] = 1;
          reader[1] = 1;
          reader[2] = 1;
        }
        break;
        default:
        {
          reader[0] = 1;
          reader[1] = 0;
          reader[2] = 0;
        }
        break;
      }
  
  if(wg.begin(reader[0], reader[1], reader[2])){
    Serial.println(F("Wiegand Link UP"));
  } else {Serial.println(F("Weigand Lik failed to active."));}
  Serial.flush();

}

void showNetConfig () {
  if (NetEeprom.checkMagic()) {
    byte mac[6];
    NetEeprom.readMac(mac);
    Serial.print(F("MAC: ")); printMac(mac); Serial.println();
    if (NetEeprom.isDhcp()) {
      Serial.println(F("Network configured using DHCP"));
    } else {
      byte addr[4];
      NetEeprom.readIp(addr);
      Serial.print(F("IP: ")); printIp(addr); Serial.println();
      NetEeprom.readDns(addr);
      Serial.print(F("DNS: ")); printIp(addr); Serial.println();
      NetEeprom.readGateway(addr);
      Serial.print(F("GW: ")); printIp(addr); Serial.println();
      NetEeprom.readSubnet(addr);
      Serial.print(F("Subnet: ")); printIp(addr); Serial.println();
    }
  } else {
    Serial.println(F("Network MAC and IP have not been configured"));
  }
  Serial.flush();
}

// post data to server
void postData() {
  if (!inetOK) {
    inetInit();
  }
  wdt_reset();
  unsigned int strSize = EEPROM.read(SERVER_ADDR_SIZE);
  char server[strSize];
  eeprom_read_string(SERVER_ADDR_OFFSET, server, strSize);
  String myURL = "GET /attd_posting.php?tag=";
  myURL += data;
  myURL += " HTTP/1.1";
  digitalWrite(readerLED, HIGH);
  digitalWrite(systemLED, HIGH);
  client.stop();
  Serial.println(F("Connecting to server..."));
  // if you get a connection, report back via serial:
  
  if (client.connect(server, 80)) {
    Serial.println(F("Connected!"));
    // Make a HTTP request:
    Serial.println(F("Posting..."));
    client.println(myURL);
    Serial.println(myURL);
    client.print("Host: ");
    client.println(server);
    Serial.print(F("Host: "));
    Serial.println(server);
    client.println("Connection: close");
    client.println();
    Serial.println(F("Posted. Disconnecting from Server."));
    Serial.println();
    client.flush();
    client.stop();
    Serial.println(F("Connection closed"));
    digitalWrite(systemLED, LOW);
    digitalWrite(readerLED, LOW);
  }
  // if the server's disconnected, stop the client: A fail safe
  else if (!client.connected()) {
    client.stop();
    Serial.println(F("Posting failed."));
  }
  else {
    // if you didn't get a connection to the server:
    Serial.println(F("Posting failed."));
  }
  Serial.flush();
  keepAliveTimeElapsed = 0;
  
}

// keep alive function
void keepAlive() {
  if (!inetOK) {
    inetInit();
  }
  wdt_reset();
  unsigned int strSize = EEPROM.read(SERVER_ADDR_SIZE);
  char server[strSize];
  eeprom_read_string(SERVER_ADDR_OFFSET, server, strSize);
  String myURL = "GET /attd_posting.php?keepalive=1 HTTP/1.1";
  digitalWrite(readerLED, HIGH);
  digitalWrite(systemLED, HIGH);
  client.stop();
  Serial.print(F("Time elapsed since last reboot: "));
  Serial.println(systemRunningTimeElapsed);
  Serial.println(F("Sending Keepalive to server..."));
  // if you get a connection, report back via serial:
  if (client.connect(server, 80)) {
    Serial.println(F("Connected!"));
    // Make a HTTP request:
    client.println(myURL);
    Serial.println(myURL);
    client.print("Host: ");
    client.println(server);
    Serial.print(F("Host: "));
    Serial.println(server);
    client.println("Connection: close");
    client.println();
    client.flush();
    client.stop();
    Serial.println(F("Connection closed"));
    //Serial.println();
    digitalWrite(systemLED, LOW);
    digitalWrite(readerLED, LOW);
  }
  // if the server's disconnected, stop the client: A fail safe
  else if (!client.connected()) {
    client.stop();
    Serial.println(F("Keepalive failed."));
  }
  else {
    // if you didn't get a connection to the server:
    Serial.println(F("Keepalive failed."));
  }

  Serial.print(F("RAM available in bytes: "));
  Serial.print(freeMemory());
  Serial.println();
  Serial.println();
  Serial.flush();
  keepAliveTimeElapsed = 0;
  
}
// Config mode function when initiated "conf t"
void configMode() {
  wdt_reset();
  digitalWrite(readerLED, HIGH);
  configTimeoutTimer = 0;
  String sub_str = "";
  Serial.println(F("Config Mode"));
  Serial.println(F("==========="));
  Serial.println(F("Press '?' for help. type exit to close"));
  Serial.println();
  Serial.print(F(">"));
  while (str_rx != "exit") {
    wdt_reset();
    if (Serial.available() > 0) {
      //Read until the newline \n comes from serial
      str_rx = String(Serial.readStringUntil('\n'));
      configTimeoutTimer = 0;
    }
    
    if (str_rx.startsWith("set dhcp enable")) { //Set Low Temperature Limit (where compressor will go OFF)
      Serial.println(F("DHCP enabled."));
      EEPROM.write(DHCP_OFFSET, 1);
      Serial.print(F(">"));
      Serial.flush();
      str_rx = "";
    }

    if (str_rx.startsWith("set dhcp disable")) { //Set Low Temperature Limit (where compressor will go OFF)
      Serial.println(F("DHCP disabled."));
      EEPROM.write(DHCP_OFFSET, 0);
      Serial.print(F(">"));
      Serial.flush();
      str_rx = "";
    }
    
    if (str_rx.startsWith("set ip ")) { //Set Low Temperature Limit (where compressor will go OFF)
      sub_str = str_rx.substring(7);
      String sub_str2 = "";
      int dotIndex = sub_str.indexOf('.');
      int secondDotIndex = sub_str.indexOf('.', dotIndex + 1);
      int thirdDotIndex = sub_str.indexOf('.', secondDotIndex + 1);
      sub_str2 = sub_str.substring(0, dotIndex);
      int ip_A = sub_str2.toInt();
      sub_str2 = sub_str.substring(dotIndex + 1, secondDotIndex);
      int ip_B = sub_str2.toInt();
      sub_str2 = sub_str.substring(secondDotIndex + 1, thirdDotIndex);
      int ip_C = sub_str2.toInt();
      sub_str2 = sub_str.substring(thirdDotIndex + 1); // To the end of the string
      int ip_D = sub_str2.toInt();

      byte ip[4] = { ip_A, ip_B, ip_C, ip_D };
      Serial.println("IP set to: " + sub_str);
      NetEeprom.writeIPConfig(ip);
      Serial.print(F(">"));
      Serial.flush();
      str_rx = "";
      sub_str = "";
    }
    
    if (str_rx.startsWith("set subnet ")) { //Set Low Temperature Limit (where compressor will go OFF)
      sub_str = str_rx.substring(11);
      String sub_str2 = "";
      int dotIndex = sub_str.indexOf('.');
      int secondDotIndex = sub_str.indexOf('.', dotIndex + 1);
      int thirdDotIndex = sub_str.indexOf('.', secondDotIndex + 1);
      sub_str2 = sub_str.substring(0, dotIndex);
      int ip_A = sub_str2.toInt();
      sub_str2 = sub_str.substring(dotIndex + 1, secondDotIndex);
      int ip_B = sub_str2.toInt();
      sub_str2 = sub_str.substring(secondDotIndex + 1, thirdDotIndex);
      int ip_C = sub_str2.toInt();
      sub_str2 = sub_str.substring(thirdDotIndex + 1); // To the end of the string
      int ip_D = sub_str2.toInt();

      byte ip[4] = { ip_A, ip_B, ip_C, ip_D };
      Serial.println("Subnet set to: " + sub_str);
      NetEeprom.writeSubnetConfig(ip);
      Serial.print(F(">"));
      Serial.flush();
      str_rx = "";
      sub_str = "";
    }

    if (str_rx.startsWith("set gateway ")) { //Set Low Temperature Limit (where compressor will go OFF)
      sub_str = str_rx.substring(12);
      String sub_str2 = "";
      int dotIndex = sub_str.indexOf('.');
      int secondDotIndex = sub_str.indexOf('.', dotIndex + 1);
      int thirdDotIndex = sub_str.indexOf('.', secondDotIndex + 1);
      sub_str2 = sub_str.substring(0, dotIndex);
      int ip_A = sub_str2.toInt();
      sub_str2 = sub_str.substring(dotIndex + 1, secondDotIndex);
      int ip_B = sub_str2.toInt();
      sub_str2 = sub_str.substring(secondDotIndex + 1, thirdDotIndex);
      int ip_C = sub_str2.toInt();
      sub_str2 = sub_str.substring(thirdDotIndex + 1); // To the end of the string
      int ip_D = sub_str2.toInt();

      byte ip[4] = { ip_A, ip_B, ip_C, ip_D };
      Serial.println("Gateway set to: " + sub_str);
      NetEeprom.writeGWConfig(ip);
      Serial.print(F(">"));
      Serial.flush();
      str_rx = "";
      sub_str = "";
    }
    
    if (str_rx.startsWith("set dns ")) { //Set Low Temperature Limit (where compressor will go OFF)
      sub_str = str_rx.substring(8);
      String sub_str2 = "";
      int dotIndex = sub_str.indexOf('.');
      int secondDotIndex = sub_str.indexOf('.', dotIndex + 1);
      int thirdDotIndex = sub_str.indexOf('.', secondDotIndex + 1);
      sub_str2 = sub_str.substring(0, dotIndex);
      int ip_A = sub_str2.toInt();
      sub_str2 = sub_str.substring(dotIndex + 1, secondDotIndex);
      int ip_B = sub_str2.toInt();
      sub_str2 = sub_str.substring(secondDotIndex + 1, thirdDotIndex);
      int ip_C = sub_str2.toInt();
      sub_str2 = sub_str.substring(thirdDotIndex + 1); // To the end of the string
      int ip_D = sub_str2.toInt();

      byte ip[4] = { ip_A, ip_B, ip_C, ip_D };
      Serial.println("DNS set to: " + sub_str);
      NetEeprom.writeDNSConfig(ip);
      Serial.print(F(">"));
      Serial.flush();
      str_rx = "";
      sub_str = "";
    }
if (str_rx.startsWith("set server ")) { //Set Server Address where it will knock)
      sub_str = str_rx.substring(11);
      sub_str.trim(); // example, www.banglardamal.org with a length = 20
      unsigned int strSize = sub_str.length()+1; //size calculated including NULL terminator '\0' We need it later for reading and last byte address known.
      EEPROM.write(SERVER_ADDR_SIZE, strSize); //has written 21 for www.banglardamal.org including NULL terminator.
      char strBuff[strSize]; //[21] for www.banglardamal.org
      char myStringChar[strSize];
      sub_str.toCharArray(myStringChar, strSize); //convert the string to an array of chars.
      strcpy(strBuff, myStringChar);

      eeprom_write_string(SERVER_ADDR_OFFSET, strBuff);

      //Now read it back for confirmation
      strSize = EEPROM.read(SERVER_ADDR_SIZE);
      eeprom_read_string(SERVER_ADDR_OFFSET, strBuff, strSize);
      Serial.print(F("Server set to: "));
      Serial.println(strBuff);
      
      Serial.print(F(">"));
      Serial.flush();
      sub_str = "";
      str_rx = "";
    }

    if (str_rx.startsWith("set reader ")) { //Set Low Temperature Limit (where compressor will go OFF)
      sub_str = str_rx.substring(11);
      switch (sub_str.toInt()) {
        case 000:
        {
          EEPROM.write(WIEGAND_OFFSET, 000);
          Serial.println(F("All three readers are turned OFF."));
        }
        
        break;
        case 100:
        {
          EEPROM.write(WIEGAND_OFFSET, 100);
          Serial.println(F("Only First reader is turned ON."));
        }
        break;
        case 110:
        {
          EEPROM.write(WIEGAND_OFFSET, 110);
          Serial.println(F("Reader 1 and 2 are turned ON."));
        }
        break;
        case 111:
        {
          EEPROM.write(WIEGAND_OFFSET, 111);
          Serial.println(F("All three readers are turned ON."));
        }
        break;
        default:
        {
          EEPROM.write(WIEGAND_OFFSET, 100);
          Serial.println(F("Only First reader is turned ON."));
        }
        break;
      }
      
      Serial.print(F(">"));
      Serial.flush();
      str_rx = "";
      sub_str = "";
    }

    if (str_rx.startsWith("set reboot ")) { //Set Low Temperature Limit (where compressor will go OFF)
      sub_str = str_rx.substring(11);
      EEPROM.write(REBOOT_OFFSET, sub_str.toInt());
      Serial.print(F("Reboot Timer set to "));
      Serial.print(sub_str);
      Serial.println(F(" hr"));
      Serial.print(F(">"));
      Serial.flush();
      str_rx = "";
    }

    if (str_rx.startsWith("set keepalive ")) { //Set Low Temperature Limit (where compressor will go OFF)
      sub_str = str_rx.substring(14);
      EEPROM.write(KEEPALIVE_OFFSET, sub_str.toInt());
      Serial.print(F("KeeAlive Timer set to "));
      Serial.print(sub_str);
      Serial.println(F(" min"));
      Serial.print(F(">"));
      Serial.flush();
      str_rx = "";
    }
    
    if (str_rx.startsWith("show run")) { //show the current config
      Serial.println();
      Serial.println(F("Displaying the running config..."));
      showNetConfig();
      Serial.print(F("Reader Active: "));
      Serial.println(EEPROM.read(WIEGAND_OFFSET), DEC);

      /*
      unsigned int strSize = EEPROM.read(SERVER_ADDR_SIZE);
      char strBuff[strSize]; //[21] for www.banglardamal.org
      Serial.print("Server Addr via eeprom: ");
      eeprom_read_string(SERVER_ADDR_OFFSET, strBuff, strSize);
      Serial.println(strBuff);
      */

      String server;
      getServerURL(server);
      Serial.print(F("Server to post data: "));
      Serial.println(server);
      Serial.print(F("System Auto Reboot after hours: "));
      Serial.println(EEPROM.read(REBOOT_OFFSET), DEC);
      Serial.print(F("Send Keepalive after minutes: "));
      Serial.println(EEPROM.read(KEEPALIVE_OFFSET), DEC);
      
      Serial.print(F(">"));
      Serial.flush();
      str_rx = "";
    }
    
    if ((str_rx.startsWith("?"))||(str_rx.startsWith("help"))) { //show the help
      Serial.println();
      Serial.println(F("HELP:::\n\r"));
      Serial.println(F("set dhcp enable/disable \n\r[To set the DHCP confg enable or disable.]\n\r"));
      Serial.println(F("set ip \n\r[To set the IP address of the device. \n\rFormat: A.B.C.D]\n\r"));
      Serial.println(F("set subnet \n\r[To set the Subnet Mask of the device. \n\rFormat: A.B.C.D]\n\r"));
      Serial.println(F("set gateway \n\r[To set the Gateway IP address of the device. \n\rFormat: A.B.C.D]\n\r"));
      Serial.println(F("set dns \n\r[To set the dns of the device. \n\rFormat: A.B.C.D]\n\r"));
      Serial.println(F("set server \n\r[To set the server FQDN/IP where the device will post data. \n\rFormat: domain.com or subdomain.domain.com or IP Address of server]\n\r"));
      Serial.println(F("set reader \n\r[To set the reader of the device. \n\rFormat: 000 OR 100 OR 110 OR 111 Where each 1 and 0 means ON/OFF of reader 1,2,3 (Reader 3 is not used now)]\n\r"));
      Serial.println(F("set reboot \n\r[To set the system auto reboot time in Hours. Value must be integer, range 1 - 255]\n\r"));
      Serial.println(F("set keepalive \n\r[To set the keepalive signal interval time in Minutes. Value must intger, range 1 - 255]\n\r"));
      Serial.println(F("show run\n\r[To see running config.]\n\r"));
      Serial.println(F("exit\n\r[To exit from config mode and reboot device.]\n\r"));
      Serial.print(F(">"));
      Serial.flush();
      str_rx = "";
    }

    if (configTimeoutTimer > configTimeoutTick) {        
      if (isBusy == false) {
        isBusy = false;
        Serial.println("Config mode timeout...");
        soft_reset(3000); 
      }
    }
  }
  
  Serial.println();
  Serial.println(F("Quitting from config mode"));
  Serial.flush();
  soft_reset(3000);
}
// Print the MAC of the device in a human readable way
void printMac(byte mac[]) {
  for (int i = 0; i < 6; i++) {
    if (i > 0) {
      Serial.print(":");
    }
    if (mac[i] < 0x10) {
      Serial.print("0");
    }
    Serial.print(mac[i], HEX);
  }
}

void netconf() {
    // wait for a new client:
    EthernetClient client = server.available();
    String socketString = "";
    // when the client sends the first byte, say hello:
    if (client) {
      if (!alreadyConnected) {
        // clear out the input buffer:
        client.flush();
        Serial.println("New client connected");
        //Serial.println(client.remoteIP());
        client.write("Connection OK");
        alreadyConnected = true;
        isBusy = true;
      }
  
      // Read a line at a time
      boolean lineEnd = false;
      while (!lineEnd) {
        while (client.available() > 0) {
            char c = client.read();
            if (c != '\n' && c != '\r') {
              socketString.concat(c);
            }
            if (c == '\n') {
              lineEnd = true;
              client.flush();
            }
          }
        }
      Serial.print("Remote said:");
      Serial.println(socketString);
      if (socketString == "ping") {
        String pong = "";
        pong = String(25) + ";" + String(24) + ";" + String(0) + ";" + String(20);
        pong = String(pong + ";" + "C1" + ";" + "F1" + ";" + "D0" + ";" + "A0" + ";");
        server.print(pong);
        Serial.print("I said:");
        Serial.println(pong);
        isBusy = false;
      }
    }
    /*
    else if (!client){
      alreadyConnected = false;
      Serial.println("Client disconnected");
    }*/
}

// Print the IP/Gateway/Subnet of the device in a humman readable way
void printIp(byte ip[]) {
  for (int i = 0; i < 4; i++) {
    if (i > 0) {
      Serial.print(".");
    }
    Serial.print(ip[i]);
  }
}

// Returns true if the address is between the
// minimum and maximum allowed values, false otherwise.
//
// This function is used by the other, higher-level functions
// to prevent bugs and runtime errors due to invalid addresses.
boolean eeprom_is_addr_ok(int addr, int buffSize, int maxBuffSize) {
  return ((addr + buffSize <= maxBuffSize));
  //return ((addr >= EEPROM_MIN_ADDR) && (addr <= EEPROM_MAX_ADDR));
}

// Writes a sequence of bytes to eeprom starting at the specified address.
// Returns true if the whole array is successfully written.
// Returns false if the start or end addresses aren't between
// the minimum and maximum allowed values.
// When returning false, nothing gets written to eeprom.
boolean eeprom_write_bytes(int startAddr, const byte* array, int numBytes) {
  // counter
  int i;
  int EEPROM_MAX_ADDR = (startAddr + 99); //This is the total byte (ADDR) allocation for one string. 99 bytes including the given one (addr) + 1byte NULL Terminator.
  // both first byte and last byte addresses must fall within
  // the allowed range 
  //if (!eeprom_is_addr_ok(startAddr) || !eeprom_is_addr_ok(startAddr + numBytes)) {
    //return false;
  //}
  if (!eeprom_is_addr_ok(startAddr, numBytes, EEPROM_MAX_ADDR)) { // check start address
    return false;
  }
  for (i = 0; i < numBytes; i++) {
    EEPROM.write(startAddr + i, array[i]);
  }
  return true;
}
  
// Writes a string starting at the specified address.
// Returns true if the whole string is successfully written.
// Returns false if the address of one or more bytes fall outside the allowed range.
// If false is returned, nothing gets written to the eeprom.
boolean eeprom_write_string(int addr, const char* string) {
  int numBytes; // actual number of bytes to be written
  //write the string contents plus the string terminator byte (0x00)
  numBytes = strlen(string) + 1;
  return eeprom_write_bytes(addr, (const byte*)string, numBytes);
}

// Reads a string starting from the specified address.
// Returns true if at least one byte (even only the string terminator one) is read.
// Returns false if the start address falls outside the allowed range or declare buffer size is zero.
// 
// The reading might stop for several reasons:
// - no more space in the provided buffer
// - last eeprom address reached
// - string terminator byte (0x00) encountered.
boolean eeprom_read_string(int addr, char* buffer, int buffSize) {
  int EEPROM_MAX_ADDR = (addr + 99); //This is the total byte (ADDR) allocation for one string. 99 bytes including the given one (addr) + 1byte NULL Terminator.
  byte ch; // byte read from eeprom
  int bytesRead; // number of bytes read so far
  if (!eeprom_is_addr_ok(addr, buffSize, EEPROM_MAX_ADDR)) { // check start address
    return false;
  }
  
  if (buffSize == 0) { // how can we store bytes in an empty buffer ?
    return false;
  }
  // is there is room for the string terminator only, no reason to go further
  if (buffSize == 1) {
    buffer[0] = 0;
    return true;
  }
  bytesRead = 0; // initialize byte counter
  ch = EEPROM.read(addr + bytesRead); // read next byte from eeprom
  buffer[bytesRead] = ch; // store it into the user buffer
  bytesRead++; // increment byte counter
  // stop conditions:
  // - the character just read is the string terminator one (0x00)
  // - we have filled the user buffer
  // - we have reached the last eeprom address
  while ( (ch != 0x00) && (bytesRead < buffSize) && ((addr + bytesRead) <= EEPROM_MAX_ADDR) ) {
    // if no stop condition is met, read the next byte from eeprom
    ch = EEPROM.read(addr + bytesRead);
    buffer[bytesRead] = ch; // store it into the user buffer
    bytesRead++; // increment byte counter
  }
  // make sure the user buffer has a string terminator, (0x00) as its last byte
  if ((ch != 0x00) && (bytesRead >= 1)) {
    buffer[bytesRead - 1] = 0;
  }
  return true;
}

//Gives the server URL as String output. Use only if you need the serverURL for several times in severalplaces, as function will reduce code.
void getServerURL(String &server) {
  unsigned int strSize = EEPROM.read(SERVER_ADDR_SIZE);
  char strBuff[strSize];
  eeprom_read_string(SERVER_ADDR_OFFSET, strBuff, strSize);
  server = String(strBuff);
}

void teachersDayTribute() {
  Serial.println();
  Serial.println(F("|---------    Teacher's Day Special Edition    ----------|"));
  Serial.println(F("| This is a special edition of the firmware released as  |"));
  Serial.println(F("| a tribute to our two life changing university teachers |"));
  Serial.println(F("| Dr. Kazi Abu Sayeed; Dr. Arshad Momen                  |"));
  Serial.println(F("| and our Parents.                                       |"));
  Serial.println(F("|                                        - Mishu & Mishu |"));
  Serial.println(F("|--------------------------------------------------------|"));
  Serial.println();
  Serial.flush();
}

Note: I could use the char strbuff instead of string and that's faaaaar better. But i used that as config mode will be used for a while only, and hence STRING issue will not make that effect i though.

Anyone can make edits and improvements will be highly appreciated.

@noiasca

THANK YOU SO MUCH IT WORKS PERFECTLY!

// switch on output as long as valid key is read

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

#define RST_PIN         9           // Configurable, see typical pin layout above
#define SS_PIN          10          // Configurable, see typical pin layout above

MFRC522 mfrc522(SS_PIN, RST_PIN);   // Create MFRC522 instance.

String read_rfid;                   // Add how many you need and don't forget to include the UID.
String ok_rfid_1 = "65f7b15";      // This is for my main RFID Card. aka. The one I will be using to turn on my PC. Can also be used to shut it down if you want to.

const uint8_t outputPin = 7;
const uint16_t timeout = 500;       // after how many ms the GPIO will set to LOW
uint32_t previousMillis;            // timestamp of last


/*
   Initialize.
*/
void setup() {
  Serial.begin(115200);       // Initialize serial communications with the PC
  while (!Serial);            // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
  SPI.begin();                // Init SPI bus
  mfrc522.PCD_Init();         // Init MFRC522 card

  pinMode(outputPin, OUTPUT);
}
/*
   Helper routine to dump a byte array as hex values to Serial.
*/
void dump_byte_array(byte *buffer, byte bufferSize) {
  read_rfid = "";
  for (byte i = 0; i < bufferSize; i++) {
    read_rfid = read_rfid + String(buffer[i], HEX);
  }
}

void valid_rfid()
{
  previousMillis = millis();
  if (digitalRead(outputPin) == LOW)
    digitalWrite(outputPin, HIGH);
}

void loop() {
  // check if it is time to shut down the output
  if (digitalRead(outputPin) == HIGH && millis() - previousMillis > timeout)
  {
    digitalWrite(outputPin, LOW);
  }

  // Look for new cards
  if ( ! mfrc522.PICC_IsNewCardPresent())
    return;

  // Select one of the cards
  if ( ! mfrc522.PICC_ReadCardSerial())
    return;

  dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size);
  Serial.println(read_rfid);
  if (read_rfid == ok_rfid_1) {
    valid_rfid();
  }
}

I strongly suggest to avoid String for regular use.