RFID + LCD + Tactical Switch = PROBLEM

Hi, i’m trying to get my RFID + Tactical switch working… but i’m with some problems.
the rfid + lcd is working fine, however when i press the tactical switch (pin 11) nothing happens :frowning: a blue led (pin 13) should be ON, but it isnt.

If i remove or comment the code in bold and leave the part of the switch (italic one), the switch and led works fine.
What can it be ?

#include <SoftwareSerial.h>
#include <LCD4Bit.h>

int val = 0;
char code[10];
int bytesread = 0;
char tag1[11] = “0F01C68668”; // this is size 11 because it is a NULL terminating string
char tag2[11] = “0F0302867B”;
int switchPin = 11; // digital input pin for a switch
int switchState = 0; // the state of the switch
int rxPin = 9; // RFID reader SOUT pin connected to Serial RX pin at 2400bps to pin8
int enablePin = 10;
SoftwareSerial RFID = SoftwareSerial(rxPin,enablePin);

int ledpin = 13;
int RED = 4;
int GREEN = 2;
int BLUE = 3;
int doorPin = 12;
LCD4Bit lcd = LCD4Bit(2);

void setup()
{
pinMode(ledpin, OUTPUT);
pinMode(switchPin, INPUT); // set the switch pin to be an input
pinMode(doorPin, OUTPUT);
digitalWrite(doorPin, LOW); // lock door
//serial.begin(9600); // Hardware serial for Monitor 2400bps
//serial.println(“Serial Enabled”);
RFID.begin(2400);
//serial.println(“RFID Enabled”);
pinMode(RED, OUTPUT);
pinMode(GREEN, OUTPUT);
pinMode(BLUE, OUTPUT);
pinMode(enablePin,OUTPUT); // Set digital pin 2 as OUTPUT to connect it to the RFID /ENABLE pin
digitalWrite(enablePin, LOW); // Activate the RFID reader
inicialize();
lcd.init();
lcd.commandWrite(0x0F);
lcd.printIn(“BEM-VINDO!”);
delay(3000);
lcd.clear();
lcdMessage();

}

void loop()
{
switchState = digitalRead(switchPin);

  • if (switchState == 1) { // if the switch is closed:*
  • digitalWrite(doorPin, HIGH);*
  • digitalWrite(ledpin, HIGH);*
  • digitalWrite(GREEN, HIGH);*
  • delay(9000);*
  • digitalWrite(ledpin, LOW);*
  • digitalWrite(doorPin, LOW);*
  • digitalWrite(GREEN, LOW);*
  • }*
  • else { // if the switch is open:*
  • digitalWrite(doorPin, LOW);*
  • digitalWrite(ledpin, LOW);*
  • }*

if((val = RFID.read()) == 10)
** { // check for header**
** bytesread = 0;**
** while(bytesread<10)**
** { // read 10 digit code**
** val = RFID.read();**
** if((val == 10)||(val == 13))**
** { // if header or stop bytes before the 10 digit reading**
** break; // stop reading**
** }**
** code[bytesread] = val; // add the digit **
** bytesread++; // ready to read next digit **
** }**
** if (bytesread == 10 && (findGoodTag())){**
** //Serial.write(“VALIDO”);**
** lcd.clear();**
** lcd.printIn(“ID. VALIDA”);**
** lcd.cursorTo(2, 0);**
** lcd.printIn(“PORTA ABERTA!”);**
** sucess();**
** lcd.clear();**
** lcdMessage();**
** } else {**
** //serial.write(“INVALIDO”);**
** lcd.clear();**
** lcd.printIn(“ID. INVALIDA”);**
** lcd.cursorTo(2, 0);**
** lcd.printIn(“PORTA FECHADA!”);**
** failed();**
** lcd.clear();**
** lcdMessage();**
** }**
** bytesread = 0;**
** digitalWrite(GREEN, LOW);**
** digitalWrite(RED, LOW);**
** digitalWrite(BLUE, HIGH);**
** delay(5500); **
** }**

}

