ID20 on SoftwareSerial and Hall effect Sensor on Serial

Hi all,

I’m doing my first project on arduino and been having fun with it. I’m doing a key management system. The idea is a user would scan his/her RFID card to open the key cabinet. The user then would be able to pick a key and will automatically sign out the key under the user’s name. I’m using hall effect to check whether a key is in or not. Everything seems to be working in pieces until I put them all together. The rfid system works fine but the hall effect sensor is not working at all. I have a feeling that it’s something with SoftwareSerial but not sure. The code is attached below.

Thanks in advance!!!

#include <SoftwareSerial.h>
#include <Wire.h>

#define LOCKED 1
#define UNLOCKED 0

SoftwareSerial id20(3,2); // virtual serial port for the RFID

char tag[13]; //will use to store the tag we read

//List of allowed tags
char* allowedTags[] = {
  "710024D6F271",
  "71002508DF83",
  "7200772C765F"
};
  
//List of names assoiated with tag
char* tagName[] = {
  "USER1",
  "USER2",
  "USER3" 
};

// Check the number of tags defined
int numberOfTags = sizeof(allowedTags)/sizeof(allowedTags[0]);

//RGB
int redPin = 7;
int greenPin = 6;
int bluePin = 5;

// State Variables: Initialize to the locked state
int LockState = LOCKED;
int SolenoidPin = 4; //pin definition for the solenoid

// the number of the hall effect sensor pin
const int hallPin1 = A0;     
const int hallPin2 = A1;
const int hallPin3 = A2;
// variable for reading the hall sensor status
int hallState1 = 0; 
int hallState2 = 0;
int hallState3 = 0;
// previous state of the hall sensor
int lastHallState1 = 0;     
int lastHallState2 = 0;
int lastHallState3 = 0;

void setup() {
  
 Serial.begin(9600);
 id20.begin(9600);
 
 //RGB
 pinMode(redPin, OUTPUT);
 pinMode(greenPin, OUTPUT);
 pinMode(bluePin, OUTPUT);
        
 //Solenoid
 pinMode(SolenoidPin, OUTPUT);
 setLockState(LOCKED); // Initialize state
 
 Serial.print("Scan card.. ");
 Serial.println();
 
  // initialize the hall effect sensor pin as an input:
  pinMode(hallPin1, INPUT); 
  pinMode(hallPin2, INPUT);
  pinMode(hallPin3, INPUT);
 
}

void loop () {

 readTag();
 hallSensor();
 
 }

/**
* Read and check tag
*/
void readTag(){
  
  boolean mem = false;     
  while (id20.available()<14){ //wait until all the 12 bytes are buffered
  }
  if(id20.read() == 2){ //checks for the header
    for (int i = 0; i < 14; ){ //store the first 12 bytes
      if (i < 13) {
        tag[i] = id20.read(); 
        i++;        
      }else {
        tag[12] = '\0'; //add null to the end of the array to terminate string
        i++;
        mem = true; //reading card is pau
      }
    }
  }
  
  if (mem==true) {
    
    int tagId = findTag( tag ); // Search the tag database for this particular tag
    // Open the door if this tag was found in the array
    if( tagId > 0 ) {
      Serial.print("Authorized tag ID ");
      Serial.print(tagId);
      Serial.print("(");
      Serial.print(tag);
      Serial.print(")");
      Serial.print(": unlocking for ");
      Serial.println(tagName[tagId - 1]); // Get the name for this tag from the database
      openDoor(); //Show feed back and open the door     
    } else {
      noMatch();
      Serial.println(tag);
      Serial.println("Tag not authorized");
    }    
    Serial.println(); 
  }
} //end of readTag()
 
/**
* Search for a specific tag in the array
*/
int findTag( char tagValue[12] ) {
  for (int thisCard = 0; thisCard < numberOfTags; thisCard++) {
    if(strcmp(tagValue, allowedTags[thisCard]) == 0) { // Check if the tag value matches this row in the tag database
    // The row in the database starts at 0, so add 1 to the result so
    // that the card ID starts from 1 instead (0 represents "no match")
      return(thisCard + 1);
    }
  }
return(0); //no match is found
} //end of findTag()
       
