Arduino bluetooth +rfid

Hi,

I am working on an electronic door lock for my room.
I use a servo to lock/unlock the door. I can do that either via bluetooth with my smartphone or via an rfid reader (MFRC522). I got it to work via both methods, but seperately.
When I try to merge the code together from the bluetooth and the rfid, there is a problem.

The problem is that if I scan the tag, the servo locks or unlocks, but via bluetooth it seems to do nothing.
Important here is the word seems, because the arduino definately receives data from my smartphone via the bluetooth module, but it doesn't get the chance to do anything, because the command from the rfid gets "privilege".

Here is my code:

#include <SPI.h>
#include <SoftwareSerial.h>
#include <MFRC522.h>
#include <Servo.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;
String ok_rfid_1="909987ab"; //add as many as you need.
String ok_rfid_2="85aaba5";
String ok_rfid_3="13d4b228";
String ok_rfid_4="9ab7b97f";
String ok_rfid_5="33578aa7";
String ok_rfid_6="b2bc71d";


Servo myservo;  // create servo object to control a servo 
int posClosed = 0;    // variable to store the servo position for locked
int posOpen = 360;    //same for open...
int bluetoothTx = 0; // bluetooth tx to 10 pin
int bluetoothRx = 1; // bluetooth rx to 11 pin
SoftwareSerial bluetooth(bluetoothTx, bluetoothRx);

/*
 * Initialize.
 */
void setup() {
    Serial.begin(9600);         // Initialize serial communications with the PC
  bluetooth.begin(9600);
    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

    myservo.attach(3);  // attaches the servo on pin 3 to the servo object 
}

/*
 * 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 open_lock() {
 
  
  //Use this routine when working with Servos.
 myservo.write(90); 
 delay(2000);
myservo.write(0);
}

void loop() {

   
      // 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) {

  open_lock();
   }
 
    if (read_rfid==ok_rfid_2) {
 

    open_lock();   
}
 if (read_rfid==ok_rfid_3) {

    open_lock();
    }
     if (read_rfid==ok_rfid_4) {
  
     open_lock();
    }
 if (read_rfid==ok_rfid_5) {
  
     open_lock();
    }
     if (read_rfid==ok_rfid_6) {

     open_lock();
    }
     //Read from bluetooth and write to usb serial
 if(bluetooth.available()> 0 ) // receive number from bluetooth
 {
  int servopos = bluetooth.read(); // save the received number to servopos
  Serial.println(servopos); // serial print servopos current number received from bluetooth
  myservo.write(servopos); // roate the servo the angle received from the android app
   
  }}

How would you bypass this problem?

Why do you create a software serial object on top of the real hardware Serial? Things like your 2 begin will clash or Serial.println(read_rfid); sends data to your Bluetooth

Why do you use the String class?

if ( ! mfrc522.PICC_IsNewCardPresent()) return;
if ( ! mfrc522.PICC_ReadCardSerial()) return;

Why do you return? Then you have no chance to read your Bluetooth if the card is not there use a else statement to do something else

Sorry, but I see you're using an RFID, if you are experienced with the RFID, could you check out this thread please: How to clone cards using RFID? - Programming Questions - Arduino Forum I really need help :D.

J-M-L:
Why do you create a software serial object on top of the real hardware Serial? Things like your 2 begin will clash or Serial.println(read_rfid); sends data to your Bluetooth

Why do you use the String class?

if ( ! mfrc522.PICC_IsNewCardPresent()) return;

if ( ! mfrc522.PICC_ReadCardSerial()) return;



Why do you return? Then you have no chance to read your Bluetooth if the card is not there use a else statement to do something else

I just used the available libraries for the rfid and bluetooth modules.
I have some basic knowledge of programming, but not that extensive to see what is wrong with the code right now.

@akatchi, I took a look at your thread, but unfortunately I can't help you.

It's not a library Issue, it's your logical flaw that has an issue. You do a test and return if the badge is not good. So there is no chance to go do anything else if the badge is not there

Also look at this - the comment do not match the pins and 0,1 are the hardware pins used by Serial and connected to the USB

int bluetoothTx = 0; // bluetooth tx to 10 pin
int bluetoothRx = 1; // bluetooth rx to 11 pin
SoftwareSerial bluetooth(bluetoothTx, bluetoothRx);

I tried this but wihtout success:

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

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

//Read from bluetooth and write to usb serial
 if(bluetooth.available()> 0 ) // receive number from bluetooth
 {
  int servopos = bluetooth.read(); // save the received number to servopos
  Serial.println(servopos); // serial print servopos current number received from bluetooth
  myservo.write(servopos); // roate the servo the angle received from the android app

So I removed the returns so the bluetooth has a chance to do something if there is no card to read for the rfid.
But now the rfid card doesn't read anything.

Regarding the bluetooth pins: the comments in the code is wrong indeed. I hooked up the Tx of the bluetooth module to the Rx pin of the arduino and the Rx pin of the module to the Tx pin of the arduino.

well you need to go read a bit about programming and conditional execution

if (condition) {ifCode} else {elseCode}

to try to understand what you wrote means for your code flow.

Regarding the Rx and Tx the pb is you can't have both those pins connected to the module AND to the USB. Pick other pins and do use indeed SoftwareSerial

So how about this:

void loop() {


      // Look for new cards

      
    if ( ! mfrc522.PICC_IsNewCardPresent()){
            //Read from bluetooth and write to usb serial
 if(bluetooth.available()> 0 ) // receive number from bluetooth
 {
  int servopos = bluetooth.read(); // save the received number to servopos
  Serial.println(servopos); // serial print servopos current number received from bluetooth
  myservo.write(servopos); // roate the servo the angle received from the android app
   
  }}

    // 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)||(read_rfid==ok_rfid_2)||(read_rfid==ok_rfid_3)||(read_rfid==ok_rfid_4)||(read_rfid==ok_rfid_5)||(read_rfid==ok_rfid_6))  {
   
    
  open_lock();
        }}

or this:

// Look for new cards
bool flag = false;
 if (mfrc522.PICC_IsNewCardPresent())
{
						

// Select one of the cards
if (mfrc522.PICC_ReadCardSerial())
{

    dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size);
    Serial.println(read_rfid);
    
    if ((read_rfid==ok_rfid_1)||(read_rfid==ok_rfid_2)||(read_rfid==ok_rfid_3)||(read_rfid==ok_rfid_4)||(read_rfid==ok_rfid_5)||(read_rfid==ok_rfid_6))  {
    flag=true;

}

if (!flag)

     //Read from bluetooth and write to usb serial
 if(bluetooth.available()> 0 ) // receive number from bluetooth
 {
  int servopos = bluetooth.read(); // save the received number to servopos
  Serial.println(servopos); // serial print servopos current number received from bluetooth
  myservo.write(servopos); // roate the servo the angle received from the android app
   
  }}

Anyone?

I really would appreciate it if someone would look at this.

I have been trying alot and still nothing. I really don't expect people to solve it for me, but I a little help is appreciated.
I tried the tips J-M-L gave me and used else function, but still nothing.

Post your new code taking into account the feedback

Ok so I removed the softwareserial and I am using the hardwareserial.

I also removed the returns, like you said, if the returns are there, then the bluetooth doesn't get a chance to do its thing, i.e. rotating the servomotor.

So now I added an else function that reads the bluetooth information if there is no RFID tag.

This is the code

#include <SPI.h>

#include <MFRC522.h>
#include <Servo.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;
String ok_rfid_1="909987ab"; //add as many as you need.
String ok_rfid_2="85aaba5";
String ok_rfid_3="13d4b228";
String ok_rfid_4="9ab7b97f";
String ok_rfid_5="33578aa7";
String ok_rfid_6="b2bc71d";

const int servoPin = 3;
int pos = 0;    // variable to store the servo position 

Servo myservo;  // create servo object to control a servo 
int posClosed = 0;    // variable to store the servo position for locked
int posOpen = 360;    //same for open...


/*
 * Initialize.
 */
void setup() 
{
    Serial.begin(9600);         // Initialize serial communications with the PC
    Serial.print("Arduino control Servo Motor Connected OK");
     Serial.print("\n");
  
    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

    myservo.attach(3);  // attaches the servo on pin 3 to the servo object 
}

/*
 * 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 open_lock() 
{
  
  //Use this routine when working with Servos.
  myservo.write(90); 
  delay(2000);
  myservo.write(0);
}

void loop() 
{

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

      // Select one of the cards
       if ( ! mfrc522.PICC_ReadCardSerial())
       {
        dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size);
        Serial.println(read_rfid);
        }

          if ((read_rfid==ok_rfid_1)||(read_rfid==ok_rfid_2)||(read_rfid==ok_rfid_3)||(read_rfid==ok_rfid_4)||(read_rfid==ok_rfid_5)||(read_rfid==ok_rfid_6)) 
          {
            open_lock();
          }
    }
    
    else
    {
      // if there's any serial available, read it:
      if (Serial.available() > 0) 
      {
   
        // look for the next valid integer in the incoming serial stream: 
    
        pos = Serial.parseInt(); 
       }
   
          // look for the newline. That's the end of your  sentence:
         if (Serial.read() == '\n') 
        {
               
           myservo.write(pos);              // tell servo to go to position in variable 'pos' 
           delay(15);                       // waits 15ms for the servo to reach the position
        }
    }
}
String ok_rfid_1="909987ab"; //add as many as you need.
String ok_rfid_2="85aaba5";
String ok_rfid_3="13d4b228";
String ok_rfid_4="9ab7b97f";
String ok_rfid_5="33578aa7";
String ok_rfid_6="b2bc71d";

In the comment, you misspelled "piss away as many resources as you like". When you properly phrase the comment, you can see that THAT is NOT the case. There is NO reason to use a String to wrap a string. Learn to embrace strings.

      // Look for new cards
    if ( ! mfrc522.PICC_IsNewCardPresent())
    {
      // Select one of the cards
       if ( ! mfrc522.PICC_ReadCardSerial())
       {
        dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size);

If there is NOT a new card present, and you can NOT read the data, dump the data.

Does that make sense to you?

Hi Paul, thanks for answering:

The first part of your comment I dont really understand, can you please explain what is wrong. And what I should use if I shouldn't use sstring?

And the second part of your comment was exactly what I was thinking. I have limited programming knowledge, but I mostly understand the reasoning behind it, if I understand what the functions do.
The code you see here is not written by me, but I found this on several other similar projects on the internet.
It was really bugging me why they would use the NOT and then dump data.
And what amazes me even more that the code seperate for the rfid works: if the right tag is present it rotates the servo to the desired position.

This is the code for the rfid only and no bluetooth:

#include <SPI.h>

#include <MFRC522.h>
#include <Servo.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;
String ok_rfid_1="909987ab"; //add as many as you need.
String ok_rfid_2="85aaba5";
String ok_rfid_3="13d4b228";
String ok_rfid_4="9ab7b97f";
String ok_rfid_5="33578aa7";
String ok_rfid_6="b2bc71d";


Servo myservo;  // create servo object to control a servo 
int posClosed = 0;    // variable to store the servo position for locked
int posOpen = 360;    //same for open...


/*
 * 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

    myservo.attach(3);  // attaches the servo on pin 3 to the servo object 
}

/*
 * 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 open_lock() {
 
  
  //Use this routine when working with Servos.
 myservo.write(90); 
 delay(2000);
myservo.write(0);
}

void loop() {

   
      // 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)||(read_rfid==ok_rfid_2)||(read_rfid==ok_rfid_3)||(read_rfid==ok_rfid_4)||(read_rfid==ok_rfid_5)||(read_rfid==ok_rfid_6))  {
    open_lock();
  
  }}
Shouldn't the code be like this:

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

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

    dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size);
    Serial.println(read_rfid);

The second return is removed and the NOT also.

EDIT:

I just tried out the adjusted code for the rfid (the second return removed and the NOT also)
and now the servomotor does not rotate.
If I upload the first code posted above, it does work, the servomotor rotates. I really do not understand why.

Shouldn't the code be like this

No. The code originally did a return if there was ! (NOT) a card present. Since you want to do something if a card is present, you need to lose the ! operator.

   if(mfrc522.PICC_IsNewCardPresent())
   {
       if(mfrc522.PICC_ReadCardSerial())
       {
          // Use the data
       }
   }

As for the first comment, you SHOULD use strings. You should NOT use Strings.

Strings and strings are NOT the same thing.

If I use string ok_rfid_1 = "909987ab";

i get an error while compiling:

'string' does not name a type

Ok guys, I kinda got it working now with this:

#include <SPI.h>
#include <MFRC522.h>
#include <Servo.h> 
#define RST_PIN         9           // Configurable, see typical pin layout above
#define SS_PIN          10          // Configurable, see typical pin layout above
const int servoPin = 3;
int pos = 0;    // variable to store the servo position 
Servo myservo;  // create servo object to control a servo 
int posClosed = 0;    // variable to store the servo position for locked
int posOpen = 360;    //same for open...
MFRC522 mfrc522(SS_PIN, RST_PIN);   // Create MFRC522 instance.

String read_rfid;
String ok_rfid_1="909987ab"; //add as many as you need.
String ok_rfid_2="85aaba5";
String ok_rfid_3="13d4b228";
String ok_rfid_4="9ab7b97f";
String ok_rfid_5="33578aa7";
String ok_rfid_6="b2bc71d";

void setup() 
{
    Serial.begin(9600);         // Initialize serial communications with the PC
    Serial.print("Arduino control Servo Motor Connected OK");
    Serial.print("\n");
    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
    myservo.attach(3);  // attaches the servo on pin 3 to the servo object 
}

/*
 * 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 open_lock() 
{
  //Use this routine when working with Servos.
  myservo.write(0); 
  delay(2000);
}

void loop() 
{
    // Look for new cards
    if (mfrc522.PICC_IsNewCardPresent())
    {
    // Select one of the cards
    if (mfrc522.PICC_ReadCardSerial())
     {   
    dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size);
    Serial.println(read_rfid);
    }
    if ((read_rfid==ok_rfid_1)||(read_rfid==ok_rfid_2)||(read_rfid==ok_rfid_3)||      (read_rfid==ok_rfid_4)||(read_rfid==ok_rfid_5)||(read_rfid==ok_rfid_6))  
    {
    open_lock();
    }
    } 
      else
    {
      if (!mfrc522.PICC_IsNewCardPresent())
      // if there's any serial available, read it:
      if (Serial.available() > 0) 
      {
        // look for the next valid integer in the incoming serial stream: 
        pos = Serial.parseInt(); 
       }
          // look for the newline. That's the end of your  sentence:
         if (Serial.read() == '\n') 
        { 
           myservo.write(pos);              // tell servo to go to position in variable 'pos' 
           delay(15);                       // waits 15ms for the servo to reach the position
        }
    }
}

With this, both of the codes do work: i can use either bluetooth or rfid to rotate the servomotor.

I still have a few questions though:
After the code for the rfid in the void loop, I use an else. And in that "else" I use an "if" to check if there is an rfid tag or not. If not, then it reads data from the bluetooth.
Could I also use an "else if (!mfrc522.PICC_IsNewCardPresent())" instead of just "else"?

Also, now the "else" is outside the brace of :
" // Look for new cards
if (mfrc522.PICC_IsNewCardPresent())
{
"
Could I also put the else inside the brace of the first "if" or not?

I give up on trying to read your

code. There is useless amounts

of white space, except where it counts,

where there is none.

You just don't seem to understand the importance of proper indenting.

I edited it. Hope it's better now?

BTW Paul, do you usually read the code directly via your webbrowser or you first paste it into the arduino IDE and then read it?
I usually copy and paste it in the arduino IDE, that way it is easier for me reading the code.
Especially for longer codes.

BTW Paul, do you usually read the code directly via your webbrowser

I read it in the browser. Starting an external editor should not be necessary.

I edited it. Hope it's better now?

Could be. I'm not going back and reading something you edited in a post that I replied to, making my comments look stupid.