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
}}
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
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);
// 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.
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
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
}}
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.
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.
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.
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.
#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?
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.