Pages: [1] 2 3   Go Down
Author Topic: Using the RDM630 RFID Tag Reader and NewSoftwareSerial library  (Read 3952 times)
0 Members and 1 Guest are viewing this topic.
Australia
Offline Offline
Jr. Member
**
Karma: 0
Posts: 59
char CoolThings[] = "Vegemite", "Swimming", "Arduino";
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 smiley-wink .  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:
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:
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:
/*==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
Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 633
Posts: 34514
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 631
Posts: 50155
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
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:
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.
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 309
Posts: 26481
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

More on this subject here
Logged

"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.

Australia
Offline Offline
Jr. Member
**
Karma: 0
Posts: 59
char CoolThings[] = "Vegemite", "Swimming", "Arduino";
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 smiley-wink
Logged

Australia
Offline Offline
Jr. Member
**
Karma: 0
Posts: 59
char CoolThings[] = "Vegemite", "Swimming", "Arduino";
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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);
  }
}
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 631
Posts: 50155
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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).
Logged

Australia
Offline Offline
Jr. Member
**
Karma: 0
Posts: 59
char CoolThings[] = "Vegemite", "Swimming", "Arduino";
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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!
Logged

Gosport, UK
Offline Offline
Faraday Member
**
Karma: 21
Posts: 3113
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

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

Massachusetts, USA
Offline Offline
Tesla Member
***
Karma: 212
Posts: 8945
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
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();
       }
    }
Logged

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

Australia
Offline Offline
Jr. Member
**
Karma: 0
Posts: 59
char CoolThings[] = "Vegemite", "Swimming", "Arduino";
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
/*==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.
« Last Edit: July 12, 2012, 09:14:15 am by Koop » Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 309
Posts: 26481
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
goto Wait_Loop;
A "while" loop would attract a lot less flak.

Edit: typo "look" -> "loop"
« Last Edit: July 12, 2012, 09:20:09 am by AWOL » Logged

"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.

Australia
Offline Offline
Jr. Member
**
Karma: 0
Posts: 59
char CoolThings[] = "Vegemite", "Swimming", "Arduino";
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Why, AWOL?
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 631
Posts: 50155
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
while(Serial.available() < 14)
{
  // Do nothing
}
makes it very clear that you are waiting for 14 characters.

Your goto mess does not.
Logged

Australia
Offline Offline
Jr. Member
**
Karma: 0
Posts: 59
char CoolThings[] = "Vegemite", "Swimming", "Arduino";
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Your goto mess does not.
Why is Goto considered a 'mess', may I ask?
Logged

Pages: [1] 2 3   Go Up
Jump to: