How to keep rfid reader triggered after one tap

hi guys, im very new to programming and was trying to make a door opening and closing system. However, I am trying to keep the rfid reader triggered after one tap of the card so that my other lines of code can run. But it seems like I have to tap the card several times to get through the code. can you please help me understand how I can fix this.

void loop() {
  
 //don't run the loop if card is not detected
    if (! rfid.PICC_IsNewCardPresent()) 
    return;
  
    //check if NUID has been detected
    if(! rfid.PICC_ReadCardSerial())
    return;
         /////// body of the RFID code ////////
    //Store userID in newID array
    for (byte i = 0; i < 4; i++)  {
      newID[i] = rfid.uid.uidByte[i];
    }
  
 //check if ID matches the database
 if (accessDoor(userID, newID) == true && servoState == 0)  {
    Serial.println ("Access Granted");
      servoState = 1;
      previousTime = millis();
    } servo();
    
   if (accessDoor(userID, newID) == false ) {
    Serial.println("Access Denied");
    

  }

  /////// to only print once //////////
  //Halt PICC
  rfid.PICC_HaltA();
  //Stop encryption on PCD
  rfid.PCD_StopCrypto1(); 

}

bool accessDoor (byte accessCode[], byte newCode[])  {
  for (byte i = 0; i< 4; i++)  {
    if (newCode[i] != accessCode[i])  {
      return false;
    }
  }
  return true; 
}
void flashing_green()  { 
  if (millis() - previousBlink >= flashTime) {
     if (greenFlash == 0) { // if light is off
        greenFlash = 255; // turn light on
     }else {
      greenFlash = 0; // or else turn off
    }
     lights (0, greenFlash);
     previousBlink = millis();
     //Serial.println("flashing green");
   }
   
}

void flashing_red()  {
  if (millis() - previousBlink >= flashTime) {
     if (redFlash == 0) { // if light is off
        redFlash = 255; // turn light on
     }else {
      redFlash = 0; // or else turn off
    }
     lights (redFlash, 0);
     previousBlink = millis();
     //Serial.println("flashing red");
   }
}

void lights(int red, int green)  {
  analogWrite (redRGB, red);
  analogWrite (greenRGB, green);
}

void servo()  {
 switch (servoState)  {
     case 0:
     {
      lights(255, 0);
      Serial.println("waiting for tag");
     break;
     }
     case 1:
     {
      flashing_green();
      Serial.println ("flashing green");
      if (millis() - previousTime >= servoDelay)  {
         pos += increment;
        myservo.write(pos);
        Serial.println(pos);
        //Serial.println ("case 1");
        previousTime = millis();
        if (pos > 80) {
          servoState = 2;
        }
       }
     break;
     }
     case 2:
     {
      lights(0, 255); // light is green to enter
        Serial.println ("green light on");
      if (millis() - previousTime >= interval) { //if 2secs have passed, go to state 3
       previousTime = millis();
       servoState = 3;
      }
     break;
     }
     case 3:
     {
        flashing_red();
        Serial.println("flashing red, closing");
      if (millis() - previousTime >= servoDelay)  {
         pos -= increment;
        myservo.write(pos);
        Serial.println(pos);
        previousTime = millis();
          if (pos == 0) {
            lights (0,0);
            Serial.println ("door closed");
          previousTime = millis(); 
          servoState = 0;
        }
       }
      break;
      }
     }
    }

Hi, @diya001
Welcome to the forum.

Thanks for using code tags on your code.
We need to see all of your code please.

Thanks.. Tom.. :smiley: :+1: :coffee: :australia:

1 Like

HI @diya001

welcome to the forum.
Very goo that you posted code as a code-section.
First of all: report your second post on the same issue to a moderator that he shall delete it.
It is against forum-rules to double-post / cross-post.

You are in danger of beeing temporarily banned from the forum if you cross-post.

Best thing to re-gain reputation in this forum is if you start saving time by investing time to the most important thing.

Please really invest 1 hour of time to save you a minimum of one week 7*24 = 168 hours of time by taking 0,5 hours of time to read

and then taking another 0,5 hours of time to add the requested details to your initial post

I can already see the point where to modify your code to make it work better. But the price for this that I post the suggestion is to expand your initial post.

best regards Stefan

1 Like