void lcdMessage(){
lcd.printIn(" Apresente “);
lcd.cursorTo(2, 0);
lcd.printIn(” ID! ");
}

boolean findGoodTag(){
if (checkTag(tag1)){ return true;}
else if (checkTag(tag2)){ return true;}
else{
//serial.print("Bad tag: ");
//serial.println(code);
return false;
}

}

boolean checkTag(char *tag){

for (int x=0;x<10;x++){
if( tag != code){
return false;
}
}
return true;
}

// Flashes Red LED if failed login
void failed()
{
digitalWrite(doorPin, LOW);
digitalWrite(GREEN, LOW); // Make sure green LED is off
digitalWrite(BLUE, LOW); // Make sure blue LED is off
// Blink red fail LED 3 times to indicate failed key
for(int i=0; i<5; i++) {
digitalWrite(RED, HIGH); // Turn on red LED
delay(500);
digitalWrite(RED, LOW); // Turn off red LED
delay(500);
}
}

void sucess()
{
digitalWrite(doorPin, HIGH);
digitalWrite(RED, LOW);
digitalWrite(BLUE, LOW);
digitalWrite(GREEN, HIGH);
delay(9000);
digitalWrite(GREEN, LOW);
digitalWrite(doorPin, LOW);
}

void inicialize() {
for(int i=0; i<8; i++)
{
digitalWrite(BLUE, HIGH);
delay(100);
digitalWrite(BLUE, LOW);
delay(150);
}
digitalWrite(BLUE, HIGH);
}

SoftwareSerial RFID = SoftwareSerial(rxPin,enablePin);

SoftwareSerial is obsolete, and has been for a long time. Try using NewSoftSerial, instead. Does the problem persist?

But the problem isnt there :S
Eveything works fine (rfid reader, lcd,led's) but the switch part isnt working, unless i comment eveything else on the loop.

But the problem isnt there

Well, as long as you are absolutely sure, then forget I said anything.

sorry buddy, i'm not absolutly sure!
I've changed to newsoftserial and now the switch is working with rfid code... however RFID is only getting BAD TAGs (//serial.write("INVALIDO"); ) and printing to lcd every 5 seconds
Is this related to newsoftserial ? Because before using that, rfid was working fine.

How many bytes were read, and what were they?

the problem is that i dont have a way to check that. Since i've made a perfboard and my usb to ttl didnt arrive yet.

EDIT: i've took out the rfid and i'm testing it with a duemilanove and a breaboard. You want me to check what it reads?

Can you print to the LCD?

I’m printing to Serial (i’ve put rfid in a breadboard with a duemilanove), thing is: using newsoftserial it doesnt anything correctly.

Serial Enabled
RFID Enabled
Bad tag: ÿÿÿÿÿÿÿÿÿÿ

INVALIDOBad tag: ÿÿÿÿÿÿÿÿÿÿ

INVALIDOBad tag: ÿÿÿÿÿÿÿÿÿÿ

INVALIDOBad tag: ÿÿÿÿÿÿÿÿÿÿ

INVALIDOBad tag: ÿÿÿÿÿÿÿÿÿÿ

INVALIDOBad tag: ÿÿÿÿÿÿÿÿÿÿ

INVALIDO

#include <NewSoftSerial.h>

int val = 0;
char code[10];
int bytesread = 0;
char tag1[11] = “0F01C68668”; // this is size 11 because it is a NULL terminating string
char tag2[11] = “0F0302867B”;
int rxPin = 9; // RFID reader SOUT pin connected to Serial RX pin at 2400bps to pin8
int enablePin = 10;
NewSoftSerial RFID(rxPin, enablePin);

void setup()
{
Serial.begin(9600); // Hardware serial for Monitor 2400bps
Serial.println(“Serial Enabled”);
RFID.begin(2400);
pinMode(enablePin,OUTPUT); // Set digital pin 2 as OUTPUT to connect it to the RFID /ENABLE pin
digitalWrite(enablePin, LOW); // Activate the RFID reader
Serial.println(“RFID Enabled”);
}

void loop()
{
if(RFID.available() > 0) {
if((val = RFID.read()) == 10)
{ // check for header
bytesread = 0;
while(bytesread<10)
{ // read 10 digit code
val = RFID.read();
if((val == 10)||(val == 13))
{ // if header or stop bytes before the 10 digit reading
break; // stop reading
}
code[bytesread] = val; // add the digit
bytesread++; // ready to read next digit
}
if (bytesread == 10 && (findGoodTag())){
Serial.write(“VALIDO”);
} else {
Serial.write(“INVALIDO”);
}

bytesread = 0;
}
}
}

boolean findGoodTag(){
if (checkTag(tag1)){ return true;}
else if (checkTag(tag2)){ return true;}
else{
Serial.print("Bad tag: ");
Serial.println(code);
return false;
}

}

boolean checkTag(char *tag){

for (int x=0;x<10;x++){
if( tag != code){
return false;
}
}
return true;
}

That’s what i get when i present a card to the RFID reader.

NewSoftSerial RFID(rxPin, enablePin);

You want the NewSoftSerial instance to talk to the enable pin? I don’t think so.

 if(RFID.available() > 0) {
     if((val = RFID.read()) == 10)
     {   // check for header
       bytesread = 0;
       while(bytesread<10)
       {  // read 10 digit code
         val = RFID.read();

If one byte is available, read all 11 of them. Do you see a problem with that?

I've saw this post: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1273612596#12
He says: You should usually check nss.available() before attempting any reads

So i thought i should check if rfid.available > 0.

The first part : NewSoftSerial RFID(rxPin, enablePin);
i dont know, since i was using SoftwareSerial and i had: SoftwareSerial RFID = SoftwareSerial(rxPin,enablePin);
It was working fine.

Weird thing, i've only changed this part

if (bytesread == 10) {
if (findGoodTag()){
Serial.write("VALIDO");
} else {
Serial.write("INVALIDO");
}
}

and now it outputs the tag fine to Serial, however it seems to be in a loop, saying "VALIDO" infinitely after presenting correct tag or INVALIDO infinitely after presenting a bad tag

however it seems to be in a loop

That will stop if you reset bytesRead to 0 after printing (and acting on) the messages.

He says: You should usually check nss.available() before attempting any reads

You should. But, the available() function returns the number of available bytes. You should not try to read more than that without checking again.

It was working fine.

You can get away with it, since you never actually write to the software serial port. Still, it's a better idea to use a different pin. If no other pins are available, use -1.

Weird thing, i've only changed this part

I don't see how that made a difference, except for losing a set of parentheses, but, the important thing is that it now works.

I've changed my code and tried what mikalhart posted.
It seems to run fine now, and also doesnt get noisy tags.

void loop()
{
if (RFID.available() > 0)
{
if (bytesread > 10)
{
Serial.println("Weird: buffer overflow");
bytesread = 0;
}
char c = RFID.read();
if (c == '\r' || c == '\n')
{
code[bytesread] = 0;
if (c == '\r')
{
Serial.print("Tag code is ");
Serial.println(code);
if (findGoodTag()) {
Serial.println("VALIDO");
} else {
Serial.println("INVALIDO");
}
}
bytesread = 0;
}
else
{
code[bytesread++] = c;
}
}

}

Now, it reads the tag that's present at RFID reader.

How do i put a delay so if a tag is present for more than 1 second the reader reads it and then ignore if the tag is continuously presented???

Because i've tried to put a delay(1000); after bytesread = 0;, and it just keeps looping at Serial.print the tag presented.

Please help :confused:
I really need to understand why putting a delay(x) after bytesread = 0; makes the arduino send every x seconds the code to Serial.println :S
i wanted to make the reader only read the tag 1 time then if the tag is still present it ignores...and reads again after x seconds.
thanks

Set c to ' ' (or anything other than \n or \r), before or after bytesread = 0;, too.

Like this Paul:

c = ' ';
bytesread = 0;
delay(3500);

?

Like this

Yes. The program keeps saying that the card is valid/invalid because the if test that precedes the print statements depends on the value in c.

It's not working Paul :frowning:
I present a tag to the reader for more or less 1 second and at Serial Monitor i get:
Tag code is 0F01C68668
VALIDOTag code is 0F01C68668
VALIDOTag code is 0F01C68668
VALIDOTag code is 0F01C68668
VALIDOTag code is 0F01C68668
VALIDO

:expressionless: So many times.. it should only read one time and wait 3,5 seconds to read the next one

if (RFID.available() > 0)
{
if (bytesread > 10)
{
Serial.println("Weird: buffer overflow");
bytesread = 0;
}
char c = RFID.read();
if (c == '\r' || c == '\n')
{
code[bytesread] = 0;
if (c == '\r')
{
Serial.print("Tag code is ");
Serial.println(code);
if (findGoodTag()) {
Serial.print("VALIDO");
} else {
Serial.print("INVALIDO");
}
}
c = ' ';
bytesread = 0;
delay(3500);
}
else
{
code[bytesread++] = c;
}
}

     if (c == '\r')
     {
       Serial.print("Tag code is ");
       Serial.println(code);
       if (findGoodTag()) {
         Serial.print("VALIDO");
       } else {
         Serial.print("INVALIDO");
       }
     }
     [glow]c = ' ';
     bytesread = 0;
     delay(3500);[/glow]

The highlighted code should be moved above the curly brace just above it.

Still getting the same results Paul :frowning: