Go Down

Topic: Using the RDM630 RFID Tag Reader and NewSoftwareSerial library (Read 4531 times) previous topic - next topic

Koop

Hi all,
Some of you may have seen my previous post regarding NewSoftwareSerial library, and I'm sorry to bother you all again, but my newbie brain has run into another wall ;) .  I'm trying to get a RDM630 RFID Tag Reader (See below for datasheet)  to read an RFID tag and send the serial ID to my PC.  The reader uses a serial interface to connect to the Arduino, and so I need to use the NewSoftwareSerial library to connect to the reader.  What is supposed to happen in the Serial Monitor is this:
Code: [Select]

Computer to Arduino Serial Ready
RFID to Arduino Serial Ready
Awaiting Tag
RFID Tag ID: (Tag's ID Here)


However, what is actually happening is this:
Code: [Select]

Computer to Arduino Serial Ready
RFID to Arduino Serial Ready
Awaiting Tag
RFID Tag ID: ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ

If you swipe the tag again, the ID appears as normal.  But, if you were to swipe a DIFFERENT tag, the ID would be the same as the first tag on the first swipe, and then would return to the second tag's ID.  From this, I get the feeling that it is 'one behind' the whole time, like the data is being sent to the PC first and then the Arduino is recieving data, although that is obviously not the case from my code (Which is yet to include XOR Checksum functionality because of this speedbump):
Code: [Select]

/*==Libraries==*/
#include <SoftwareSerial.h>

/*==Pin Definitions==*/
#define RFID_LED 2
#define RFID_RX 3
#define RFID_TX 4

/*==Variables==*/
char RFID_Data[15];
boolean RFID_Data_Stored = false;

SoftwareSerial RFID =  SoftwareSerial(RFID_RX, RFID_TX);

void setup() {
  Serial.begin(57600); //Setup connection to Computer via HardwareSerial
  Serial.println("Computer to Arduino Serial Ready"); //Acknowledge connection establihment to Computer
 
  RFID.begin(9600); //Setup connection to RFID Reader via SoftwareSerial
  pinMode(RFID_TX, OUTPUT);//Define RFID TX pin as OUTPUT (Not nessesary)
  pinMode(RFID_RX, INPUT);//Define RFID RX pin as INPUT (Nessesary)
  Serial.println("RFID to Arduino Serial Ready");//Acknowledge connection establishment to RFID Reader
  Serial.println("Awaiting Tag");//Provide Arduino's current status
}


void loop() {
  if(digitalRead(RFID_LED) == LOW) { //Wait for LED pin from RFID Reader to go LOW
    Recieve_RFID(); //And go to 'Recieve_RFID' function
  }
 
  if(RFID_Data_Stored) { //If the RFID Reader has been read, then:
    Serial.print("RFID Tag ID: "); //Print to the computer the Tag ID
    for(int i = 1; i <=14; i++) {
      Serial.write(RFID_Data[i]);
    }
    Serial.println("");
   
    RFID_Data_Stored = false; //Say that the data has been printed
    delay(500); //Delay to avoid false readings
  }
}
void Recieve_RFID() {
  for(int i = 1; i <= 14; i++) { //Recieve data coming from RFID Reader
    RFID_Data[i] = RFID.read(); //Store it in a string
    if(i == 14) {
      RFID_Data_Stored = true; //Tell the Arduino that there is data stored
    }
  }
}

Oh, and here is the Reader datasheet: http://australianrobotics.com.au/sites/default/files/RDM630-Spec..pdf

Thanks for all your help,
Koop

Grumpy_Mike

You are not waiting for all the data to be sent before reading it. Your rubbish characters are the result of getting -1 from the read because there is nothing to read. Then by the time the data has arrived in the buffer you have stopped reading it until next time.
You have to ensure that there is something to trad EACH TIME you read the serial.

PaulS

Code: [Select]
SoftwareSerial RFID =  SoftwareSerial(RFID_RX, RFID_TX);

  pinMode(RFID_TX, OUTPUT);//Define RFID TX pin as OUTPUT (Not nessesary)
  pinMode(RFID_RX, INPUT);//Define RFID RX pin as INPUT (Nessesary)

You have told the SoftwareSerial instance that the pins are its to manage. So, why are you diddling with them?

Code: [Select]
void Recieve_RFID() {
  for(int i = 1; i <= 14; i++) { //Recieve data coming from RFID Reader
    RFID_Data[i] = RFID.read(); //Store it in a string
    if(i == 14) {
      RFID_Data_Stored = true; //Tell the Arduino that there is data stored
    }
  }
}

As soon as the reader senses a tag, you expect the data to be available in the serial buffer to be read. At 9600 baud, that is a most unrealistic expectation. The data trickles in slowly. By the time you get frustrated, and wave the tag again, the first set of data has arrived. If you wave a second tag, all you will read is the first tag's data.

This function needs to block (not indefinitely, though) and WAIT for the 14 bytes to arrive, before trying to read them. Why does the first byte get stored in the second position in the array? Array indices start at 0.

AWOL

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Koop

Thanks all,
I changed the Recieve_RFID Function to this, but it still won't work :/
Quote

void Recieve_RFID() {
  if(RFID.available() >= 13) {
    for(int i = 0; i <= 13; i++) { //Recieve data coming from RFID Reader
      RFID_Data = RFID.read(); //Store it in a string
      if(i == 13) {
        RFID_Data_Stored = true; //Tell the Arduino that there is data stored
      }
    }
  }
}



And AWOL, I know!  That was my original post ;)