this is my full code :slight_smile: please ignore the lcd commands as Im still working on it.

#include <Servo.h> // including the servo library
#include <SPI.h>
#include <MFRC522.h>
#include <LiquidCrystal_I2C.h>

#define NSS_pin 10
#define RST_pin 6 //usually pin 9 but changed to pin 6
MFRC522 rfid(NSS_pin, RST_pin); //Instance of the class

// Create LCD object : Use 0x27 If 0x3F Doesn't work
LiquidCrystal_I2C lcd(0x3F, 16, 2);

byte newID [4];
byte userID[4] = {0xFC, 0x6D, 0x39, 0x4A};
int rfidState = 0;

int redRGB = 3; // pin for red rgb
int greenRGB = 5; //pin for green rgb
int redFlash = 0;
int greenFlash = 0;

 // INITIALISE SERVO PINS
Servo myservo; // create servo object to control a servo
int servoPin = 6; // pin for servo
int pos = 0; //position in degrees for servo
int increment = 10; //angle goes up or down by increment
int servoDelay = 20; // interval between every sweep
int servoState = 0; //state of servo

//millis time variables;
unsigned long previousBlink = 0; //time for flash
unsigned long previousTime = 0; // time for servo
int flashTime = 200; // flash for RGB 5Hz

const int interval = 2000; // wait time till door closes

void setup() {

  Serial.begin (9600);
  SPI.begin(); //initiate SPI bus
  rfid.PCD_Init(); //initiate the library MFRC522

  // Setup LCD with backlight and initialize
  lcd.init();
  lcd.backlight();
  printWelcomeMessage();

  myservo.attach(servoPin); // attaches the servo on pin 9 to the servo object
  myservo.write (pos); //changed 0 to pos
}

void loop() {
  
 //don't run the loop if card is not detected
    if (! rfid.PICC_IsNewCardPresent()) 
    return;
  
    //check if NUID has been detected
    if(! rfid.PICC_ReadCardSerial())
    return;
         /////// body of the RFID code ////////
    //Store userID in newID array
    for (byte i = 0; i < 4; i++)  {
      newID[i] = rfid.uid.uidByte[i];
    }
  
 //check if ID matches the database
 if (accessDoor(userID, newID) == true && servoState == 0)  {
    Serial.println ("Access Granted");
      servoState = 1;
      previousTime = millis();
    } servo();
    
   if (accessDoor(userID, newID) == false ) {
    Serial.println("Access Denied");
    

  }

  /////// to only print once //////////
  //Halt PICC
  rfid.PICC_HaltA();
  //Stop encryption on PCD
  rfid.PCD_StopCrypto1(); 

}

bool accessDoor (byte accessCode[], byte newCode[])  {
  for (byte i = 0; i< 4; i++)  {
    if (newCode[i] != accessCode[i])  {
      return false;
    }
  }
  return true; 
}
void flashing_green()  { 
  if (millis() - previousBlink >= flashTime) {
     if (greenFlash == 0) { // if light is off
        greenFlash = 255; // turn light on
     }else {
      greenFlash = 0; // or else turn off
    }
     lights (0, greenFlash);
     previousBlink = millis();
     //Serial.println("flashing green");
   }
   
}

void flashing_red()  {
  if (millis() - previousBlink >= flashTime) {
     if (redFlash == 0) { // if light is off
        redFlash = 255; // turn light on
     }else {
      redFlash = 0; // or else turn off
    }
     lights (redFlash, 0);
     previousBlink = millis();
     //Serial.println("flashing red");
   }
}

void lights(int red, int green)  {
  analogWrite (redRGB, red);
  analogWrite (greenRGB, green);
}

void servo()  {
 switch (servoState)  {
     case 0:
     {
      lights(255, 0);
      Serial.println("waiting for tag");
     break;
     }
     case 1:
     {
      flashing_green();
      Serial.println ("flashing green");
      if (millis() - previousTime >= servoDelay)  {
         pos += increment;
        myservo.write(pos);
        Serial.println(pos);
        //Serial.println ("case 1");
        previousTime = millis();
        if (pos > 80) {
          servoState = 2;
        }
       }
     break;
     }
     case 2:
     {
      lights(0, 255); // light is green to enter
        Serial.println ("green light on");
      if (millis() - previousTime >= interval) { //if 2secs have passed, go to state 3
       previousTime = millis();
       servoState = 3;
      }
     break;
     }
     case 3:
     {
        flashing_red();
        Serial.println("flashing red, closing");
      if (millis() - previousTime >= servoDelay)  {
         pos -= increment;
        myservo.write(pos);
        Serial.println(pos);
        previousTime = millis();
          if (pos == 0) {
            lights (0,0);
            Serial.println ("door closed");
          previousTime = millis(); 
          servoState = 0;
        }
       }
      break;
      }
     }
    }