/**
* Opens door and blink the green LED
*/
void openDoor() {
  
   tone(7,4978,125); //sound buzzer
 
  //Open door and blink green light for 3 secs
  for (int i = 0; i < 30; i++) {
   setLockState(UNLOCKED);
   setColor(0,255,0);
   delay(50);
   setColor(0,0,0);
   delay(50);   
  }
  setLockState(LOCKED);//lock the door again
  
} //end of openDoor()

/**
* Lights Red LED if card is invalid
*/
void noMatch() {  
  tone(7,62,1000); //sound a buzzer       
  setColor(255,0,0); //red led
  delay(2000);
  setLockState(LOCKED);
} //end of no Match

/**
* Set the state and the time of the state change
*/
void setLockState(int state) {
  LockState = state;
  
  if (state == LOCKED) {
    //Serial.println("Locked!");
    setColor(255,255,0); //yellow
    digitalWrite(SolenoidPin, LOW);  
  }else if (state == UNLOCKED){
    //Serial.println("Unlocked!");
    digitalWrite(SolenoidPin, HIGH); //activate solenoid
  }
} //end SetLockState

/**
* Set the color for the RGB LED (Common Anode)
*/
void setColor(int red, int green, int blue) {  
    digitalWrite(redPin, 255 - red); //RED
    digitalWrite(greenPin, 255 - green); //GREEN
    digitalWrite(bluePin, 255 - blue); //BLUE
} //end of setColor()

void hallSensor(){
  // read the state of the hall effect sensor: 
  hallState1 = digitalRead(hallPin1);
  hallState2 = digitalRead(hallPin2);
  hallState3 = digitalRead(hallPin3);
  //Serial.println(hallState);

  if (hallState1 != lastHallState1) {        
   if (hallState1 == LOW) {     
     Serial.println("IN");
   } else {
     Serial.println("OUT");
   } 
 } 

if (hallState2 != lastHallState2) {         
   if (hallState2 == LOW) {     
     Serial.println("IN");
   } else {
     Serial.println("OUT");
   } 
 } 
 
 if (hallState3 != lastHallState3) {         
   if (hallState3 == LOW) {     
     Serial.println("IN");
   } else {
     Serial.println("OUT");
   } 
 } 
  //remember the last states of the sensor
  lastHallState1 = hallState1;
  lastHallState2 = hallState2;
  lastHallState3 = hallState3;
  
} //end of hall Sensor

Is the hall sensor working by itself? Remove all the other stuff and just write a sketch that looks at the hall sensors. I would not expect a hall sensor to be able to detect just a metal key.

Thanks for the reply. The hallSensor() method works when I commented out the readTag() in the void loop. Is there a way to turn off the SoftwareSerial for the ID20 momentarily (after the user scan his/her tag) and see if that would solve the problem?

Right now I'm using a magnet to use for the sensor, but eventually I would attach a magnet into an aluminum rod as a key chain and would be inserted into slots with the sensors inside it.

There is no connection between serial and the analogue inputs you are using. However the read tag function blocks until a tag is present, is that what you want to do.

Yes, would that be causing the problem? I'm stripping everything off and just connecting the rfid and one hall sensor and see if that'll work.

BTW. I forgot to mention, I have an ethernet shield on top of the UNO hopefully that's not causing the problem.

So I stripped everything down with just the rfid reader and one hall sensor and I'm still getting the same result. Sensor works by itself but not with the rfid on. Any idea? Thanks.

Have you tried disconnecting the RFID reader but still leaving the code in to see if the hardware is interfering with the analogue inputs! Can you post this cut down code and explain more what you mean by not working.

I did more testing and found out that it'll only prints the status of the sensor after I scan a card. Sounds like the readTag() has to always execute first before the program calls the hallSensor(). I intend to keep monitoring the changes in sensor not only after a card was read. Hope this made the problem clearer?

Hi Grumpy_Mike I apologize if I wasn’t clear. The code is suppose to print through serial any changes on the sensor regardless. The rfid is just to open the door and login the user. Further testing shows that the changes on the sensor would ONLY prints after a card was read. the rfid and sensor are suppose to work independently. Let me know if there’s a part that’s not clear. Below is the code with just the rfid and 1 hall sensor. Thanks again.

Also, I tried disconnecting the RFID but still the same result.

#include <SoftwareSerial.h>
#include <Wire.h>

SoftwareSerial id20(3,2); // virtual serial port for the RFID