Koop

Sorry, this is the code, actually:
Quote

void Recieve_RFID() {
 if(RFID.available() >= 13) {
   for(int i = 0; i <= 13; i++) { //Recieve data coming from RFID Reader
     RFID_Data = RFID.read(); //Store it in a string
     if(i == 13) {
       RFID_Data_Stored = true; //Tell the Arduino that there is data stored
     }
   }
 } else {
   delay(1);
 }
}

PaulS

So, if there are 13 bytes, it's OK to read all 14 of them. Hmmm. I don't think so.

Since you are not using the hardware serial port to talk to the RFID reader, that means that you can use the hardware serial port to debug the issue. I'd suggest that you do that.

By the way, I really don't think your code looks like what you posted. Using the quote button is inappropriate for code. Use the code button, instead (the one with the # on it).

Koop

Oh sorry about that.  I just hit 'Copy for Forum' in the IDE.  Thanks for your help.  If I figure it out, I'll be sure to post it up here!

dxw00d

Quote
I just hit 'Copy for Forum' in the IDE.


They really need to fix that button, or get rid of it completely.

johnwasser

Are there any framing characters to let you know when a tag begins and ends?  Those might be useful to check for.

Note: Your new code is reading 14 characters (0-13).

Try a test sketch that echoes characters from SoftwareSerial() to the serial monitor:
Code: [Select]

const int RFID_RX = 3;
const int RFID_TX = 4;
SoftwareSerial RFID =  SoftwareSerial(RFID_RX, RFID_TX);

void setup() {
 Serial.begin(57600); //Setup connection to Computer via HardwareSerial  
 RFID.begin(9600); //Setup connection to RFID Reader via SoftwareSerial
 Serial.println("Awaiting Tag");//Provide Arduino's current status
}

void loop()
   {
   if (RFID.available())
      {
      char val = RFID.read();
      Serial.print(val, HEX);
      Serial.print(" ");
      if (val == 10 || val == 13)
          Serial.println();
      }
   }

Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

Koop

#10
Jul 12, 2012, 04:11 pm Last Edit: Jul 12, 2012, 04:14 pm by Koop Reason: 1
Awesome, guys!  I adapted my Receive_RFID function so that if there is not 14 bytes, then it waits 1 millisecond and tries again, and it works fine!  Here is the completed code:
Code: [Select]
/*==Libraries==*/
#include <SoftwareSerial.h>

/*==Pin Definitions==*/
#define RFID_LED 2
#define RFID_RX 3
#define RFID_TX 4

/*==Variables==*/
char RFID_Data[15];
boolean RFID_Data_Stored = false;

SoftwareSerial RFID =  SoftwareSerial(RFID_RX, RFID_TX);

void setup() {
 Serial.begin(57600); //Setup connection to Computer via HardwareSerial
 Serial.println("Computer to Arduino Serial Ready"); //Acknowledge connection establihment to Computer
 
 RFID.begin(9600); //Setup connection to RFID Reader via SoftwareSerial
 pinMode(RFID_TX, OUTPUT);//Define RFID TX pin as OUTPUT (Not nessesary)
 pinMode(RFID_RX, INPUT);//Define RFID RX pin as INPUT (Nessesary)
 Serial.println("RFID to Arduino Serial Ready");//Acknowledge connection establishment to RFID Reader
 Serial.println("Awaiting Tag");//Provide Arduino's current status
}


void loop() {
 if(digitalRead(RFID_LED) == LOW) { //Wait for LED pin from RFID Reader to go LOW
   Recieve_RFID(); //And go to 'Recieve_RFID' function
 }
 
 if(RFID_Data_Stored) { //If the RFID Reader has been read, then:
   Serial.print("RFID Tag ID: "); //Print to the computer the Tag ID
   for(int i = 0; i <=13; i++) {
     Serial.write(RFID_Data[i]);
   }
   Serial.println("");
   
   RFID_Data_Stored = false; //Say that the data has been printed
   delay(500); //Delay to avoid false readings
 }
}

void Recieve_RFID() {
 Wait_Loop:
 if(RFID.available() >= 14) {
   for(int i = 0; i <= 13; i++) { //Recieve data coming from RFID Reader
     RFID_Data[i] = RFID.read(); //Store it in a string
     if(i == 13) {
       RFID_Data_Stored = true; //Tell the Arduino that there is data stored
     }
   }
 } else {
   delay(1);
   goto Wait_Loop;
 }
}

Now all I need to do is do some verification, and I'm done!

Johnwasser: Yes there are, and to the Serial Monitor, they appear as spaces.  I think that they are ASCII beginning and end of transmission decimal values (that is, they are 002 and 003) the code for understanding them will be added in for verification.

AWOL

#11
Jul 12, 2012, 04:14 pm Last Edit: Jul 12, 2012, 04:20 pm by AWOL Reason: 1
Code: [Select]
goto Wait_Loop;
A "while" loop would attract a lot less flak.

Edit: typo "look" -> "loop"
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Koop


PaulS

Quote
Why, AWOL?

Because in 30 years of writing C/C++ code, I have yet to use a single goto.

You want there to be 14 bytes to read. So,
Code: [Select]
while(Serial.available() < 14)
{
  // Do nothing
}

makes it very clear that you are waiting for 14 characters.

Your goto mess does not.

Koop

Quote
Your goto mess does not.

Why is Goto considered a 'mess', may I ask?

Go Up