thank you for this! im aware about my double post and will report it :slight_smile:

I know you have taken this part of the code from the demo-code of the RFID-library

Well it is a rather bad suited base for developping code.

I will teach you fishing to find out what is happening.

I'm using three macros that reduce the effort for adding debug-output to the code

these 3 macros are similar to each other but have functional variants

the macro "dbg" prints to the serial monitor on each and every call

the macro "dbgi" (do you see the "i" at the end ?) prints to the serial monitor only once every "x" milliseconds which can be specified in as the third parameter
print once every interval

so dbgi can be used at places where your code runs thriugh thousands of times per second but the printing happends only once every 500 milliseconds or once every 2 seconds or whatver interval you find useful

the macro "dbgc" (do you see the "c" at the end ?) prints to the serial monitor only once if integer variable specified has changed its value
print once on every change

These macros print the variable-name and the variable-value
The fixed text as the first parameter can be used to identify the exact position inside the code that has done the printing if you put a different fixed text into each call.

This helps a lot to see what is really going on in your code

This compiles but as I don't have your hardware you have to do the real test yourself

// MACRO-START * MACRO-START * MACRO-START * MACRO-START * MACRO-START * MACRO-START *

https://forum.arduino.cc/t/comfortable-serial-debug-output-short-to-write-fixed-text-name-and-content-of-any-variable-code-example/888298
#define dbg(myFixedText, variableName) \
  Serial.print( F(#myFixedText " "  #variableName"=") ); \
  Serial.println(variableName);
// usage: dbg("1:my fixed text",myVariable);
// myVariable can be any variable or expression that is defined in scope

#define dbgi(myFixedText, variableName,timeInterval) \
  do { \
    static unsigned long intervalStartTime; \
    if ( millis() - intervalStartTime >= timeInterval ){ \
      intervalStartTime = millis(); \
      Serial.print( F(#myFixedText " "  #variableName"=") ); \
      Serial.println(variableName); \
    } \
  } while (false);
// usage: dbgi("2:my fixed text",myVariable,1000);
// myVariable can be any variable or expression that is defined in scope
// third parameter is the time in milliseconds that must pass by until the next time a
// Serial.print is executed
// end of macros dbg and dbgi
// print only once when value has changed
#define dbgc(myFixedText, variableName) \
  do { \
    static long lastState; \
    if ( lastState != variableName ){ \
      Serial.print( F(#myFixedText " "  #variableName" changed from ") ); \
      Serial.print(lastState); \
      Serial.print( F(" to ") ); \
      Serial.println(variableName); \
      lastState = variableName; \
    } \
  } while (false);
// MACRO-END * MACRO-END * MACRO-END * MACRO-END * MACRO-END * MACRO-END * MACRO-END *

#include <Servo.h> // including the servo library
#include <SPI.h>
#include <MFRC522.h>
#include <LiquidCrystal_I2C.h>

#define NSS_pin 10
#define RST_pin 6 //usually pin 9 but changed to pin 6
MFRC522 rfid(NSS_pin, RST_pin); //Instance of the class

// Create LCD object : Use 0x27 If 0x3F Doesn't work
LiquidCrystal_I2C lcd(0x3F, 16, 2);

byte newID [4];
byte userID[4] = {0xFC, 0x6D, 0x39, 0x4A};
int rfidState = 0;

int redRGB = 3; // pin for red rgb
int greenRGB = 5; //pin for green rgb
int redFlash = 0;
int greenFlash = 0;

// INITIALISE SERVO PINS
Servo myservo; // create servo object to control a servo
int servoPin = 6; // pin for servo
int pos = 0; //position in degrees for servo
int increment = 10; //angle goes up or down by increment
int servoDelay = 20; // interval between every sweep
int servoState = 0; //state of servo

//millis time variables;
unsigned long previousBlink = 0; //time for flash
unsigned long previousTime = 0; // time for servo
int flashTime = 200; // flash for RGB 5Hz

const int interval = 2000; // wait time till door closes

void printWelcomeMessage() {
  dbg("print Welcome to the LCD",0);
}


void setup() {

  Serial.begin (9600);
  SPI.begin(); //initiate SPI bus
  rfid.PCD_Init(); //initiate the library MFRC522

  // Setup LCD with backlight and initialize
  lcd.init();
  lcd.backlight();
  printWelcomeMessage();

  myservo.attach(servoPin); // attaches the servo on pin 9 to the servo object
  myservo.write (pos); //changed 0 to pos
}

void loop() {
  dbgi("0: top of loop",0,2000);
  //don't run the loop if card is not detected
  if (! rfid.PICC_IsNewCardPresent())
    return;

  dbgi("1: card is present",1,2000);
  //check if NUID has been detected
  if (! rfid.PICC_ReadCardSerial())
    return;
    
  dbgi("2: rfid.PICC_ReadCardSerial() is true",2,2000);
  /////// body of the RFID code ////////
  //Store userID in newID array
  for (byte i = 0; i < 4; i++)  {
    newID[i] = rfid.uid.uidByte[i];
  }
  dbgi("3:newID assigned",newID[0],1000);
  //check if ID matches the database
  if (accessDoor(userID, newID) == true && servoState == 0)  {
    Serial.println ("Access Granted");
    servoState = 1;
    previousTime = millis();
  } 
  
  servo();

  if (accessDoor(userID, newID) == false ) {
    Serial.println("Access Denied");
  }

  /////// to only print once //////////
  //Halt PICC
  rfid.PICC_HaltA();
  //Stop encryption on PCD
  rfid.PCD_StopCrypto1();
}


bool accessDoor (byte accessCode[], byte newCode[])  {
  for (byte i = 0; i < 4; i++)  {
    if (newCode[i] != accessCode[i])  {
      return false;
    }
  }
  return true;
}

void flashing_green()  {
  dbgi("A: flashing green",greenFlash,500);
  
  if (millis() - previousBlink >= flashTime) {
    if (greenFlash == 0) { // if light is off
      greenFlash = 255; // turn light on
    }
    else {
      greenFlash = 0; // or else turn off
    }
    lights (0, greenFlash);
    previousBlink = millis();
    //Serial.println("flashing green");
  }
}

void flashing_red()  {
  dbgi("B: flashing red",redFlash,500);
  if (millis() - previousBlink >= flashTime) {
    if (redFlash == 0) { // if light is off
      redFlash = 255; // turn light on
    }
    else {
      redFlash = 0; // or else turn off
    }
    lights (redFlash, 0);
    previousBlink = millis();
    //Serial.println("flashing red");
  }
}


void lights(int red, int green)  {
  analogWrite (redRGB, red);
  analogWrite (greenRGB, green);
}

void servo()  {

  dbgc("S:",servoState);
  
  switch (servoState)  {
    case 0:
      lights(255, 0);
      Serial.println("waiting for tag");
      break;

    case 1:
      flashing_green();
      //Serial.println ("flashing green");
      if (millis() - previousTime >= servoDelay)  {
        pos += increment;
        myservo.write(pos);
        Serial.println(pos);
        //Serial.println ("case 1");
        previousTime = millis();
        if (pos > 80) {
          servoState = 2;
        }
      }
      break;

    case 2:
      lights(0, 255); // light is green to enter
      //Serial.println ("green light on");
      dbgi("G:green light on",0,500);
      if (millis() - previousTime >= interval) { //if 2secs have passed, go to state 3
        previousTime = millis();
        servoState = 3;
      }
      break;

    case 3:
      flashing_red();
      //Serial.println("flashing red, closing");
      dbgi("flashing red, closing",pos,500);
      
      if (millis() - previousTime >= servoDelay)  {
        pos -= increment;
        myservo.write(pos);
        Serial.println(pos);
        previousTime = millis();
        if (pos == 0) {
          lights (0, 0);
          Serial.println ("door closed");
          previousTime = millis();
          servoState = 0;
        }
      }
      break;
  }
}

best regards Stefan

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.