char tag[13]; //will use to store the tag we read

//List of allowed tags
char* allowedTags[] = {
  "710024D6F271",
  "71002508DF83",
  "7200772C765F"
};
  
//List of names assoiated with tag
char* tagName[] = {
  "USER1",
  "USER2",
  "USER3" 
};

// Check the number of tags defined
int numberOfTags = sizeof(allowedTags)/sizeof(allowedTags[0]);

// the number of the hall effect sensor pin
const int hallPin1 = A0; 

    
// variable for reading the hall sensor status
int hallState1 = 0; 
// previous state of the hall sensor
int lastHallState1 = 0; 
void setup() {
  
 Serial.begin(9600);
 id20.begin(9600);
 
 Serial.print("Scan card.. ");
 Serial.println();
 
  // initialize the hall effect sensor pin as an input:
  pinMode(hallPin1, INPUT);
 
}

void loop () [
 readTag();
 hallSensor();
 }

/**
* Read and check tag
*/
void readTag(){
  
  boolean mem = false;
    
  while (id20.available()<14){ //wait until all the 12 bytes are buffered
  }  
  if(id20.read() == 2){ //checks for the header
    for (int i = 0; i < 14; ){ //store the first 12 bytes
      if (i < 13) {
        tag[i] = id20.read(); 
        i++;
        
      }else {
        tag[12] = '\0'; //add null to the end of the array to terminate string
        i++;
        mem = true; //reading card is pau
      }
    }
  }
  
  if (mem==true) {
    
    int tagId = findTag( tag ); // Search the tag database for this particular tag
    // Only open the door if this tag was found in the database
    if( tagId > 0 ) {
      Serial.print("Authorized tag ID ");
      Serial.print(tagId);
      Serial.print("(");
      Serial.print(tag);
      Serial.print(")");
      Serial.print(": unlocking for ");
      Serial.println(tagName[tagId - 1]); // Get the name for this tag from the database
      //openDoor(); //Show feed back and open the door
      
    } else {
      //noMatch();
      Serial.println(tag);
      Serial.println("Tag not authorized");
    }    
    Serial.println(); 
  }
} //end of readTag()
 
/**
* Search for a specific tag in the array
*/
int findTag( char tagValue[12] ) {
  for (int thisCard = 0; thisCard < numberOfTags; thisCard++) {
    if(strcmp(tagValue, allowedTags[thisCard]) == 0) { // Check if the tag value matches this row in the tag database
    // The row in the database starts at 0, so add 1 to the result so
    // that the card ID starts from 1 instead (0 represents "no match")
      return(thisCard + 1);
    }
  }
return(0); //no match is found
} //end of findTag()
    
void hallSensor(){
  // read the state of the hall effect sensor:

  hallState1 = digitalRead(hallPin1);
   Serial.println(hallState1);

  if (hallState1 != lastHallState1) {     
    
   if (hallState1 == LOW) {
     
     Serial.println("IN");
   } else {
     Serial.println("OUT");
   } 
 } 

  //remember the last states of the sensor
  lastHallState1 = hallState1;
}

That is what I would expect from that software. Once the read tag function is called it will not exit until a tag is read, that is how the code is written. Add a

If( id20.avaliable() == 0) return;

To the start of this function to stop this from happerning.

Add a...To the start of this function to stop this from happerning.

Actually. I'd recommend a slightly different approach:

void readTag()
{
   if(id20.available() >= 14)
   {
      // There are 14 or more bytes, so read them
   }
}

Grumpy_Mike's suggestion would still block waiting for the other 13 bytes to arrive. Which may, or may nor, really be a problem. Mine does nothing until all the data has arrived.

I tried Grumpy_Mike's suggestion and the hall sensor would work fine until I scan a card and would go back to the same problem.

Then tried PaulS' suggestion and read all the data from the card first and it worked!!!! Sensor and rfid works independently.

Thank you both!! I appreciate you guys help and time.

I tried Grumpy_Mike’s suggestion and the hall sensor would work fine until I scan a card and would go back to the same problem.

That indicates that you have another problem with not reading the right number of bytes from the serial port.

Then tried PaulS’ suggestion and read all the data from the card first and it worked!

Notice that in your original code you had:-
(id20.available()<14) as a condition and Paul had (id20.available() >= 14)