How to make LED stay on after RFID is scanned

I am trying to program an RFID lock to turn on a Green LED when I scan the right card. While the green LED does turn on after I scan the right card, I want it to stay on until I scan the card again to turn it off. I know there is a way to do this but I just can't think of it. Here is the code.

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

#define SS_PIN 10
#define RST_PIN 9
#define LED_G 4 //define green LED pin
#define LED_R 5 //define red LED
MFRC522 mfrc522(SS_PIN, RST_PIN);   // Create MFRC522 instance.

void setup() {
  Serial.begin(9600);   // Initiate a serial communication
  SPI.begin();      // Initiate  SPI bus
  mfrc522.PCD_Init();   // Initiate MFRC522

  pinMode(LED_G, OUTPUT);
  pinMode(LED_R, OUTPUT);

  Serial.println("Put card to the reader...");
  Serial.println();
}
void loop() {
  digitalWrite(LED_R, HIGH);
  // Look for new card
  if ( ! mfrc522.PICC_IsNewCardPresent()) 
  {
    return;
  }
  // Select one of the cards
  if ( ! mfrc522.PICC_ReadCardSerial()) 
  {
    return;
  }
  //Show UID on serial monitor
  Serial.print("UID 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.println();
  Serial.print("Message : ");
  content.toUpperCase();
  if (content.substring(1) == "E9 3B 3B D9") //change here the UID of the card/cards that you want to give access
  {
    Serial.println("Authorized access");
    Serial.println();
    delay(500);
    digitalWrite(LED_R, LOW);
    digitalWrite(LED_G, HIGH);
    delay(3000);
    digitalWrite(LED_G, LOW);
  }
    else   {
    Serial.println(" Access denied");
    digitalWrite(LED_R, LOW);
    delay(1000);
    digitalWrite(LED_R, HIGH);
    delay(1000);
    digitalWrite(LED_R, LOW);
    delay(1000);
    digitalWrite(LED_R, HIGH);
    delay(1000);
    digitalWrite(LED_R, LOW);
    delay(1000);
    digitalWrite(LED_R, HIGH);
    delay(1000);
    digitalWrite(LED_R, LOW);
    delay(1000);
    digitalWrite(LED_R, HIGH);
    delay(1000);
    digitalWrite(LED_R, LOW);
    
    }

}

OK, first things first.

You need to go and read the forum instructions so that you can go back and modify your original post (not re-post it) - using the "More -> Modify" option below the right hand corner of your post - to mark up your code as such using the "</>" icon in the posting window. Just highlight each section of code (or output if you need to post that) from the IDE and click the icon.

In fact, the IDE itself has a "copy for forum" link to put these markings on a highlighted block for you so you then just paste it here in a posting window. But even before doing that, don't forget to use the "Auto-Format" (Ctrl-T) option first to make it easy to read. If you do not post it as "code" it can as easily be quite garbled and is always more difficult to read due to the font.

It is inappropriate to attach it as a ".ino" file unless it is clearly too long to include in the post proper. People can usually see the mistakes directly and do not want to have to actually load it in their own IDE. And even that would also assume they are using a PC and have the IDE running on that PC.

Also tidy up your blank space. Do use blank lines, but only single blanks between complete functional blocks.

Oh alright, thanks for letting me know. I think I changed it to be good.

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

#define SS_PIN 10
#define RST_PIN 9
#define LED_G 4 //define green LED pin
#define LED_R 5 //define red LED
MFRC522 mfrc522(SS_PIN, RST_PIN);   // Create MFRC522 instance.

void setup() {
 Serial.begin(9600);   // Initiate a serial communication
 SPI.begin();      // Initiate  SPI bus
 mfrc522.PCD_Init();   // Initiate MFRC522

 pinMode(LED_G, OUTPUT);
 pinMode(LED_R, OUTPUT);

 Serial.println("Put card to the reader...");
 Serial.println();
 digitalWrite(LED_R, LOW);
 digitalWrite(LED_G, LOW);
}

void loop() {
 digitalWrite(LED_R, HIGH);
 // Look for new card
 if ( ! mfrc522.PICC_IsNewCardPresent())
 {
   return;
 }
 // Select one of the cards
 if ( ! mfrc522.PICC_ReadCardSerial())
 {
   return;
 }
 digitalWrite(LED_R, LOW);
 digitalWrite(LED_G, LOW);
 //Show UID on serial monitor
 Serial.print("UID 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.println();
 Serial.print("Message : ");
 content.toUpperCase();
 if (content.substring(1) == "E9 3B 3B D9") //change here the UID of the card/cards that you want to give access
 {
   Serial.println("Authorized access");
   Serial.println();
   delay(500);
   digitalWrite(LED_R, LOW);
   digitalWrite(LED_G, HIGH);
   delay(3000);
   if digitalRead(LED_G) == LOW 
     digitalWrite(LED_G, HIGH);
   else 
     digitalWrite(LED_G, LOW);
 }
   else   {
   digitalWrite(LED_G, LOW);
   Serial.println(" Access denied");
   delay(1000);
   digitalWrite(LED_R, HIGH);
   delay(1000);
   digitalWrite(LED_R, LOW);
   delay(1000);
   digitalWrite(LED_R, HIGH);
   delay(1000);
   digitalWrite(LED_R, LOW);
   delay(1000);
   digitalWrite(LED_R, HIGH);
   delay(1000);
   digitalWrite(LED_R, LOW);
   delay(1000);
   digitalWrite(LED_R, HIGH);
   delay(1000);
   digitalWrite(LED_R, LOW);
   }
}

Thanks for trying to help but the green LED still seems to do the same thing it's been doing. Once I scan the right card, the Green LED turns on for 3 seconds then back off.

Michael30040:
Thanks for trying to help but the green LED still seems to do the same thing it's been doing. Once I scan the right card, the Green LED turns on for 3 seconds then back off.

Um, yea. That's what you coded:

  digitalWrite(LED_G, HIGH);
   delay(3000);
   if digitalRead(LED_G) == LOW
     digitalWrite(LED_G, HIGH);
   else
     digitalWrite(LED_G, LOW);

I didn't code that. I want the LED to stay on until I scan the card again.

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

#define SS_PIN 10
#define RST_PIN 9
#define LED_G 4 //define green LED pin
#define LED_R 5 //define red LED
MFRC522 mfrc522(SS_PIN, RST_PIN);   // Create MFRC522 instance.

void setup() {
 Serial.begin(9600);   // Initiate a serial communication
 SPI.begin();      // Initiate  SPI bus
 mfrc522.PCD_Init();   // Initiate MFRC522

 pinMode(LED_G, OUTPUT);
 pinMode(LED_R, OUTPUT);

 Serial.println("Put card to the reader...");
 Serial.println();
 digitalWrite(LED_R, LOW);
 digitalWrite(LED_G, LOW);
}

void loop() {
 digitalWrite(LED_R, HIGH);
 // Look for new card
 if ( ! mfrc522.PICC_IsNewCardPresent())
 {
   return;
 }
 // Select one of the cards
 if ( ! mfrc522.PICC_ReadCardSerial())
 {
   return;
 }
 digitalWrite(LED_R, LOW);
 digitalWrite(LED_G, LOW);
 //Show UID on serial monitor
 Serial.print("UID 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.println();
 Serial.print("Message : ");
 content.toUpperCase();
 if (content.substring(1) == "E9 3B 3B D9") //change here the UID of the card/cards that you want to give access
 {
   Serial.println("Authorized access");
   Serial.println();
   delay(500);
   digitalWrite(LED_R, LOW);
   if digitalRead(LED_G) == LOW
     digitalWrite(LED_G, HIGH);
   else
     digitalWrite(LED_G, LOW);
 }
   else   {
   digitalWrite(LED_G, LOW);
   Serial.println(" Access denied");
   delay(1000);
   digitalWrite(LED_R, HIGH);
   delay(1000);
   digitalWrite(LED_R, LOW);
   delay(1000);
   digitalWrite(LED_R, HIGH);
   delay(1000);
   digitalWrite(LED_R, LOW);
   delay(1000);
   digitalWrite(LED_R, HIGH);
   delay(1000);
   digitalWrite(LED_R, LOW);
   delay(1000);
   digitalWrite(LED_R, HIGH);
   delay(1000);
   digitalWrite(LED_R, LOW);
   }
}

Didn't notice that original rubbish! Removed. :sunglasses:

Ok, that helped a lot. After adding some delays and removing some unneeded code it finally works. The new code is below. I know I've already asked for help once but is there any way I could program the code to not switch from locked to unlock if I hold the right card up to the scanner without removing it? Thanks for helping me out.

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

#define Lock 2
#define SS_PIN 10
#define RST_PIN 9
#define LED_G 4 //define green LED pin
#define LED_R 5 //define red LED
MFRC522 mfrc522(SS_PIN, RST_PIN);   // Create MFRC522 instance.

void setup() {
 Serial.begin(9600);   // Initiate a serial communication
 SPI.begin();      // Initiate  SPI bus
 mfrc522.PCD_Init();   // Initiate MFRC522

 pinMode(Lock,  OUTPUT);
 pinMode(LED_G, OUTPUT);
 pinMode(LED_R, OUTPUT);

 Serial.println("Put card to the reader...");
 Serial.println();
 digitalWrite(LED_R, HIGH);
 digitalWrite(LED_G, LOW);
 digitalWrite(Lock, LOW);
}

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

 //Show UID on serial monitor
 Serial.print("UID 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.println();
 Serial.print("Message : ");
 content.toUpperCase();
 if (content.substring(1) == "E9 3B 3B D9") //change here the UID of the card/cards that you want to give access
 {
   Serial.println("Authorized access");
   Serial.println();
   if (digitalRead(LED_G) == LOW)
   {
     digitalWrite(Lock, HIGH);
     digitalWrite(LED_G, HIGH);
     digitalWrite(LED_R, LOW);
     delay(1000);
   }
   else
   {
     digitalWrite(Lock, LOW);
     digitalWrite(LED_G, LOW);
     digitalWrite(LED_R, HIGH);
     delay(500);
   }
 }
   else   {
   digitalWrite(LED_G, LOW);
   digitalWrite(Lock, LOW);
   Serial.println(" Access denied");
   delay(500);
   digitalWrite(LED_R, HIGH);
   delay(500);
   digitalWrite(LED_R, LOW);
   delay(500);
   digitalWrite(LED_R, HIGH);
   delay(500);
   digitalWrite(LED_R, LOW);
   delay(500);
   digitalWrite(LED_R, HIGH);
   delay(500);
   digitalWrite(LED_R, LOW);
   delay(500);
   digitalWrite(LED_R, HIGH);
   }
}

Michael30040:
is there any way I could program the code to not switch from locked to unlock if I hold the right card up to the scanner without removing it?

Have another go at explaining what you mean! :grinning:

Haha sorry, it's a little hard to explain. So once I hold up the card to the RFID scanner, it does what it's supposed to do and it unlocks...But, if I hold the card to the scanner for too long, it locks again and just continues to unlock and lock while the card is on the scanner. So I guess what I am asking is...is there any way to program it to not do this by somehow knowing if the card is on the scanner for more than one second and stopping the loop? That might have made no sense, sorry I'm trying my best to explain!

Yes, that is a problem of using delays and no "state change" verification. Once it passes through the delays, it takes another look at the card and acts accordingly.

So you clearly need to detect whether the card is not present before you go round in the loop again.

Actually, the loop needs to be properly designed, but that is another matter ...

1 Like