1

I'm making a little parking lot, which includes mostly opening a servo motor using either keypad, Bluetooth (hc-05) and freshly added, RFID (RC522).

I can't get inputs from other sources if I want to get the UID from the RFID meaning when I added the only piece of code that I found that returns the UID it seems to block all the void loop() hence all the other inputs/code don't work. Here's the full code:

#include <LiquidCrystal.h>  //Lcd functions library
#include <Servo.h>          //Servo Motor
#include <SoftwareSerial.h>//Bluetooth functions library:HC05 IS SUPERIOR!
#include "TM1637.h"        //4 digit display functions library
#include <SPI.h>
#include <MFRC522.h>
//Credit to Baroryan

//copyright (c)*/
const int rs = 38, en = 39, d4 = 36 ,d5 = 37, d6 = 41, d7 = 40;//Defining LCD PINS
const int DA=31, D0=30,D1=33,D2=32,D3=35;//Defining KEYPAD data PINS
const int servoPin=43,buzzer=42,rx=53,tx=52;//Defining(By order): servo pin, buzzer pin, 4DD pins, and bluetooth pins(rx tx)
//buzzer pin is 36!
//,CLK=34,DIO=35

#define SS_PIN 45
#define RST_PIN 44
int count = 0;
int cnt=0;//this cnt is used later on to make sure all 5 chars are equal.
int cnt2=0;//used for switch case to count how many chars were already received
int cnt3=0;
char c=0;//this is where we place the char received from the user

char password[5] = {'8', '5', '2', '0', '#'};
char keysPressed[5] = "";
char keys[5]="";

byte customChar2[] = {
  B00000,
  B00000,
  B01010,
  B00000,
  B10001,
  B01110,
  B00000,
  B00000
};


byte customChar[] = {//Custom Char for lcd screen, in this case; a heart.  
  0x00,
  0x00,
  0x0A,
  0x1F,
  0x1F,
  0x0E,
  0x04,
  0x00
};
//  #define DA 25 Used to define Keypad pins and other misc using #Define which talks to the processor->
//  #define D0 24  ->decided to use const int instead.
//  #define D1 27
//  #define D2 26
//  #define D3 29
//  #define servoPin 37
//  #define buzzer 36
//  #define CLK 34 
//  #define DIO 35
void lcdSetup();
void gateOpenSequence();
void returnKey(int key);
void wrongPassword();
void Beep();
SoftwareSerial Bluetooth(rx,tx);//intialize bluetooth to pins
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);//intialize LCD to pins
MFRC522 mfrc522(SS_PIN, RST_PIN);   // Create MFRC522 instance.
Servo servo;//intialize servo
byte nuidPICC[4];


void printHex(byte *buffer, byte bufferSize) {
  for (byte i = 0; i < bufferSize; i++) {
    Serial.print(buffer[i] < 0x10 ? " 0" : " ");
    Serial.print(buffer[i], HEX);
  }
}

void setup()
{
  Serial.begin(9600);
  Bluetooth.begin(9600);
  SPI.begin();      // Initiate  SPI bus
  pinMode(DA ,INPUT);
  pinMode(D0 ,INPUT);
  pinMode(D1 ,INPUT);
  pinMode(D2,INPUT);
  pinMode(D3,INPUT);
  mfrc522.PCD_Init();   // Initiate MFRC522
  lcd.begin(20,4);
  lcdSetup();//Self Created function that turns lcd to our preffered default screen "Home screen"
  servo.attach(servoPin);
  servo.write(5);
  pinMode(buzzer,OUTPUT);
  digitalWrite(buzzer, HIGH); 
  delay(200);          
  digitalWrite(buzzer, LOW);
  Bluetooth.print("Enter 1 to open the gate!");//Write to user bluetooth terminal instructions
  lcd.createChar(2, customChar2);
  lcd.createChar(1, customChar);
}

void loop()
{


  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) == "17 27 C7 A6" || "BA FA 21 28") //change here the UID of the card/cards that you want to give access
  {
    Serial.println("Authorized access");
    Serial.println();
    delay(3000);
  }
 
 else   {
    Serial.println(" Access denied");
    delay(3000);
  }
  
  char Data=Bluetooth.read();//Recieves Data from bluetooth and places it in variable 'Data'
  if(Data=='1'){//if data from bluetooth equals to 1(1 recieved from bluetooth IS NOT an integer, it is a char.)
    gateOpenSequence();//Self created function that executes all actions when Gate need to be opened.
  }
  while(digitalRead(DA)==1){         //While recieving characters from keypad.
    int key =digitalRead(D3)*8 + digitalRead(D2)*4 +digitalRead(D1)*2 + digitalRead(D0);//Certain formula used to decipher what key has been pressed
    returnKey(key);//Self created function that translates key deciphered to keypad layout. puts key pressed into variable 'c'
    Serial.print(c);
    if(c!='D') keys[cnt3]=c;
      
    switch(cnt2){
      case 0:
        if(c!='D'){
          lcd.clear();
          lcd.setCursor(9, 0);
          lcd.print(keys[cnt3]);
          ++cnt3;
          ++cnt2;
          Beep();
          break;
        }
        else break;
      case 1:
        if(c!='D'){
          lcd.setCursor(8,0);
          lcd.print("*");
          lcd.print(keys[cnt3]);
          ++cnt3;
          ++cnt2;
          Beep();
          break;
        }
        else{
          lcd.clear();
          --cnt3;
          --cnt2;
          break;
        }

      case 2:
        if(c!='D'){
          lcd.setCursor(8, 0);
          lcd.print("**");
          lcd.print(keys[cnt3]);
          ++cnt2;
          ++cnt3;
          Beep();
          break;
        }
        else{
          lcd.clear();
          lcd.setCursor(9,0);
          cnt3--;
          cnt2--;
          lcd.print(keys[cnt3-1]);
          
          
          break;
        }

      case 3:
        if(c!='D'){
          lcd.setCursor(8, 0);
          lcd.print("***");
          lcd.print(keys[cnt3]);
          ++cnt2;
          ++cnt3;
          Beep();
          break;
        }
        else{
          lcd.clear();
          lcd.setCursor(9,0);
          lcd.print("*");
          cnt3--;
          cnt2--;
          lcd.print(keys[cnt3-1]);
          break;
        }
      case 4:
        if(c!='D'){
          cnt2=0;
          cnt3=0;
        }
        else{
          lcd.clear();
          lcd.setCursor(9, 0);
          lcd.print("**");
          cnt2--;
          cnt3--;
          lcd.print(keys[cnt3-1]); 
        }
      break;
    }
    while(digitalRead(DA)==1);//Making sure we wont get double input from one press, forcing the loop to stay there as long as a key is pressed
    if(c!='D'){
      keysPressed[count] = c;//Placing key pressed into an array
      count++;//raising array index
    }
    else{
      keysPressed[count]="";
      count--;      
     }
    if (count == 5)//when count reaches 5, meaning array is full check if array 'password' is equal to the 5 keys the user just entered.
    {
      for (int i = 0; i < 5; i++)
      {
        if (password[i] == keysPressed[i])//if keys are the same add one to cnt, if cnt equals to 5, it means all keys were the same
        {
          cnt++;
        }
      }
        if(cnt==5){
          gateOpenSequence();
          cnt=0;
        }
        else{
          wrongPassword();
          cnt=0;
        }
        }
      }
  }


void returnKey(int key)
{ 
  char arrkey[16]={ '1','2','3','A','4','5','6','B','7','8','9','C','*','0','#','D' };
  c=arrkey[key];
  
}

void lcdSetup(){
  lcd.setCursor(0,0);
  lcd.write(2);
  lcd.setCursor(1, 0);
  lcd.write(1);
  lcd.setCursor(18,0);
  lcd.write(1);
  lcd.setCursor(19,0);
  lcd.write(2);
  lcd.setCursor(2,0);
  lcd.print("----Welcome-----");
  lcd.setCursor(0,1);
  lcd.print("|  Enter password  |");
  lcd.setCursor(0,2);
  lcd.print("|and then press '#'|");
  lcd.setCursor(0, 3);
  lcd.print("|------------------|");
}
void gateOpenSequence(){
  int start = 0;
  int desired = 105;
  lcd.clear();
  lcd.setCursor(6,0);
  lcd.print("Welcome");
  lcd.setCursor(8,1);
  lcd.print("Home");
  count = 0;
  digitalWrite(buzzer,HIGH);
  while(start<desired){
  servo.write(++start);
  delay(10);
  }
  delay(1000);
  digitalWrite(buzzer,LOW);
  lcdSetup();
  while(start>5){
  servo.write(--start);
  delay(10);
  }


}
void wrongPassword(){
  lcd.clear();
  lcd.setCursor(7,0);
  lcd.print("Wrong");
  lcd.setCursor(6,1);
  lcd.print("Password");
  lcd.setCursor(4, 2);
  lcd.print("Achalta ota");
  count = 0;
  for(int jj=0;jj<3;jj++){
    Beep();
  }
  delay(2000);
  lcdSetup();

}

void Beep(){
  digitalWrite(buzzer,HIGH);
  delay(200);
  digitalWrite(buzzer,LOW);
  delay(200);
}

I will really appreciate help as I can't seem to find any explanations about these two functions:

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

1 Answer 1

0
mfrc522.PICC_IsNewCardPresent()

will check, if a new RFID card/tag was presented to the reader. So if this returns true, you can read the card.

mfrc522.PICC_ReadCardSerial()

will actually read the data from the card/tag, so that the UUID is then available via mfrc522.uid.


Your problem stems from how you are using these functions. Lets have a look at that exact code snippet:

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

When we translate the first if statement into english we get:

 If no new card is present restart the function `loop()`.

This code snippet is at the start of the function. This means, that you will only read the code below that, if a new card is present and could be read. This logic only works good, if the RFID code is the only thing done in that function, which is not the case for you.

Instead you can restructure your RFID code a bit:

if(mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()){
    // Handling all RFID code in here
    //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) == "17 27 C7 A6" || "BA FA 21 28") //change here the UID of the card/cards that you want to give access
    {
        Serial.println("Authorized access");
        Serial.println();
        delay(3000);
    } else {
        Serial.println(" Access denied");
        delay(3000);
    }
}

This will execute the RFID code, if a new card could be read. Otherwise it will just continue with the rest of the code.

Note, that due to the delay(3000) call your code won't react to anything for 3 seconds after a card was presented to the reader. You might wanna ditch that delay in favor of a better responsiveness.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.