RFID reader stops working as soon as relay is engaged

Hi!

I'm working on an electromagnetic door lock project. I have an Arduino Uno hooked up to an RC522 RFID module and an SRD-05VDC-SL-C 5V relay, which controls a 12V electromagnetic lock. As of now, my power source is a 4.8V battery, but it doesn't seem to be affecting the lock's performance.

My problem is that as soon as I scan the RFID tag that is authorized and the relay gets engaged and the electromagnetic lock is "unlocked", I can no longer scan the tag again. The RFID reader stops reading and I have to reset the Arduino for it to work again. I've tested my circuit extensively and found that I can scan, add and remove as many tags as I want before unlocking the lock, but as soon as that happens, the reader stops working. I am not sure if this is a software problem or a hardware problem. My design is based on this project, but I have modified many things.

Here is the void loop() of my code, as that is the part that handles the reading and unlocking. Please let me know if the full code is required (it is quite long).

void loop () {
  do {
    successRead = getID();  // sets successRead to 1 when we get read from reader otherwise 0
    // When device is in use if wipe button pressed for 10 seconds initialize Master Card wiping
    if (digitalRead(wipeB) == LOW) { // Check if button is pressed
      // Visualize normal operation is iterrupted by pressing wipe button Red is like more Warning to user
      digitalWrite(redLed, LED_ON);  // Make sure led is off
      digitalWrite(greenLed, LED_OFF);  // Make sure led is off
      digitalWrite(blueLed, LED_OFF); // Make sure led is off
      // Give some feedback
      Serial.println(F("Wipe Button Pressed"));
      Serial.println(F("Master Card will be Erased! in 10 seconds"));
      bool buttonState = monitorWipeButton(10000); // Give user enough time to cancel operation
      if (buttonState == true && digitalRead(wipeB) == LOW) {    // If button still be pressed, wipe EEPROM
        EEPROM.write(1, 0);                  // Reset Magic Number.
        Serial.println(F("Master Card Erased from device"));
        Serial.println(F("Please reset to re-program Master Card"));
        while (1);
      }
      Serial.println(F("Master Card Erase Cancelled"));
    }
    if (programMode) {
      cycleLeds();              // Program Mode cycles through Red Green Blue waiting to read a new card
    }
    else {
      normalModeOn();     // Normal mode, blue Power LED is on, all others are off
    }
  }
  while (!successRead);   //the program will not go further while you are not getting a successful read
  
  if (programMode) {
    if ( isMaster(readCard) ) { //When in program mode check First If master card scanned again to exit program mode
      Serial.println(F("Master Card Scanned"));
      Serial.println(F("Exiting Program Mode"));
      Serial.println(F("-----------------------------"));
      programMode = false;
      return;
    }
    else {
      if ( findID(readCard) ) { // If scanned card is known delete it
        Serial.println(F("I know this PICC, removing..."));
        deleteID(readCard);
        Serial.println("-----------------------------");
        Serial.println(F("Scan a PICC to ADD or REMOVE to EEPROM"));
      }
      else {
        Serial.println(F("I do not know this PICC, adding..."));
        writeID(readCard);
        Serial.println(F("-----------------------------"));
        Serial.println(F("Scan a PICC to ADD or REMOVE to EEPROM"));
      }
    }
  }
  else {
    if ( isMaster(readCard)) {    // If scanned card's ID matches Master Card's ID - enter program mode
      programMode = true;

      Serial.println(F("Hello Master - Entered Program Mode"));
      uint8_t count = EEPROM.read(0);   // Read the first Byte of EEPROM that
      Serial.print(F("I have "));     // stores the number of ID's in EEPROM
      Serial.print(count);
      Serial.print(F(" record(s) on EEPROM"));
      Serial.println("");
      Serial.println(F("Scan a PICC to ADD or REMOVE to EEPROM"));
      Serial.println(F("Scan Master Card again to Exit Program Mode"));
      Serial.println(F("-----------------------------"));
    }
    else {
      if ( findID(readCard) ) { // If not, see if the card is in the EEPROM
        Serial.println(F("Welcome, You shall pass"));
        granted(3000);         // Open the door lock for 300 ms
      }
      else {      // If not, show that the ID was not valid
        Serial.println(F("You shall not pass"));
        denied();
      }
    }
  }
}

Thanks in advance for any help!

Karma for using code tags on first post but supply the entire code! Also produce a wiring diagram.

Railroader:
Karma for using code tags on first post but supply the entire code! Also produce a wiring diagram.

Attached is the entire code (it was too long to put between code tags). Where would I be able to make a wiring diagram?

AccessControl.ino (23.8 KB)

Like this, as a file. That's the only way when code is larger than 9000 characters.
Here the sun is soon raising and I'm down for sleeping, using the phone so my reply will come some 12 hours later.

  if ( ! rfid.PICC_IsNewCardPresent()) {
    return;
  }

Is only true for a NEW card. Does the reader read a different card? In other words, try card A then card B then card A again.

SteveMann:

  if ( ! rfid.PICC_IsNewCardPresent()) {

return;
  }



Is only true for a NEW card. Does the reader read a different card? In other words, try card A then card B then card A again.

Hmm, that might be the problem. Will try it out!

SteveMann:
Is only true for a NEW card. Does the reader read a different card? In other words, try card A then card B then card A again.

I tried Card A then Card B then Card A again, but it didn’t work. I even tried a new, unregistered Card C, but there was still no response from the reader.

Attached is the schematic I am following for my circuit (schematic was not made by me). The only change is that I have a 220µF capacitor across Power and Ground to eliminate any noise.

  if (programMode) {
    if ( isMaster(readCard) ) { //When in program mode check First If master card scanned again to exit program mode
      Serial.println(F("Master Card Scanned"));
      Serial.println(F("Exiting Program Mode"));
      Serial.println(F("-----------------------------"));
      programMode = false;
      return;
    }

This section ends with a return. What are you returning to?

I got it working! I switched the relay from an NO to an NC circuit and electrically isolated the power supply for the electromagnet, as well as cleaned up the code a little bit. It seems to be working perfectly now. Big thanks to everyone that helped me out, I appreciate it!

Greate! Thanks for telling us!

ozayr:
Attached is the schematic I am following for my circuit (schematic was not made by me).

For future reference. A pretty Fritzing picture IS NOT A SCHEMATIC. It is a pretty picture, but useless for engineering purposes.

SteveMann:
For future reference. A pretty Fritzing picture IS NOT A SCHEMATIC. It is a pretty picture, but useless for engineering purposes.

Thanks for letting me know! I don't know how to make a good schematic on the computer, so I thought I would just include the picture that was provided with the project that I based my project on. My apologies.

I don't know how to make a good schematic on the computer,

You fold the laptop flat. Take a piece of paper and place it on the laptop and then draw your schematic using a pencil. Photograph the result and then post the picture.

You could also have solved your problem by proper power supply decoupling instead of a separate supply.